将死(aka小便池问题)


35

我的Precalc老师遇到​​了他最喜欢的问题之一,他解决了(或更可能是受xkcd启发而偷走了)涉及小便池的问题。“将死”的情况是,每个小便池已经被占用,或者在其旁边有一个小便池被占用。例如,如果某人是,则nX

X-X--X

被认为是将死。注意,一个人不能在一个已经被占用的小便池旁边占用一个小便池。

任务

您的程序将通过stdin,命令行参数或函数参数获取一个数字。然后,您的程序将打印出或返回与输入的小便池数量对应的将发生伴侣的方式。

例子

0 -> 1(空的情况下计为将死)
1 -> 1X
2 -> 2X--X
3 -> 2X-X-X-
4 -> 3X-X--X-X,或X--X
5 -> 4X-X-XX--X--X-X-,或-X--X
6 -> 5X-X-X-X--X-XX-X--X-X--X--X-X-X
7 -> 7X-X-X-XX--X-X--X-X--X-X--X-XX-X--X-X--X--X-X-X-X-
8 -> 9-X--X--X-X--X-X--X-X--X--X-X-X-XX--X--X-X--X-X-XX-X--X-XX-X-X--XX-X-X-X-
...

计分

以字节为单位的最小程序获胜。




12
n = 0的情况应该为1。恰好有一个设置是checkmate,那就是''。这与阶乘和置换相同,为0!= 1,因为恰好有1种方式可以排列0个项目。
orlp


19
根本没有洗手间的确是将死的局面。:D
泰特斯

Answers:


20

绿洲,5字节

cd+2V

扩大的视野

cd+211

说明

1 = a(0)
1 = a(1)
2 = a(2)

a(n) = cd+
       c      # Calculate a(n - 2)
        d     # Calculate a(n - 3)
         +    # Add them up

在线尝试!


7
这是一个奇怪的答案,语言被创造大约一个月前,在回购没有适当的文件....

2
@tuskiomi它确实有一个文档,于info.txt
TuxCrafting

6
@TùxCräftîñg当然,如果您想成为技术专家。我可以画一匹马,称其为我的编程项目的文档。这没有用处或决定性的。

1
@tuskiomi info.txt非常有用,它包含每个Oasis命令的文档
TuxCrafting

8
@tuskiomi这是拖延和懒惰的结果。我将尝试添加一个简洁的文档,介绍当今实际语言的工作方式。
阿德南

12

Java 7,65 42字节

int g(int u){return u>1?g(u-2)+g(u-3):1;}

该序列仅添加先前的元素即可获得新的元素。对于这种较短的方法,帽子尖指向orlp和Rod;)

旧:

int f(int u){return u<6?new int[]{1,1,2,2,3,4}[u]:f(u-1)+f(u-5);}

在第五个元素之后,序列中的间隔增加了前五个元素。


如果u = 3,则您的函数返回1,但示例显示应为

糟糕!我f从另一个代码段使用我的函数,而不是递归。愚蠢的我,正在解决...
Geobits,2016年

1
最后一部分(u>0?u:1;)不能变成1;吗?
科纳·奥布莱恩

2
@Jordan如果小便池为零,则在一种配置下“每个小便池已被占用”。我相信问题中显示的测试用例是错误的。
Geobits's

1
可以取代u>0?u:1;)通过1;如果你改变了第一比较u>1,然后在U = 2的输出将是克(0)+ G(-1),这将是2

9

Python 2,42 40 39 35字节

f=lambda n:n>1and f(n-2)+f(n-3)or 1

生成实际集合:

lambda n:["{:0{}b}".format(i,n).replace("0","-").replace("1","X")for i in range(2**n)if"11"not in"{:0{}b}".format(i*2,2+n).replace("000","11")]

8

Ruby,58个 34字节

受Geobits最初的Java答案启发。

f=->n{n<3?n:n<6?n-1:f[n-1]+f[n-5]}

在repl.it上查看:https ://repl.it/Dedh/1

