4音のオルゴールでその曲を再生できますか?


51

一連の4つのノートを演奏できるクランク式オルゴールがあります。クランクを回すと、クランクの位置と回転の方向に応じて、4つの弦のうちの1つが弾かれます。クランクを真北に向けると、ボックス(ストリングは1から4までの番号が付けられています)は次のようになります。

1  |  2
   |
   O   

4     3

そこから、クランクを時計回りに回して#2弦を摘み、クランクを東に向けることができます。

1     2

   O---   

4     3

または、クランクを北から反時計回りに回して#1弦を演奏し、クランクが西を指すようにすることもできます。

1     2

---O   

4     3

いつでも、ボックスは次の2つの音符のいずれかを再生できます。次の音符は時計回りに使用でき、次の音符は反時計回りに使用できます。

チャレンジ

あなたの課題は、音符の値(すなわち、数字の非空の文字列受け入れプログラムまたは機能書くことで1スルー4)し、オルゴールのノートのシーケンスを再生するには、これまで可能であるかどうかを判断します。入力の再生可能性または再生不可能性を示すために、真実または偽の結果を生成します。

いくつかのメモ:

  • 入力では、最初の開始位置については想定されていません。入力214(東から開始して厳密に反時計回りに移動)および234(北から開始して厳密に時計回りに移動)および両方が有効です。

  • クランクは各音の後にどちらの方向にも自由に移動できます。333331つの文字列を前後に移動することにより、同じ音符の連続が可能です(例:)。シリーズ1221441は完全にプレイ可能です(西から始まり、時計回りに2ステップ、次に反時計回りに3ステップ、時計回りに2ステップ移動します)。

サンプル

いくつかのtrueケース:

1
1234
1221
3333
143332
22234
2234
22214
1221441
41233

いくつかのfalseケース:

13     (note 3 is never available after note 1)
1224   (after `122`, the crank must be north, so 4 is not playable)
121    (after `12` the crank is east; 1 is not playable)
12221  (as above, after `1222` the crank is east)
43221  

入力は引用符を含む文字列にすることができますか?
ルイスメンドー

@LuisMendo確かに、私はそれを許可します-入力を取得するためにフープを飛び越えさせるのではなく、あなたのアルゴリズムに興味があります。とにかく、一般に大丈夫だという非公式のコミュニティのコンセンサスがあります。「」の有無にかかわらず文字列入力?
アサイラー

1
知りませんでした。リンクをありがとう!
ルイスメンドー

1
@AJMansfieldいいえ、ソリューションでは任意の数のサイクルを許可する必要があります。もちろん、何らかの入力によりコードが言語のインタープリターまたはコンピューターのメモリの制限を超える場合、それは問題ありません(物理的に持っているメモリまたはインタープリターが許可するメモリによって制限されるため)が、ソリューションは追加の制限を課すべきではありませんクランクがどこまで、または何回動くかについて。
アサイラー

1
このチャレンジは、Best of PPCG 2016のカテゴリほど単純ではありません。残念ながら、チャレンジに賞金を与えることはできませんが、Zgarbはあなたに敬意を表してチャレンジを書きました。おめでとうございます!
マーティンエンダー

回答:


9

Pyth、30 27バイト

f!-aVJ.u%-ysYN8zTtJ,1 7cR2T

アイデアは次のとおりです。

 1.5  1  0.5

  2       0

 2.5  3  3.5

クランクは常に半整数位置にありcます。各ステップで、をn設定することにより、整数位置ノートにそれを反映しますc = 2*n-c。場合はn有効で、c8の場合は±1 MODによって変化しn、無効であるc±3 MOD 8.私たちは、累積のすべての値を収集するために入力を超える削減によって変化しc、そしてすべてのノートが有効であったならば、参照してください。c最初の音符に隣接するものだけをチェックするよりも短いので、すべての開始値に対してこれを行います。

フォーマット済み:

