후크 길이 제품


27

젊은 다이어그램은 왼쪽 정렬 행과 상단 정렬 열의 상자의 배열입니다. 각 상자마다 위와 왼쪽의 모든 공간이 사용됩니다.

XXXXX
XXX
XXX
X

상자 의 후크 길이 는 행의 오른쪽에있는 상자 수와 열의 아래에있는 상자 수이며 한 번만 계산됩니다. 예를 들어 두 번째 상자의 후크 길이는 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". 원하는대로 목록이 오름차순 또는 내림차순으로 정렬 될 수 있습니다. 이 목록은 비어 있지 않으며 양의 정수만 포함합니다.

출력 : 후크 길이의 곱으로 양의 정수입니다. 정수 오버플로 또는 런타임에 대해 걱정하지 마십시오.

Young 다이어그램이나 정수 파티션을 다루는 내장 함수는 허용되지 않습니다.

테스트 사례 :

[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

@Dennis Nice : ab를위한 arity order 사용 %: P
Optimizer

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

방법

  • 입력 값에서 이진 행렬 만들기
  • 두 차원의 연속 차이를 계산합니다.
  • 각 셀에 대해 두 개의 결과를 더하고 1을 빼고 절대 값을 취하십시오 (원래 0 셀을 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'

여기에서 온라인으로 사용해보십시오.



4

Pyth, 18 바이트

*Fsm.e+k-bdf>TdQeQ

와 같이 오름차순으로 입력을 [1, 3, 3, 5]받습니다.

데모.


대체 솔루션, 19 바이트

*Fs.em+s>Rd<Qk-bdbQ

3

파이썬 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

(결합하여 저장 한 정신 나간 바이트 @xnor에게 감사 p하고 j)

d.get나에게 약간의 의심스러운 보이지만, 그렇지 않으면 나는이 상대적으로 행복 해요. 재귀 및 압축과 같은 다른 접근 방식을 시도했지만 이것이 100 미만인 유일한 방법입니다.

예를 들어 STDIN에서 오름차순으로 목록으로 입력을받습니다 [1, 3, 3, 5].


3

하스켈, 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를 곱하여 위에서 아래로 스캔합니다 . fp


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

파이썬 2, 135128 바이트

이것은 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

내가 그것을 삭제했다고 맹세했을 수 있습니다! 나는 한 번만 사용하고 유일한 사용법을 대체했다는 것을 기억합니다. 그러나 실제로 변수를 삭제하려면 놓쳤을 것입니다. :(
Reto Koradi

1

자바 스크립트 ( 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

파이썬, 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:])

파이썬 골프에 오신 것을 환영합니다! 사실을 사용하여 언제 목록인지 z and _ or 1와 같이 z==[]or _할 수 있습니다 . 파이썬의 함수 선언은 Haskell보다 더 중요하므로 내부 및 외부 재귀 루프를 모두 수행하는 단일 재귀 함수를 정의하는 것이 좋습니다. zTrue==1
xnor

@xnor "파이썬 골프에 오신 것을 환영합니다"?
Sherlock9

아 죄송합니다, 당신은 파이썬에서 골프를합니다. 나는 실제로 당신을 연결합니다.
xnor

@xnor 사실, 실제로 시작하기 오래 전에 파이썬에서 골프를 쳤다. 나는 당신이 기억하지 못하는 것이 약간 화가났습니다. : P
Sherlock9

나는 xnor를 위해 말할 수 없지만 주로 아바타로 사용자를 인식합니다.
Dennis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.