第一次尝试

->n{(1...2**n).count{|i|!("%0#{n}b"%i)[/11|^00|000|00$/]}}

在repl.it上查看:https ://repl.it/Dedh


6

Python,33个字节

f=lambda n:+(n<2)or f(n-2)+f(n-3)

使用偏移的基本情况f(-1) = f(0) = f(1) = 1。如果True可以用于1,则不需要3个字节+()


6

J,31 27 23字节

多亏了英里,节省了4个字节!

0{]_&(]}.,+/@}:)1 1 2"_

一个解释即将到来。

旧解决方案

(>.1&^)`(-&3+&$:-&2)@.(2&<)

这是一个议程。LHS是由两个动词组成的动名词:>.1&^-&3+&$:-&2。如果条件(2&<)失败,则使用第一个。这意味着>.1&^在参数上激活了fork 。观察:

   1 ^ 0 1 2
1 1 1
   (1&^) 0 1 2
1 1 1
   0 1 2 >. (1&^) 0 1 2
1 1 2
   (>.1&^) 0 1 2
1 1 2

在此,>.取两个值的最大值。因此,它产生1、1和2作为初始项。

动名词中的第二个动词是叉子:

-&3 +&$: -&2

左,右叉齿分别应用于动词,分别减去3和2;然后用与之相等的左右参数调用中间动词。$:在每个参数上调用动词,+并将这两个参数相加。它基本上相当于($: arg - 3) + ($: arg - 2)

测试用例

   f =: (>.1&^)`(-&3+&$:-&2)@.(2&<)
   f 0
1
   f 2
2
   f 4
3
   f 6
5
   f 8
9
   F =: f"0         NB. for tables
   F i.13
1 1 2 2 3 4 5 7 9 12 16 21 28
   i.13
0 1 2 3 4 5 6 7 8 9 10 11 12
   (,. F) i.13
 0  1
 1  1
 2  2
 3  2
 4  3
 5  4
 6  5
 7  7
 8  9
 9 12
10 16
11 21
12 28

4

MATL25 23字节

W:qB7BZ+t!XAw3BZ+!3>a>s

在线尝试!检查所有测试用例

说明

两个卷积!好极了!

这将构建一个数组,例如A,其中每个可能的配置都是一行。1在这个数组中代表一个占领的位置。例如,对于输入4,数组A为

0 0 0 0
0 0 0 1
0 0 1 0
···
1 1 1 0
1 1 1 1

然后,代码将数组A与卷积[1 1 1]。这给出了数组B。A中的占用位置和占用位置的邻居给出了数组B中的非零结果:

0 0 0 0
0 0 1 1
0 1 1 1
···
2 3 2 1
2 3 3 2

因此,使配置成为校验对象的第一个条件是B在该行中不包含零。这意味着在A的那一行中没有空位,或者有一些空位是邻居。

我们需要第二个条件。例如,最后一行满足上述条件,但不是解决方案的一部分,因为配置从一开始就无效。一个有效的配置不能有两个相邻的占用位置,即1在A中不能有两个连续的位置。等效地,它在B中不能有两个连续的值超过1。因此,我们可以通过将B与卷积[1 1]并在结果数组C中进行检查来检测到这一点,

0 0 0 0
0 1 2 1
1 2 2 1
···
5 5 3 1
5 6 5 2

该行中的值不超过3。最终结果是满足两个条件的配置数量。

W:q    % Range [0 1 ... n-1], where n is implicit input
B      % Convert to binary. Each number produces a row. This is array A
7B     % Push array [1 1 1] 
Z+     % 2D convolution, keeping size. Entries that are 1 or are horizontal 
       % neighbours of 1 produce a positive value. This is array B
t!     % Duplicate and transpose (rows become columns)
XA     % True for columns that contain no zeros
w      % Swap. Brings array B to top
3B     % Push array [1 1]
Z+     % 2D convolution, keeping size. Two horizontally contiguous entries
       % that exceed 1 will give a result exeeding 3. This is array C