f
  ! -
      aV J .u
              % -
                  y s Y
                  N
                8
              z
              T
         t J
      ,
        1 
        7
  cR2 T

テストスイート


18

CJam、34 31バイト

8,q{~2*f{_@-_zF8b&,@@+8,=*}0-}/

私の電話でこれをしたので、後で説明をしなければなりません。真実であれば、出力は空ではありません。

オンラインで試す | テストスイート

説明

新しいコードはレイアウトを少し変更します:

2    3    4

1    .    5

0/8  7    6

偶数は弦の位置に対応し、奇数はクランクの位置に対応します。

発生することは次のとおりです。

8,           Create the range [0 1 .. 7] of possible starting positions
             We can leave the string positions [0 2 4 6] in since it doesn't matter
q{ ... }/    For each character in the input...
  ~2*          Evaluate as integer and double, mapping "1234" -> [2 4 6 8]
  f{ ... }     Map over our possible current crank positions with the string
               position as an extra parameter
    _@-          Calculate (string - crank), giving some number in [-7 ... 7]
    _z           Duplicate and absolute value
    F8b          Push 15 base 8, or [1 7]
    &,           Setwise intersection and get length. If (string - crank) was in
                 [-7 -1 1 7] then the move was valid and this evaluates to 1, otherwise 0
    @@+          Calculate ((string - crank) + string)
    8,=          Take modulo 8, giving the new crank position. x%y in Java matches the
                 sign of x, so we need to do ,= (range + index) to get a number in [0 .. 7]
    *            Multiply the new crank position by our previous 0 or 1
  0-           Remove all 0s, which correspond to invalid positions

スタックは最後に自動的に印刷されます。可能な終了位置は出力にあります。たとえば、入力の場合1、出力は31です。つまり、クランクは左または上を向いて終了できます。

CJamのみに追加パラメーターのフィルターがある場合...


編集:この29バイトが機能することを確信している間、一時的にロールバックします。

8,q{~2*f{_@-_7b1#@@+8,=|}W-}/

37
誰かがcjamのような難しい言語で答えて「私の電話でこれをやった」と言うたびに、私は少し内側で死にます
デニスヴァンギルズ

2
彼はおそらくテキストが電話を使用して出力されたことを意味したが、それは彼の頭の中で行われた。
ネルソン

7

Haskell、93 88 87バイト

any(all(\(a,b:c)->1>mod(a!!1-b)4).(zip=<<tail)).mapM((\a->[[a,a+1],[a+1,a]]).read.pure)

これは、文字列を取り、ブール値を返す匿名関数に評価されます。テストスイートはこちら。

説明

次の図に従って、右側のラムダは数値a[[a,a+1],[a+1,a]]にマッピングし、その数値をクランクでとる2つの可能な「動き」にマッピングします。

  1 (2) 2

(1/5)  (3)

  4 (4) 3

メインの匿名関数では、まずmapM((...).read.pure)、各文字を整数に変換し、上記のラムダを適用して、2つのムーブのいずれかを選択し、結果のすべてのムーブシーケンスのリストを返します。次に、これらのシーケンスのいずれかに、各移動の2番目の数が次のモジュロ4の最初の数に等しいというプロパティがあるかどうかをチェックします。これは、物理的に可能なシーケンスであることを意味します。これを行うには、zipそれぞれのシーケンスをそのtailで移動しall、ペアの条件を確認し、anyシーケンスがに評価されるかどうかを確認しTrueます。



6

網膜127 109バイト

^((1|2)|(2|3)|(3|4)|(4|1))((?<2-5>1)|(?<5-2>1)|(?<3-2>2)|(?<2-3>2)|(?<4-3>3)|(?<3-4>3)|(?<5-4>4)|(?<4-5>4))*$

これにより、0または1が表示されます。

オンラインでお試しください!(これは、印刷0またはの代わりに、入力内のすべての一致をマークするわずかに変更されたバージョン1です。)

私はエレガントなアルゴリズムを考え出そうとしましたが、最初のいくつかの試みはバックトラッキングを回避できませんでした...そしてバックトラッキングの実装は迷惑です...有効なソリューション。残念ながら、エンコーディングはかなり冗長でかなり冗長です...これは短縮できると確信しています。

私はもっ​​とすてきなものを見つけようとしますが、誰かがこれがどのように機能するかを整理したい場合は、ここでやや読みやすいバージョンがあります:

^
(
    (?<a>1|2)
  | (?<b>2|3)
  | (?<c>3|4)
  | (?<d>4|1)
)
(
    (?<a-d>1) | (?<d-a>1)
  | (?<b-a>2) | (?<a-b>2)
  | (?<c-b>3) | (?<b-c>3)
  | (?<d-c>4) | (?<c-d>4)
)*
$

そして、ここにヒントがあります:

1  a  2

d  O  b

4  c  3

6

MATL57 55バイト

1t_hjnZ^!t1tL3$)2_/wvG1)UGnl2$Ov+Ys.5tv3X53$Y+4X\G!U=Aa

