フック長さ製品


27

A ヤング図は左詰め行及び上部詰め列のボックスの配置です。各ボックスについて、その上とその左のすべてのスペースが占有されます。

XXXXX
XXX
XXX
X

ボックスのフックの長さは、その行の右側にあるボックスの数であり、その列の下にあるボックスの数であり、それ自体も一度カウントします。たとえば、2番目のボックスのフックの長さは6です。

X****
X*X
X*X
X

すべてのフックの長さは次のとおりです。

86521
532
421
1

ここでの目標は、フックの長さのを計算することです8*6*5*2*1*5*3*2*4*2*1*1 = 115200

(この式が重要な理由に興味がある場合は、フックの長さの式について読んでください。)

入力:行サイズのコレクション、[5,3,3,1]またはのような数字として、[[1,1,1,1,1], [1,1,1], [1,1,1], [1]]またはのような繰り返される単項記号として"XXXXX XXX XXX X"。リストは、必要に応じて昇順または降順で並べ替えることができます。リストは空ではなく、正の整数のみが含まれます。

出力:フックの長さの積。正の整数です。整数オーバーフローやランタイムについて心配する必要はありません。

特に若いダイアグラムまたは整数パーティションを扱うビルトインは許可されていません。

テストケース:

[1] 1
[2] 2
[1, 1] 2
[5] 120
[2, 1] 3
[5, 4, 3, 2, 1] 4465125
[5, 3, 3, 1] 115200
[10, 5] 798336000

回答:


13

CJam、20 19バイト

{ee::+W%}_q~%z%:+:*

これは、昇順でCJamスタイルの単項リストを取ります。例えば:

[[1] [1 1 1] [1 1 1] [1 1 1 1 1]]

与える

115200

使い方

このバージョンはDennisによって提供されBlock ArrayList %、CJamでまだ動作するという事実を使用しています:D

{       }_             e# Put this block on stack and make a copy
          q~           e# Read the input and evaluate it to put the array of arrays on stack
            %          e# Use the copy of the block and map the array using that block
 ee                    e# Here we are mapping over each unary array in the input. ee converts
                       e# the array to [index value] pair.
   ::+                 e# Add up each index value pair. Now we have the horizontal half of
                       e# hook length for each row
      W%               e# Reverse the array to make sure the count is for blocks to the right
             z%        e# Transpose and do the same mapping for columns
               :+      e# Now we have all the hook lengths. Flatten the array
                 :*    e# Get the product of all hook lengths.

これは元の20バイトバージョンです

1q~:,Wf%z:ee{:+)*}f/

これは、行サイズのCJamスタイルリストを昇順で受け取ります。例えば:

[1 3 3 5]

与える

115200

使い方

これを見ると、Youngブロック図の各ブロックのフックの長さは、そのブロックの行と列のインデックスの合計であり、逆方向にカウントされます。すなわち、各行のインデックスを右側から開始し、各列のインデックスを下から開始します。

各列のインデックスを下から簡単に開始できるように、行サイズの昇順で入力を取得します。最初に、行ごとにインデックスを取得し、逆にします。次に転置します。元の行の順序が逆になっているため、この転置図でインデックスを取得すると、下から上のインデックスが直接得られます。

コード拡張

1                       e# This serves as the initial term for product of hook lengths
 q~                     e# Read the input and eval it to put an array on stack
   :,                   e# For each row-size (N), get an array of [0..N-1]
     Wf%                e# Reverse each row so that each row becomes [N-1..0]
        z               e# Transpose for the calculation of blocks below each block
         :ee            e# Enumerate each row. Convert it into array of [index value] pairs
            {    }f/    e# Apply this mapping block to each cell of each row
             :+         e# Add the index value pair. Here, index is the blocks below the
                        e# block and value is the blocks to the right of it in the Young diag
               )        e# Increment the sum by 1 to account for the block itself
                *       e# Multiply it with the current holding product, starting with 1

こちらからオンラインでお試しください


{ee::+W%}_q~%z%:+:*(19バイト)入力形式:[[1][1 1 1][1 1 1][1 1 1 1 1]]
デニス