!      % Transpose
3>     % Detect entries that exceed 3
a      % True for columns that contain at least one value that exceeds 3
>      % Element-wise greater-than comparison (logical and of first
       % condition and negated second condition)
s      % Sum (number of true values)

4

PHP,105个 113 93字节

+3为n=1; + 9 $argv,-1-3打高尔夫球
-20:请注意,我不需要这些组合,只需要计数

for($i=1<<$n=$argv[1];$i--;)$r+=!preg_match("#11|(0|^)0[0,]#",sprintf("%0{$n}b,",$i));echo$r;

-r

从2 ** n-1循环到0:

  • 检查二进制N位表示为1100000在开始或结束时,或单个0
  • 如果不匹配,则增加结果

打印结果

相同大小,正则表达式稍简单

for($i=1<<$n=$argv[1];--$i;)$r+=!preg_match("#11|^00|00[,0]#",sprintf("%0{$n}b,",$i));echo$r;
  • 从2 ** n-1循环到1(而不是0)
  • 检查二进制表示1100在开始或结束,或000
  • 对于n = 0不打印任何内容

PHP,82字节

Arnauld的答案传达并打了个高尔夫球:

for($i=$k=1<<$n=$argv[1];--$i;)$r+=!($i&$x=$i/2|$i*2)&&(($i|$x)&~$k)==$k-1;echo$r;

对于n = 0不打印任何内容


在new处添加3个字节n=0?:1在决赛之前插入;
Titus

4

果冻,11 字节

,’fR_2߀So1

在线尝试!验证所有测试用例

怎么运行的

,’fR_2߀So1  Main link. Argument: n

 ’           Decrement; yield n - 1.
,            Pair; yield [n, n - 1].
   R         Range; yield [1, ..., n].
  f          Filter; keep the elements that are common to both lists.
             This yields [n, n - 1] if n > 1, [1] if n = 1, and [] if n < 1.
    _2       Subtract 2 from both elements, yielding [n - 2, n - 3], [-1], or [].
      ߀     Recursively call the main link for each integer in the list.
        S    Take the sum of the resulting return values.
         o1  Logical OR with 1; correct the result if n < 1.

2
这是如何运作的?它使用递归公式,还是其他?
科纳·奥布莱恩

@ ConorO'Brien是的,它使用递归公式。我添加了一个解释。
丹尼斯

4

JavaScript(ES6)/递归,30 27字节

编辑:感谢Shaun H,节省了3个字节

let

f=n=>n<3?n||1:f(n-2)+f(n-3)

for(var n = 1; n < 16; n++) {
  console.log(n, f(n));
}

JavaScript(ES6)/非递归90 77字节

编辑:由于Conor O'Brien和Titus节省了13个字节

let f =

n=>[...Array(k=1<<n)].map((_,i)=>r+=!(i&(x=i>>1|i+i))&&((i|x)&~k)==k-1,r=0)|r

for(var n = 1; n < 16; n++) {
  console.log(n, f(n));
}


1
我认为((i|r|l)&(k-1))可以成为((i|r|l)&k-1),甚至成为((i|r|l)&~-k)
Conor O'Brien

一个字节:i<<1-> i*2i+i
Titus

1
您可以使用一个变量L和R,节省了6个字节:!(i&(x=i>>1|i+i))&&((i|x)&(k-1))==k-1; 如果您可以插入,k--某处,则可以替换k-1k以保存括号。
泰特斯(Titus)2016年

&(k-1)无论如何都不需要赦免;但您可以&~k改用。
泰特斯(Titus)2016年

1
我只是要离开这里:f=n=>n<3?n||1:f(n-2)+f(n-3)
Shaun H

3

Mathematica,35个字节

a@0=a@1=1;a@2=2;a@b_:=a[b-2]+a[b-3]

定义一个函数a。以整数作为输入,并返回整数作为输出。简单的递归解决方案。


3

AnyDice,51字节