これは現在のリリース(10.2.1)を使用しますが、これはこの課題よりも前のものです。

言語の変化に起因する、:EDIT(2017年1月17日)v必要により置換されるべき&v、とtL3$)することによりY)(加えて、他のいくつかの改善が可能性が行うこと)。次のリンクには、これらの2つの変更が含まれています

オンラインでお試しください!

説明

これは、私のお気に入りのコードゴルフの2つのツール、ブルートフォースコンボリューションに基づいています。

コードが定義パス座標点でクランク続いて0.51.5各数値は、音符間のクランクの位置を指示など。コードは、最初に、入力文字列の最初のノートで始まるすべての可能なパスでパス配列を作成します。各パスは、この配列の列です。これはブルートフォースコンポーネントです。

このパス配列からノート配列が取得されます。各列は再生可能なノートの実現可能なシーケンスです。たとえば、位置から位置0.5への移動1.5は音符を生成し1ます。これは、位置間の平均を取得し、モジュロ4演算を適用することにあります。各列に沿った移動平均は、2D コンボリューションで行われます。

最後に、プログラムはノート配列の列が入力と一致するかどうかをチェックします。

1t_h        % row array [1, -1]
j           % input string
nZ^!        % Cartesian power of [1, -1] raised to N, where "N" is length of string
t           % duplicate
1tL3$)      % extract first row
2_/         % divide by -2
wv          % attach that modified row to the top of Cartesian power array
G1)U        % first character of input string converted to number, "x"
Gnl2$O      % column array of N-1 zeros, where N is length of input
v           % concat vertically into column array [x;0;0...;0]
+           % add with singleton expansion
Ys          % cumulative sum along each column. Each column if this array is a path
.5tv        % column array [.5;.5]
3X5         % predefined string 'same' (for convolution)
3$Y+        % 2D convolution of path array with [.5;.5]
4X\         % modified modulo operation. This gives note array with values 1,2,3,4
G!U         % column array of input string characters converted to numbers
=Aa         % true if any column of the note array equals this

5

Pyth、43

Km-R2sMdc`M%R4-VJjQTtJ`0|Fm!s-VKdCm_B^_1dlK

テストスイート

これはおそらく非常にゴルフに適しており、ゴルフに最適なアルゴリズムではありません(すべてのパスを列挙する方が短くなると思いますか?)...とにかく、アルゴリズムでエラーを見つけた場合はお知らせください、私はそれがうまくいくはずだと思いますが、 '以前は間違っていました!

の入力例を使用して、アルゴリズムを説明します1221。このプログラムは、次のように、最初に数字を後継者にマッピングします[[1,2],[2,2],[2,1]]。次に、modの差を取得します4(Pythはの正しい引数の符号と一致する結果を取得するため、%これは常に正です)[3,0,1]。次に、結果が分割され02それぞれから減算されます[[1],[-1]]

