网格中有多少个矩形?


29

好吧,尽管这一挑战取得了巨大的成功,但解决起来却非常琐碎。因此,对于那些寻求更多挑战的人,我创建了此挑战的续集,其中您现在必须计算唯一矩形的数量。看看这个!

现在,对于那些希望解决这一挑战的人来说,它来了。


好吧,我们还没有真正面临这样的挑战,所以我们开始吧。

考虑以下3 x 3矩形网格:

例

有多少个矩形?好吧,从视觉上进行计数,我们可以看到实际上存在36矩形,包括整个平面本身,这些都显示在下面的动画GIF中:

示例中的矩形

任务

如上所示,矩形的计数是任务。换句话说,给定2个大于或等于的整数0m并且和n,其中m表示宽度并n表示高度,输出该矩形m x n网格中的矩形总数。

规则

  • 明确禁止使用任何直接解决此问题的内置程序。

  • 这个挑战不是要找到最短的答案,而是要找到每种语言的最短答案。因此,将不接受任何答案。

  • 禁止出现标准漏洞。

测试用例

呈现格式Array of Integers Input -> Integer Output

[0,0] -> 0
[1,1] -> 1
[3,3] -> 36 (Visualized above)
[4,4] -> 100
[6,7] -> 588

参考文献

记住,这是,所以最短的代码胜出!


588为最后一个测试用例进行了计算。
Leaky Nun

@LeakyNun好吧,我想我在计数时错过了一些。它是固定的。
R. Kap

输入的最大值是多少?
暴民埃里克(Erik the Outgolfer)'16年

Answers:


34

Python,22个字节

lambda m,n:m*~m*n*~n/4

m*n*(m+1)*(n+1)/4使用位补码来缩短公式~m=-(m+1),表示(m+1)*(n+1)~m*~n

为什么矩形数是m*n*(m+1)*(n+1)/4多少?通过选择两条水平线(顶部和底部)和两条垂直线(左侧和右侧)来指定每个矩形。有m+1水平线,我们从中选择两个截然不同的子集。因此,选择的数量choose(m+1,2)m*(m+1)/2。乘以n*(n+1)/2垂直线的选择即可得出结果。


+1技巧很棒。
David Ljung Madison Stellar

11

果冻,4 字节

RS€P

在线尝试!

另外,还有4个字节

pP€S

在线尝试!


做得好。竖起大拇指。:)
R. Kap

24
介意解释吗?
Pureferret

还有בHP‘c2P也许其他4个字节的替代品。
英里

1
@Pureferret这使用从OEIS有关此作为产物的通式nthmth三角形数量。R将每个数字转换为基于1的索引:[1, 2, ..., n]S是sum,表示“每个”,因此将每个列表相加,得到如下列表:[nth triangle number, mth triangle number]。然后P取该列表的乘积,得到所需的结果。
FryAmTheEggman'8

1
@FryAmTheEggman所以,你的意思是...。魔术
Pureferret


9

Mathematica,15个字节

##(1##+##+1)/4&

这是一个未命名的函数,带有两个整数参数并返回矩形的数量。

说明

该实现基本上是两个三角数的乘积的一种非常复杂的形式。这可能是值得阅读节“的参数序列” 在这个职位的细节,但我将在这里总结的要点。

##扩展为所有参数的序列。这类似于用其他语言进行喷溅。例如,如果参数为3and 4{1, 2, ##, 5}则将为您提供{1, 2, 3, 4, 5}。但这不仅适用于列表,而且适用于任何表达式,例如f[1, 2, ##, 5]也可以f[1, 2, 3, 4, 5]

当您##与运算符结合使用时,这变得很有趣。Mathematica中的所有运算符只是一些f[...]类似表达式(可能是嵌套的)的简写形式。例如a+bPlus[a, b]并且a-b实际上代表Plus[a, Times[-1, b]]。现在,当您##与运算符结合使用时,Mathematica所做的就是首先扩展运算符,将##其视为单个操作数,然后仅在最后扩展它们。通过##在正确的位置插入,我们可以同时使用它来相乘和相加操作数。

让我们针对上面的代码执行此操作:

##(1##+##+1)/4

将其展开为完整形式,我们得到以下信息:

