钩长产品


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

Answers:


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]]
丹尼斯2015年

@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

方法

  • 从输入创建二进制矩阵
  • 计算这两个维度的运行差异。
  • 对于每个像元,将两个结果相加,然后减去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'

在这里在线尝试。



4

Pyth,18个字节

*Fsm.e+k-bdf>TdQeQ

以升序输入,例如[1, 3, 3, 5]

示范。


备用解决方案,19字节

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

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

(感谢@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 2015年

可能发誓我删除了它!我记得曾经注意到我只使用过一次,并替换了唯一的用法。但是我一定错过了实际删除变量的方法。:(
Reto Koradi

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答案的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 1z==[]or _时候z是一个列表,使用的事实True==1。Python的函数声明比Haskell复杂,因此定义一个同时执行内部和外部递归循环的单个递归函数通常会带来很多收益,尽管我不知道这在这里是否可行。
xnor

@xnor“欢迎使用Python打高尔夫球”?
Sherlock16年

哦,对不起,您使用Python打高尔夫球。我实际上与您相关。
xnor

@xnor很久很久以前,我实际上是在Python中打高尔夫球的。我有点不高兴,你不记得了:P
Sherlock9

我不能代表xnor,但我主要通过用户的头像来识别用户。
丹尼斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.