セットアップが完了したので、リスト[-1,1,-1...]とその否定を作成します[1,-1,...]。どちらも前の結果の配列と同じ長さです。次に、これらのリストのそれぞれについて、リストの要素と前の手順で生成されたリストのセットワイズ減算を実行します。次に、いずれかの結果に空のリストのみが含まれる場合、trueを出力します。


「結果が0で分割される」とはどういう意味ですか?特に、あなたは何をするためになるだろう12212211221441
ニール

1
@Neil 1221221はfalseであり1221441、全体としてtrueになりますが、アルゴリズムのそのステップの後の結果が必要なことがわかった場合、その場合はそれができます:から[3, 0, 1, 3, 0, 1]まで[[3], [1, 3], [1]][3, 0, 1, 1, 0, 3]します[[3], [1, 1], [3]]。他に何か説明したい場合はお知らせください:)
FryAmTheEggman

私は以前よりも混乱していると思うので、これらの2つの例を終了して、(正しい)結果がどのように達成されるかを説明してください。
ニール

1
@Neil確かに、問題ありませんが:)そこから、我々は、取得するための減算を行います。[[1], [-1, 1], [-1]]そして[[1], [-1, -1], [1]]ここから、あなたは最初のものは間の代替というリストを持っていないことがわかります-1し、1最終的な結果を与え、他のリストしばらくはありません。このアルゴリズムは、ビット鈍角であるが、それは基本的に方向を変更するマッピングの0ようにして方向性を+/-1何らのジャンプが行われていないとの方向が意味をなすしていることを確認し、。
FryAmTheEggman

ああ、私が欠けていたのは、各分割リストが同じ値で構成されていなければならず、それらの値が交互に並んでいなければならないということでした。ありがとう!
ニール

4

Matlab、279 180バイト

o=eye(4);a=input('')-'0';M=[o,o(:,[4,1:3]);o(:,[2:4,1:4,1])];x=2;for p=[a(1),mod(a(1),4)+1];for k=a;i=find(M*[o(:,k);o(:,p)]>1);if i;p=mod(i-1,4)+1;else;x=x-1;break;end;end;end;x>0

非常に怠zyな解決策ですが、私が思いつくことができた最短。私は特別な行列を作成しました:あなたはpluckerの状態と摘まされる最後の文字列をエンコードする場合、それはpluckerの新しい位置をコードするベクターを、返し、以前かどうか摘むがすべてで可能でした。ここで、2つの可能な開始位置からすべてのノートをループし、そのうちの1つが演奏可能なメロディーになるかどうかを確認します。おそらくもっとたくさんゴルフできるでしょう。

展開され説明されたソース:

o=eye(4);
a=input('')-'0';

% encoding of plucker/notes
%      1
%   1     2
%4           2
%   4     3
%      3
%

M=[...
%12 3 4 1 2 3 4 <
1,0,0,0,0,1,0,0; %1  k = current note
0,1,0,0,0,0,1,0; %2  
0,0,1,0,0,0,0,1; %3  
0,0,0,1,1,0,0,0; %4  
0,0,0,1,0,0,0,1; %1  p = current position of plucker
1,0,0,0,1,0,0,0; %2
0,1,0,0,0,1,0,0; %3
0,0,1,0,0,0,1,0];%4
% the vector we multiply with this matrix has following structure,
% the k-th and the p+4 th entries are 1, the rest 0
% when we multiply this vecotr with this matrix, we get a vector with an
% entry of value 2 IF this is a valid move ( mod(positionOfThe2 -1,4)+1 is
% the position of the plucker now)
% or only entries less than 2 it is impossible
x=2;  %number of "chances" to get it right
for p=[a(1),mod(a(1),4)+1] %check both starting values;
    for k=a;                %loop throu the notes
        size(M);

        c = M * [o(:,k);o(:,p)];
        i=find(c>1);               %did we find a 2?
        if i;
           p=mod(i-1,4)+1;         %if yes, valid move
        else;
            x=x-1;                 %if no, invalid, 
            break;
        end 
    end
