チェックメイト(別名小便器の問題)


35

私のPrecalcの先生は、彼が作成した(またはxkcdに触発されて盗んだ可能性が高い)彼のお気に入りの問題の1つを抱えています。「チェックメイト」とは、すべての小便器がすでに使用されているか、隣に使用済みの小便器がある状況です。たとえば、人がの場合、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でなければなりません。チェックメイトであるセットアップが1つだけあります''。これは、階乗および順列の場合と同じです、0!=1。0個のアイテムを配置する方法は1つだけです。
orlp


19
実際、トイレはまったくありません。:D-
タイタス

回答:


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
この奇妙な答えは、言語はレポではありません適切な文書で1ヶ月前に作成されました....

2
@tuskiomi文書がありますinfo.txt
-TuxCrafting

6
@TùxCräftîñg確かに、技術的になりたいのなら。私は馬を描き、それをプログラミングプロジェクトに向けたドキュメントと呼ぶことができました。それはそれを有用、または決定的にしません。

1
@tuskiomi info.txtは便利です。すべてのOasisコマンドのドキュメントが含まれています
-TuxCrafting

8
@tuskiomiそれは先延ばしと怠zyの結果です。今日、実際の言語がどのように機能するかについての簡潔なドキュメントを追加しようとします。
アドナン

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);}

5番目の要素の後、シーケンスのギャップは5つ前の要素によって上昇します。


U = 3であれば、あなたの関数は1を返しますが、例では、それは2でなければならないことを示して
ポケ

おっとっと!f再帰ではなく、他のスニペットの関数を使用していました。ばかげて、修正
...-Geobits

1
その最後の部分(u>0?u:1;)にならないの1;ですか?
コナーオブライエン

2
@Jordan小便器がゼロの場合、可能な構成では「すべての小便器がすでに使用されています」。質問に示されているテストケースは間違っていると思います。
ジオビット

1
あなたは置き換えることができますu>0?u:1;)によって1;あなたが最初に比較を変更した場合、u>1uは出力が2になりますG(0)+ G(-1)、となります2 = ON、その後、
ロッド

9

パイソン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

ルビー、58 34バイト

GeobitsのオリジナルのJavaの回答に大きく影響を受けました。

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

repl.itでそれを参照してください。 https

最初の試み

->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ます。True1に使用できる場合、に3バイトは必要ありません+()


6

J、31 27 23バイト

マイルのおかげで4バイト節約できました!

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

説明はすぐに来ます。

古いソリューション

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

これは議題です。LHSは、2つの動詞で構成される動名詞です:>.1&^-&3+&$:-&2。最初の条件は、条件(2&<)が失敗した場合に使用されます。つまり、フォーク>.1&^は引数を介してアクティブになります。観察する:

   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

ここで>.は、最大2つの値を取ります。したがって、最初の項として1、1、および2が生成されます。

動名詞の2番目の動詞はフォークです。

-&3 +&$: -&2

左と右のタインが動詞に適用され、それぞれ3と2が減算されます。次に、中央の動詞が、左右の引数に等しい値で呼び出されます。$:各引数で動詞を呼び出し、+これら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

オンラインでお試しください!あるいは、すべてのテストケースを確認してください

説明

2つの畳み込み!わーい!

これにより、可能な構成がそれぞれ行である配列(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のその行に空のポジションがないか、または占有ポジションの隣人がいましたが隣人がいたことを意味します。

2番目の条件が必要です。たとえば、最後の行は上記の条件を満たしますが、構成が最初から有効ではなかったため、ソリューションの一部ではありません。有効な構成は、2つの隣接する占有位置を持つことはできません。つまり1、Aに2つの連続した位置を持つことはできません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。最終結果は、2つの条件を満たす構成の数です。

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については何も出力しません


新しいために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バイト

編集:ショーン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バイト

編集:コナー・オブライエンとタイタスのおかげで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)
コナー・オブライエン

1バイト:i<<1-> i*2またはi+i
Titus

1
lとrに1つの変数を使用して、6バイトを節約できます!(i&(x=i>>1|i+i))&&((i|x)&(k-1))==k-1。また、,k--どこかに挿入できる場合は、k-1と置き換えてk括弧を保存できます。
タイタス

&(k-1)とにかく括弧を必要としません。&~k代わりに使用できます。
タイタス

1
:私はちょうどここにこれを残すつもりだf=n=>n<3?n||1:f(n-2)+f(n-3)
ショーン・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])

2つのダミー変数名が必要になったのはこれが初めてです。再帰的なバージョンはおそらくもっと短いでしょうが、私は本当に好きreduceです...

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パドバンの数を返します

Ḥ⁹_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。ここで、は入力番号です。逆方向に実行される2行目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.



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.