function:A{ifA<3{result:(A+2)/2}result:[A-2]+[A-3]}

这里应该有更多的AnyDice答案。

我的解决方案定义了计算的递归函数a(n)=a(n-2)+a(n-3)。它返回a(0)=a(1)=1a(2)=2使用一些整数除法魔术。

在线尝试

注意:输出可能看起来很奇怪,这是因为它通常用于输出骰子概率。只需查看条形图左侧的数字即可。


3

Perl,35 34字节

包括+1的 -p

在STDIN上输入

checkmate.pl <<< 8

checkmate.pl

#!/usr/bin/perl -p
$\+=$b-=$.-=$\-$b*4for(++$\)x$_}{

新开发的秘密配方。纹波更新3个状态变量,而无需并行分配。

同样可以解决原始问题的时间也很短(但是要慢得多,并且要占用更多的内存):

#!/usr/bin/perl -p
$_=grep!/XX|\B-\B/,glob"{X,-}"x$_

但这不适用于 0


2

JavaScript(ES6),62个字节

n=>[1,...Array(n)].reduce(($,_,i,a)=>a[i]=i<3?i:a[i-3]+a[i-2])

这是我第一次需要两个虚拟变量名称。递归版本可能会更短一些,但我真的很喜欢reduce...编辑:找到了一个解决方案,也有62个字节,只有一个虚拟变量:

n=>[1,...Array(n)].reduce((p,_,i,a)=>a[i]=i<5?i+2>>1:a[i-5]+p)

2

果冻,19 字节

递归的解决方案可能短...

Ḥ⁹_c@⁸
+3µ:2R0;瀵S

看到它的TryItOnline
或者看到系列n = [0, 99],也在TryItOnline

怎么样?

n+3通过计算组合数返回th Padovan的数字

Ḥ⁹_c@⁸ - Link 1, binomial(k, n-2k): k, n
Ḥ      - double(2k)
 ⁹     - right argument (n)
  _    - subtract (n-2k)
     ⁸ - left argument (k)
   c@  - binomial with reversed operands (binomial(k, n-2k))

+3µ:2R0;瀵S - Main link: n
  µ       µ  - monadic chain separation
+3           - add 3 (n+3)
   :2        - integer divide by 2 ((n+3)//2)
     R       - range ([1,2,...,(n+3)//2]
      0;     - 0 concatenated with ([0,1,2,...,(n+3)//2]) - our ks
        ç€   - call previous link as a dyad for each
           S - sum

2

> <>,25 + 2 = 27字节

211rv
v!?:<r@+@:$r-1
>rn;

需要输入在程序启动时出现在堆栈上,因此该-v标志为+2字节。在线尝试!

第一行将堆栈初始化为1 1 2 n,其中n输入数字为。第二行向后运行,检查n大于1的值。如果大于1,n则递减并生成序列中的下一个元素,如下所示:

r$:@+@r              a(n-3) a(n-2) a(n-1) n

r        Reverse   - n a(n-1) a(n-2) a(n-3)
 $       Swap      - n a(n-1) a(n-3) a(n-2)
  :      Duplicate - n a(n-1) a(n-3) a(n-2) a(n-2)
   @     Rotate 3  - n a(n-1) a(n-2) a(n-3) a(n-2)
    +    Add       - n a(n-1) a(n-2) a(n)
     @   Rotate 3  - n a(n) a(n-1) a(n-2)
      r  Reverse   - a(n-2) a(n-1) a(n) n

最后一行在堆栈底部输出数字,这是序列中必需的元素。


2

CJam,20个字节

1_2_{2$2$+}ri*;;;o];

在线尝试!

说明

这将使用OEIS页面中显示的重复关系。

1_2_                   e# Push 1, 1, 2, 2 as initial values of the sequence
           ri          e# Read input
    {     }  *         e# Repeat block that many times
     2$2$              e# Copy the second and third elements from the top
         +             e# Add them
              ;;;      e# Discard the last three elements
                 o     e# Output
                  ];   e# Discard the rest to avoid implicit display

2

05AB1E,12个字节

XXXIGX@DŠ0@+

说明

XXX            # initialize stack as 1, 1, 1
   IG          # input-1 times do:
     X@        # get the item 2nd from bottom of the stack
       DŠ      # duplicate and push one copy down as 2nd item from bottom of the stack
         0@    # get the bottom item from the stack
           +   # add the top 2 items of the stack (previously bottom and 2nd from bottom)
               # implicitly print the top element of the stack after the loop

在线尝试!


1

FRACTRAN,104 93字节

输入为11**n*29,输出为29**checkmate(n)

这主要是为了好玩,特别是因为我目前对Python,JS Java 感到厌烦。与PHP相同的字节数::D欢迎高尔夫建议。

403/85 5/31 3/5 9061/87 3/41 37/3 667/74 37/23 7/37 38/91 7/19 5/77 1/7 1/17 1/2 340/121 1/11

开球

               At the start we have 11**n * 29
1/11           If n < 2, we remove the 11s and print 29**1
340/121        If n >= 2, we subtract two 11s (n-2) and add one 17, two 2s and one 5.
                 We now have 17**1 * 29**1 * 2**2 * 5.
                 These are the register for a, b, c at registers 17, 29, and 2.
                 5 is an indicator to start the first loop.
                 This loop will move a to register 13.
403/85 5/31    Remove the 17s one at a time, adds them to the 13 register.
                 5 and 31 reset the loop.
3/5            Next loop: moves b to a and adds b to a in register 13.
9061/87 3/41   Remove the 29s one at a time, adds them to the 17 and 13 registers.
                 3 and 41 reset the loop.
37/3           Next loop: moves c to b in register 29.
667/74 37/23   Remove the 2s one at a time, adds them to the 29 register.
                 37 and 23 reset the loop.
7/37           Next loop: moves a+b to c in register 2.
38/91 7/19     Remove the 13s one at a time, adds them to the 2 register.
                 7 and 19 reset the loop.
5/77           Move to the first loop if and only if we have an 11 remaining.
1/7 1/17 1/2   Remove the 7 loop indicator, and all 17s and 2s.
               Return 29**checkmate(n).

1

其实是25个位元组

对于简单的f(n) = f(n-2) + f(n-3)递归关系,这似乎有点长。欢迎打高尔夫球。在线尝试!

╗211╜¬`);(+)`nak╜2╜2<I@E

开球

         Implicit input n.
╗        Save n to register 0.
211      Stack: 1, 1, 2. Call them a, b, c.
╜¬       Push n-2.
`...`n   Run the following function n-2 times.
  );       Rotate b to TOS and duplicate.
  (+       Rotate a to TOS and add to b.
  )        Rotate a+b to BOS. Stack: b, c, a+b
         End function.
ak       Invert the resulting stack and wrap it in a list. Stack: [b, c, a+b]
╜        Push n.
2        Push 2.
╜2<      Push 2 < n.
I        If 2<n, then 2, else n.
@E       Grab the (2 or n)th index of the stack list.
         Implicit return.

1

其实是18个位元组

这实际上是丹尼斯更长的果冻答案的转折点。欢迎打高尔夫球。在线尝试!

3+;╖½Lur⌠;τ╜-@█⌡MΣ

开球

         Implicit input n.
3+       Add 3. For readibility, m = n+3.
;╖       Duplicate and store one copy of m in register 0.
½Lu      floor(m/2) + 1.
r        Range from 0 to (floor(m/2)+1), inclusive.
⌠...⌡M   Map the following function over the range. Variable k.
  ;        Duplicate k.
  τ╜-      Push m-2k. Stack: [m-2k, k]
  @█       Swap k and m-2k and take binomial (k, m-2k).
            If m-2k > k, █ returns 0, which does not affect the sum() that follows.
         End function.
Σ        Sum the list that results from the map.
         Implicit return.



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.