end
x=x>0 %if we failed more than once, it is not possible

4

ES6、104の 100バイト

s=>!/13|24|31|42|3[24]{2}1|4[13]{2}2|1[24]{2}3|2[13]{2}4|(.).\1/.test(s.replace(/(.)(\1\1)+/g,"$1"))

編集:@DigitalTraumaのおかげで4バイトを保存しました。

私の以前のアプローチに欠陥があったので、これは完全な書き直しです。

最初に、実行中に奇数または偶数があったかどうかに応じて、数字のすべての実行を1または2に減らします。次に、すべての違法な組み合わせを探します。

  • 13|24|31|42 (反対側)
  • 3[24]{2}1として32213441違法です
  • 同様のため4xx21xx3そして2xx4どこx行方不明の数字のいずれかであります
  • (.).\1のようなもの121は違法であるため(以前に111削減されまし1た)

不正なペアまたは「トリプル」がない場合、文字列全体が合法です(ここでは深夜なので、誘導による証明は演習として残されています)。

3[24]{2}1|1[24]{2}3ネガティブな先読みアサーションを使用して単純化しようとしましたが、その方が長くなることがわかりました。


f("1122") => true@DigitalTrauma
コナーオブライエン

@CᴏɴᴏʀO'Bʀɪᴇɴ私はそれについて何も悪いことは見ていません。一方f("1221221")、間違った答えを出力することに気づいたので、考え直さなければなりません。
ニール

'43221'が失敗するテストスイートを含めることは常に便利です。jsbin.com/ vafitotequ
Pavlo

@パブロフープ、私はゴルフ[24][24]をした(2|4)\1が、十分にテストしていなかった ごめんなさい
ニール

あなたのゴルフができ[24][24][24]{2}
デジタル外傷

2

JavaScript(ES6)、80バイト

s=>[r=0,1,2,3].map(i=>[...s].map(n=>n-1-i%4?n%4-i%4?v=0:i+=3:i++,v=1)|v?r=1:0)|r

説明

i%4 現在のクランク位置です:

    1 (i%4 == 1) 2   

(i%4 == 0) (i%4 == 2)

    4 (i%4 == 3) 3   

インデントとコメント

s=>
  [r=0,1,2,3].map(i=> // i = crank position, test for i starting at 0 to 3, r = result
    [...s].map(n=>    // for each note n
      n-1-i%4?        // if n is not at the position after i
        n%4-i%4?      // if n is not at the position before i
          v=0         // set the result of this test to invalid
        :i+=3         // else i-- (+3 used because i%4 would break for negative values)
      :i++,           // else i++
      v=1             // v = result of test, initialise to 1 (valid)
    )
    |v?r=1:0          // if the test returned true, set the result to true
  )
  |r                  // return the result

テスト

var solution = s=>[r=0,1,2,3].map(i=>[...s].map(n=>n-1-i%4?n%4-i%4?v=0:i+=3:i++,v=1)|v?r=1:0)|r
<input type="text" value="1221441" oninput="result.textContent=solution(this.value)" />
<pre id="result"></pre>


よくできました。|この場合の仕組みを説明してください。
パブロ

1
@pavloありがとう。短い書き方(x.map(...),v)です。がmap返す配列は0andにキャストするため、機能し0|v == vます。
user81655

2

Lua146142108162159149144135132118113バイト

z,q,s=0,0,io.read()for i in s:gmatch'.'do t=i-z if 2==math.abs(t)or t==q then return''end q=-t z=i end return 2>1