Times[##, Plus[Times[1, ##], ##, 1], Rational[1/4]]

让我们插入函数参数ab

Times[a, b, Plus[Times[1, a, b], a, b, 1], Rational[1/4]]

现在,我们将其转换回标准数学符号:

a * b * (a * b + a + b + 1) / 4

稍作重新排列就表明这是三角形数字的乘积:

a * b * (a + 1) * (b + 1) / 4
(a * (a + 1) / 2) * (b * (b + 1) / 2)
T(a) * T(b)

有趣的事实:此实现非常复杂,与用于计算单个三角数的内置长度相同PolygonalNumber


8

C,25个字节

#define r(x,y)x*y*~x*~y/4

纯粹版本(27):

r(x,y){return x*y*~x*~y/4;}

ISO-er版本(35):

#define r(x,y)((x)*(y)*~(x)*~(y)/4)

您认为哪个版本最好?
暴民埃里克

8

水母,16字节

p|%/**+1
  4  Ei

输入格式为[x y],输出仅为结果。

在线尝试!

替代解决方案,相同的字节数:

pm%/*[*i
  4  +1

说明

是时候给水母介绍它应有的介绍了!:)

水母是Zgarb2D语法挑战语言。语义很大程度上受J启发,但语法是艺术品。所有功能都是单个字符,并布置在网格上。函数从它们的下一个标记以南和以东获取参数,并以北和西返回结果。这样,您就可以创建一个有趣的函数调用网络,在其中可以通过将值从多个方向传递到多个函数中来重用值。

如果我们忽略了上面程序中的某些标记是特殊运算符(高级功能)的事实,那么上面的程序将以一种通俗的语言编写为:

p(|( /*(i*(i+1)) % 4 ))

让我们自下而上地检查代码。输入由输入i,因此计算为[x y]

+它的顶部上一起接收该输入与文字1,并因此增加两个元件,得到[(x+1) (y+1)](最操作在列表自动螺纹)。

的其他值i向左发送,但E拆分为东方论点北部和西部。这意味着右边的输入*实际上是正确的[x y][(x+1) (y+1)]因此将进行计算[x*(x+1) y*(y+1)]

下一个*实际上是由前一个修饰的/,它将前一个变为折叠操作。折叠*一对简单地将其相乘,就可以得到x*(x+1)*y*(y+1)

现在%只是除法,因此可以计算x*(x+1)*y*(y+1)/4。不幸的是,这导致浮点数,因此我们需要将其与一元整数舍入|。最终,该值被送入p打印最终结果。


我可能发誓我在文档中读到了一些关于整数除法的信息……
Conor O'Brien

7

R,40 35字节

好吧,是时候深入了解了!这是我的R代码,灵感来自@xnor答案:

a=scan();(n=a[1])*(m=a[2])*(n+1)*(m+1)/4 

编辑:在此版本中,R将询问两次输入。

(n=scan())*(m=scan())*(n+1)*(m+1)/4

cat(prod(choose(scan()+1,2)))是29个字节。
朱塞佩

6

CJam,12个 10字节

感谢Martin,节省了2个字节。

{_:)+:*4/}

在线尝试!

这是一个从堆栈中获取2个元素的列表并将解决方案留在堆栈上的块。测试使用的完整方案:riari+{_:)+:*4/}~

基于xnor出色的python解决方案。

说明:

{_:)+:*4/}
{        } -- Define a block
 _:)       -- Duplicate list, increment all values in new list
    +      -- Join the two lists
     :*    -- Fold multiply over all 4 elements
       4/  -- Divide by 4

2
如果您输入两个元素的列表,我认为这适用于10?{_:~+:*4/}
Martin Ender

实际上,~在CJam中根本不需要使用。只需使用)
Martin Ender

5

Matlab,23 19字节

@(x)prod([x/2,x+1])

执行公式m*n*(m+1)*(n+1)/4
用法:ans([m,n])


4

MATL,6个字节

tQ*2/p

输入是形式为的数组[m,n]

在线尝试!

说明

基于公式的直接计算m*(m+1)*n*(n+1)/4

t     % Input array [m,n] implicitly. Duplicate
Q     % Add 1 to each entry of the copy: gives [m+1,n+1]
*     % Multiply element-wise: gives [m*(m+1),n*(n+1)]
2/    % Divide each entry by 2: [m*(m+1)/2,n*(n+1)/2]
p     % Product of the two entries: m*(m+1)*n*(n+1)/4. Display implicitly


4

Java 7,39 38字节

int c(int a,int b){return~a*a*b*~b/4;}

Java 8,26 25 19 18 17字节

a->b->a*~a*b*~b/4

基于@xnor的出色回答。多亏@DavidConrad节省了多个字节。在这里尝试。

测试代码(Java 7):

在这里尝试。

class M{
  static int c(int a,int b){return~a*a*b*~b/4;}

  public static void main(String[] a){
    System.out.println(c(0, 0));
    System.out.println(c(1, 1));
    System.out.println(c(3, 3));
    System.out.println(c(4, 4));
    System.out.println(c(6, 7));
  }
}

输出:

0
1
36
100
588

1
您不需要它,return并且a->b->比短一个字节(a,b)->
戴维·康拉德

2
我也不认为您也不需要分号,因为如果您将lambda传递到以a Function<Integer, Function<Integer, Integer>>作为参数的方法中,则不会后跟分号。
大卫·康拉德

2
我同意@DavidConrad:我不计算;单个语句J8 lambda 的结尾。
CAD97

@DavidConrad对不起,很晚的编辑,但是我现在才注意到我已读完您的评论以删除return ..另外,我几乎从不使用Java 8编程(因此我的所有Java 7答案都如此),但是我如何a->b->工作?这是当前情况下的ideone。
凯文·克鲁伊森

1
抱歉,回复太晚了!你需要讨好的功能,所以你需要改变MathOperation.operation只取一个int,返回一个Function<Integer, Integer>,当你调用它,您最初只传递第一个参数a,然后调用.apply(b)Function。您还需要导入java.util.function.Function这是发生变化的一个想法。
戴维·康拉德

3

Ruby,22个字节

偷@xnor的把戏并制作一个稳定的lambda:

r=->(m,n){m*n*~m*~n/4}

示例调用:

r[6,7]     # => 588

或作为proc,也为22个字节:

proc{|m,n|m*n*~m*~n/4}

然后我们可以称之为:

proc{|m,n|m*n*~m*~n/4}.call(6,7)     # => 588

你并不需要它命名为匿名函数没关系,每个站点的惯例
康纳尔奥布莱恩

3

迷宫13 11字节

*?;*_4/!
):

在线尝试!

说明

像大多数答案一样,这也可以计算三角数的乘积。领先的2x2块是一个小循环:

*?
):

第一次迭代*不执行任何操作,因此真正的循环顺序是这样的:

?   Read integer N from STDIN or 0 at EOF and push onto stack. If 0, exit the loop.
:   Duplicate N.
)   Increment.
*   Multiply to get N*(N+1).

其余代码只是线性的:

;   Discard the zero that terminated the loop.
*   Multiply the other two values.
_4  Push a 4.
/   Divide.
!   Print.

迷宫然后尝试/再次执行,由于除以零而终止了程序。


2

Pyke,6个字节

mh+Bee

在这里尝试!

mh     -    map(increment, input)
  +    -   ^ + input
   B   -  product(^)
    ee - ^ \ 4

这可能会使用细分,但就我个人而言,这是一件艺术品。
corsiKa

2

05AB1E,4个字节

€LOP

说明

使用A096948中描述的公式

      # Implicit input, ex: [7,6]
€L    # Enumerate each, [[1,2,3,4,5,6,7],[1,2,3,4,5,6]]
  O   # Sum, [28,21]
   P  # Product, 588
      # Implicit display

将输入作为[n,m]

在线尝试


1

Pyth,8个 6字节

@DenkerAffe节省了两个字节。

*FmsSd

输入应为列表,例如[m,n]在这里尝试一下

说明:

          Implicit assignment of Q to eval(input).
*         Multiplication.
 F        Splat the following sequence onto the arguments of the previous function.
  m       Map the following function of d over Q (Q is implicitly added to the end).
   s      Reduce the following list with addition, initial value of 0.
    Sd    Return range(1,d+1).

1
您可以使用F代替.*并删除Q它,因为它是隐式添加的。
Denker

我知道,F但是我不知道该怎么用,以为我需要.*改用...谢谢!
Rhyzomatic


1

Lua,74 63字节

x,y=...n=0 for i=1,y do for j=i,i*x,i do n=n+j end end print(n)

函数将输入作为数字参数。

由于Lua的实现方式,从技术上讲,这是一个具有可变args的函数,可以通过将其包装在“ function”语句中或通过使用“ loadstring”从源代码加载它来调用


1
我看到您那里有很多用于I / O的代码。仅仅制作一个使用两个数字并返回答案并删除所有不必要的I / O代码的函数,也许会更短一些?
Zwei

@Zwei我忘记了允许函数通过参数进行输入。感谢您指出了这一点。
brianush1年

该函数可以命名为“ f”,而不是全称“ function”,以节省更多的7个字节
Zwei

在Lua中,必须使用关键字“功能”来声明功能。如果未指定名称(例如:“ function f()”),则为匿名函数。(例如:“ function()”)。因此,“功能”是代码正常工作所必需的。
brianush1年

哦,我忘了lua就是这样。我的错!
Zwei


1

Brain-Flak84 80字节

({}<>)({({})<({}[()])>}{})<>({({})<({}[()])>}{}[()]){<>(({}))<>({}[()])}<>({{}})

在线尝试!

可能非常次优,尤其是由于有关三角数的代码重用,但至少我们有一个可行的Brain-Flak解决方案。

可悲的是,它似乎无法通过0 0测试用例无限循环而失败,但是其他所有都可以正常工作。




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.