@Dennis Nice(ab)%:Pのアリティ順序の使用
オプティマイザー

6

J、24バイト

*/@,@(1|@-+/\."1++/\)@:>

25バイト(説明付き):

*/@,@(+/\."1|@<:@++/\)@:>

例と同様に、単項数字の昇順リストのリストとして入力を受け取ります[[1], [1,1,1], [1,1,1], [1,1,1,1,1]]

使用法:

   f=.*/@,@(+/\."1|@<:@++/\)@:>

   f 1;1 1 1;1 1 1;1 1 1 1 1
115200

方法

  • 入力からバイナリ行列を作成します
  • 両方の次元で実行中の差を計算します。
  • セルごとに2つの結果を加算し、1を減算して、絶対値を取得します(元々ゼロだったセルを1にマッピングするため)
  • マトリックスを解き、数値の積を取ります。

入力に中間結果が表示されます1 1 1 1 1;1 1 1;1 1 1;1 (5,3,3,1 in unary)これは、以前のバージョンで、長さは降順ですが、同じ方法を使用しています):

   ]c=.1 1 1 1 1;1 1 1;1 1 1;1
┌─────────┬─────┬─────┬─┐
│1 1 1 1 1│1 1 1│1 1 1│1│
└─────────┴─────┴─────┴─┘

   (>)  c
1 1 1 1 1
1 1 1 0 0
1 1 1 0 0
1 0 0 0 0

   (+/\.@:>)  c
4 3 3 1 1
3 2 2 0 0
2 1 1 0 0
1 0 0 0 0

   (+/\."1@:>)  c
5 4 3 2 1
3 2 1 0 0
3 2 1 0 0
1 0 0 0 0

   ((+/\."1++/\.)@:>)  c
9 7 6 3 2
6 4 3 0 0
5 3 2 0 0
2 0 0 0 0

   ((+/\."1<:@++/\.)@:>)  c
8  6  5  2  1
5  3  2 _1 _1
4  2  1 _1 _1
1 _1 _1 _1 _1

   ((+/\."1|@<:@++/\.)@:>)  c
8 6 5 2 1
5 3 2 1 1
4 2 1 1 1
1 1 1 1 1

   (,@(+/\."1|@<:@++/\.)@:>)  c
8 6 5 2 1 5 3 2 1 1 4 2 1 1 1 1 1 1 1 1

   (*/@,@(+/\."1|@<:@++/\.)@:>)  c
115200

同じ長さの明示的なバージョン:

3 :'*/,|<:(+/\."1++/\)>y'

こちらからオンラインでお試しください。




3

Python 2、89 88バイト

p=j=-1;d={}
for n in input():j+=1;i=0;exec"a=d[i]=d.get(i,j);p*=n-i+j-a;i+=1;"*n
print-p

(1非常識なバイトのため@xnorのおかげで組み合わせることで、保存pしてj

d.get私には少し不審に見えますが、そうでなければ、私はこれで、比較的満足しています。再帰やジッピングなど、他の方法も試しましたが、これが100未満になった唯一の方法です。

STDINからの入力を昇順のリストとして取得します(例:)[1, 3, 3, 5]


3

Haskell、68バイト

f[]=1
f g@(h:t)=(h+length t)*f[x-1|x<-g,x>1]
p[]=1
p g@(_:t)=f g*p t

使用例:p [5,4,3,2,1]->4465125

f一番外側のフックの長さに、入力リストの各要素が1(リストに達するとドロップする0)だけ減少する再帰呼び出しを掛けて、左から右にスキャンします。リスト全体pと末尾を乗算してf、上から下にスキャンしますp


2

R、174バイト

だから...この解決策は非常に長く、おそらくもっとゴルフすることができます。考えておく !

v=c();d=length;m=matrix(-1,l<-d(a<-scan()),M<-max(a));for(i in 1:l)m[i,(1:a[i])]=c(a[i]:1);for(j in 1:M)m[,j]=m[,j]+c((((p=d(which(m[,j]>0)))-1)):0,rep(0,(l-p)));abs(prod(m))

アンゴルフド:

v=c()          #Empty vector
d=length       #Alias

m=matrix(-1,l<-d(a<-scan()),M<-max(a)) #Builds a matrix full of `-1`

for(i in 1:l)
    m[i,(1:a[i])]=c(a[i]:1) #Replaces each row of the matrix by `n` to 1, `n` being the 
                            #corresponding input : each number is the number of non-empty
                            #cells at its left + itself

for(j in 1:M)
    m[,j]=m[,j]+c((((p=d(which(m[,j]>0)))-1)):0,rep(0,(l-p)))

    #This part calculates the number of "non-empty" (i.e. without `-1` in a column), -1,
    #because the count for the cell itself is already done.
    # Then, it creates a vector of those count, appending 0's at the end if necessary 
    #(this avoids recycling)

abs(prod(m)) #Outputs the absolute value of the product (because of the `-1`'s)

1

Python 2、135 128バイト

これは、stdinからPythonタイプリストを取得します。

r=input()
c=[-1]*r[0]
for a in r:
 for b in range(a):c[b]+=1
s=1
y=0
for a in r:
 for x in range(a):s*=a-x+c[x]-y
 y+=1
print s

これは非常に標準的な実装ですが、これまでのところ、これほど賢いものは思いつきませんでした。「実際の」プログラミング言語であっても、はるかに短いソリューションがあると感じています。

入力として各行のボックスの数を取得します。このソリューションでは、最初に各列のボックスの数をカウントします。この列は保存されますc(実際のカウントから1を引いて、後の計算での使用を簡素化します)。次に、すべてのボックスを反復処理し、フックの長さを乗算します。フックの長さ自体は、各行と列のボックスの数がわかれば簡単に計算できます。


1
使用していないように見えますmか?
xnor

私はそれを削除したと誓ったかもしれません!一度しか使用していないことに気付き、唯一の使用法に置き換えました。しかし、実際に変数を削除するのを忘れていたに違いありません。:(
レトコラディ

1

JavaScript(ES6)69

整数の配列を昇順で受け取る関数。

スニペットを実行してテストします(Firefoxのみ)

F=x=>x.map(r=>{for(i=-1;++i<r;p[i]=-~p[i])t*=r-i+~~p[i]},p=[],t=1)&&t

// TEST
out=x=>O.innerHTML += x + '\n';

test=[
 {y:[1], h: 1}
,{y:[2], h: 2}
,{y:[1, 1], h: 2}
,{y:[5], h: 120}
,{y:[2, 1], h: 3}
,{y:[5, 4, 3, 2, 1], h: 4465125}
,{y:[5, 3, 3, 1], h: 115200}
,{y:[10, 5], h: 798336000}
]

test.forEach(t=>{ 
  t.y.reverse(); // put in ascending order
  r=F(t.y);
  out((r==t.h? 'Ok':'Fail')+' Y: ['+t.y+'] Result:'+r+' Check:'+t.h)
})  
<pre id=O></pre>


1

Python、95 91バイト

これは、nimiのHaskell answerの Python実装です。ゴルフの提案を歓迎します。

f=lambda z:z==[]or(z[0]+len(z)-1)*f([i-1for i in z if~-i])
p=lambda z:z==[]or f(z)*p(z[1:])

Pythonゴルフへようこそ!であるという事実を使用して、リストがいつであるかのz and _ or 1ようz==[]or _にすることができます。Pythonの関数宣言はHaskellよりも冗長なので、多くの場合、内側と外側の両方の再帰ループを実行する単一の再帰関数を定義すると良い結果が得られます。zTrue==1
xnor

@xnor "Welcome to Python golfing"?
Sherlock9

ああ、すみません、あなたはPythonでゴルフをします。あなたを実際に関連付けます。
xnor

@xnor Long、Actuallyを始めるずっと前から、Pythonでゴルフをしていました。私はあなたが覚えていないことを少し困惑しています:P
Sherlock9

私はxnorの代弁はできませんが、主にアバターでユーザーを認識しています。
デニス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.