1から4までの数字の文字列を指定すると、trueまたはfalseを返します(データを処理しないか、範囲外の数字を処理しません。

単に最後の動きが何であったかを追跡し、この動きが最後の動き(IE、121または12221)の反転かどうか、または移動距離が可能な範囲を超えているかどうかを確認します。

編集1

6バイトを保存しました。if (int) thenintがゼロ以外の場合にtrue を返すことを忘れていました。

副<文>この[前述の事実の]結果として、それ故に、従って、だから◆【同】consequently; therefore <文>このような方法で、このようにして、こんなふうに、上に述べたように◆【同】in this manner <文>そのような程度まで<文> AひいてはB◆【用法】A and thus B <文>例えば◆【同】for example; as an example:

if t~=0 then

変更点:

if t then

また、再構築により数バイトを節約しました。

編集2

私はゆっくりとこれを理解しています。私はここでドキュメントを読んでいます:http : //www.lua.org/pil/そして、ゴルフのためにそこにあるより有用なページの1つはhttp://www.lua.org/pil/3.3.htmlです

特に、これは非常に役立ちます。

制御構造と同様に、すべての論理演算子はfalseとnilをfalseと見なし、他のすべてをtrueと見なします。

これが意味することは、設定されるまで「false」と見なされるため、先に進み、q(最初は0に設定されていた)の宣言を削除できることです。そのため、これによりさらに数バイト節約できます。

言及する価値のあるもう1つのことは、使用していませんが、Luaで値を交換する場合、一時変数を必要とせ a,b=b,aずに単純に実行できることです。

編集3

そのため、いくつかの巧妙な再構築と新しい関数により、バイトカウントがさらに9カウントダウンされました。

入力を受信するための最適なモード

数字のリストを読み、それらを一度に1つずつ操作する必要がある場合は、次を使用できます。

for x in string:gmatch('.') do
    print(x) --This is our number
end

string:subを使用した代替と比較すると、ゴルフ(または一般的な使用)の値を確認できます。

for x=1,string:len() do
    print(string:sub(x,x)) --This is our number
end

関数または文字列を再構築する

次に、1行に複数の宣言があり、値の1つが関数である場合、または数値を次のような関数の結果と比較する条件がある場合:

x,y,z=io.read(),0,0 print('test')

if math.abs(x)==2 then

閉じ括弧が条件または宣言の最後の文字になるように再構成することにより、次のように文字を切り取ることができます。

y,z,x=0,0,io.read()print('test') --Notice no space

if 2==math.abs(x)then --If we put the '2' first in the conditional statement, we can now remove a space character

「True」または「False」の代わりにTrueまたはFalseに等しい条件を返す

バイトカウントをさらに削減するための半面白い方法を見つけました。trueまたはfalseを返す必要がある場合は、「true」または「false」自体よりも文字数が少ないtrueまたはfalseに相当するステートメントを返すことができます。

たとえば、比較します:

return true
return false

に:

return 2>1
return 1>2

121falseを出力する必要があります。
リトシアスト

ああ、気にしないで。そうですか。間もなく修正されます
Skyl3r

Luaのゴルフのヒントが表示されていない場合は、これらのLuaのヒントの一部をLua でのゴルフのヒントに追加してください。
-apsillers

2

MATL、49バイト(非競合1

1.答えは(ab)新しいバージョンのMATLのより厳密でないインデックスを使用しており、このチャレンジが投稿された時点では機能しませんでした。

dt~aX`tt~f1)q:)w3MQJh)_ht~a]tT-3hX|n2=wT_3hX|n2=+

オンラインでお試しください!

ベストオブPPCG 2016でこの課題を見て、これが私のお気に入りの演算子を使用できると考えました。

d

または、diffMATLAB / Octaveで(人間にとって読みやすいので、MATLAB / Octaveの用語を説明で自由に使用します)。このコマンドは、ベクトル内、またはこの場合は文字配列内の要素ごとの差を計算します。

この問題では、違いは興味深いパターンを示しています。ご了承ください

方向の変更は、ノートが2回再生されることを意味する必要があります。

差のパターンの場合(1-4今のところ移行を無視)、これは

サインインの変更には、間にゼロの奇数diff(input)必要です。反対に、偶数のゼロの後に符号を変更することはできません。


これを実装するには、配列ごとに最初のゼロを見つけます。ゼロを切り取り、その後のすべての要素にを掛けます-1。最終結果では、これはすべての要素が同じ符号を持たなければならないことを意味します。もちろん、小さな問題がある-3等しく+1、そして2一般的に禁止されています。これを解決するには、結果の集合の和集合を取得し、[1 -3]これがサイズ2であるかどうかを確認します(つまり、許可されていない要素が和集合を介して集合に「入った」ことはありません)。について繰り返し、[-1 3]一方(または長さが1の入力の場合は両方)が真であるかどうかを確認します。

d                                % Difference of input
 t~a                             % Check if any element equals 0
    X`                     t~a]  % Start while loop, ending in the same check
       t~                           % Get a new vector, logical negated to find zeroes.
          f1)                       % Find the position of the first zero. 
      t         q:)                 % Decrement by 1, to index all elements before that zero.
                   w3MQJh)          % Push the result of 'find', but increment to get all elements after.
                         _h         % Multiply the second half by -1, and concatenate horizontally.

  T-3hX|n2=                      % Check if set union with [1 -3] is size 2
 t        wT_3hX|n2=             % Check if set union with [-1 3] is size 2
                    +            % Logical OR. 

@LuisMendoありがとう。M前回読んだとき、本当に読んでおく必要がありますが、予想とは異なる動作をしたため、当面は無視しました。そうする必要があると言うのは正しいですか?それ3M)、notの入力を取得するのではなく、の入力を取得するため:ですq通常の機能でwはないのでスキップします)?
-Sanchises

はい、正確に。w通常の機能ではないため、スキップされます。入力を
受け取ら

2

パイソン(3.5)160 151 150バイト

再帰的な解決策

def f(s):g=lambda s,c:s==''or g(s[1:],(c[:4]*2)[(s[0]==c[0])*2+1:])if s==''or s[0]in c[:2]else 0;return any([g(s,"1234123"[i:])for i in range(4)])

ラムダなしのゴルフなし

def f(s):
    def g(s,c):
        if s=='' or s[0] in c[:2] :
            return s=='' or g(s[1:],(c[:4]*2)[(s[0]==c[0])*2+1:])
        else:
            return False
    return any([g(s,"1234123"[i:]) for i in range(4)])

クランクの代わりにすべてのボックスを回転させます。クランク位置は、cストリングの最初の文字と2番目の文字の間にあります。クランクのすべての開始位置をテストする必要があります。

トリックを使用して文字列を回転させる

Python(s[i:]+s[:i])で文字列を回転させる通常の方法では、インデックスと文字列の両方を繰り返す必要があります。この場合、文字列を複製し、最初の文字を切り取ります。

(c*2)                        # duplicate the string
     [(s[0]==c[0])*2+1       # test that return 1 if firsts characters match 3 instead 
                      :]     
                        [:4] # crop again to have a 4 characters string

テストケース

[f(i) for i in ["1", "1234", "1221", "3333", "143332", "22234", "2234", "22214", "1221441", "41233", "13", "1224", "121", "12221", "43221"]]
[True, True, True, True, True, True, True, True, True, True, False, False, False, False, False]

1
でスペースを削除でき3"[i:]) forます。
エリックアウトゴルファー

@EriktheOutgolferありがとう、削除します。
エルワン


1

JavaScript(ES2015)、 110 95

p=(s,d)=>(h=s[0],t=s.slice(1),g=t[0],!g||(d?g==h?p(t,-d):g%4==(h-d)%4&&p(t,d):p(s,1)||p(s,-1)))

Neilによって15バイトが節約されました!元のバージョンungolfed:

p = (s, d) => {
  h = s[0]
  t = s.substr(1)

  if (!t[0]) return true
  if (!d) return p(s, 1) || p(s, -1)
  if (t[0] == h) return p(t, d*-1)
  if (t[0] == (h-d > 4 ? 1 : h-d || 4)) return p(t, d)

  return false
}

テスト:https : //jsbin.com/cuqicajuko/1/edit?js,console


1
17バイト節約しました:(s,d)=>(h=s[0],t=s.slice(1),g=t[0],!g||(d?g==h?p(t,-d):g%4==(h-d)%4&&p(t,d):p(s,1)||p(s,-1)))
ニール

それでも@ user81655の答えほど短くはありません。
ニール

1

チューリングマシンコード、395バイト

0 1 _ r a
0 2 _ r b
0 3 _ r c
0 4 _ r d
a 1 _ r a
a 2 _ r E
a 3 _ r h
a 4 _ r S
b 1 _ r W
b 2 _ r b
b 3 _ r S
b 4 _ r h
c 1 _ r h
c 2 _ r N
c 3 _ r c
c 4 _ r W
d 1 _ r N
d 2 _ r h
d 3 _ r E
d 4 _ r d
N 1 _ r W
N 2 _ r E
N _ _ r r
N * _ r h
E 2 _ r N
E 3 _ r S
E _ _ r r
E * _ r h
S 3 _ r E
S 4 _ r W
S _ _ r r
S * _ r h
W 4 _ r S
W 1 _ r N
W _ _ r r
W * _ r h
h _ 0 r halt
h * _ r h
r _ 1 r halt

オンラインでお試しください!

これは基本的に状態ベースのアプローチです。

  • 初期状態は0です。
  • abc、とdだけ最初に発生している「未定状態」
  • NES、とW明らかに放置、 "決めた状態"であり、Nオース、EAST、SOUTH、およびWEST。

1

火、203バイト

ここまでゴルフをする方法は考えられません。

0::=:::
>11::=>1
>22::=>2
>33::=>3
>44::=>4
>12::=b
>21::=d
>14::=c
>41::=a
>23::=c
>32::=a
>34::=d
>43::=b
a1::=d
a2::=b
b2::=a
b3::=c
c3::=b
c4::=d
d4::=c
d1::=a
a<::=~n
b<::=~e
c<::=~s
d<::=~w
::=
>0<

ノートシーケンスが可能な場合、終了方向が出力されます。それ以外の場合、出力は空になります。


1

プロローグ(SWI)、117バイト

a(N,P):-P=N;N=1,P=4,!;P is N-1.
m([A,B|C],[X,Y|Z]):-a(A,X),a(B,X),a(B,Y),X\=Y,m([B|C],[Y|Z]).
m([_],_).
p(N):-m(N,_).

p再生可能な入力(整数のリストとして与えられる)で成功し、再生できない入力で失敗する述語を定義します。オンラインでお試しください!

説明

aノートNとクランクポジションの隣接関係を定義しますP。位置pを音符pp + 1の間に定義します。したがって、位置は音符に隣接していますNiff

  • 等しいNP=N); または
  • ノートは1で、位置は4(N=1,P=4)です。または
  • 上記の場合は真ではなく(!)、位置は等しいN-1P is N-1)。

mノートのリストを取得し、それらのノートを再生する位置のリストを生成しようとします。A演奏されたばかりの音符、演奏さBれようとしている音符です。Xは現在のクランク位置、Y次のクランク位置です。移動は有効な場合のみ

  • 演奏されたばかりの音符は、現在のクランク位置(a(A,X))に隣接しています。
  • 演奏しようとしている音符も現在のクランク位置に隣接していa(B,X)ます()。
  • 演奏しようとしている音符は次のクランク位置に隣接していa(B,Y)ます()。そして
  • 2つのクランク位置は等しくありません(X\=Y)。

これらすべてが成り立つ場合、再帰します。1つの音符(m([_],_))に到達すると、一連の音符が再生可能になります。

この質問では、一連の動きが存在するかどうかだけを気にするので、生成されたクランク位置のリストpを呼び出しmて破棄することを定義します。

無償版を参照し、すべてのテストケースをここで確認してください

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