Diffyゲームは劣化していますか?


23

最近、Diffyゲームに関する質問を投稿しましたが、回答がありませんでした。結構です、質問は本当に難しいですが、Diffyゲームについて簡単な質問をして、ボールが転がるようにしたいと思います。


Diffyの仕組み

Find Diffy Gamesからコピー

Diffyゲームは次のように機能します。まず、負でない整数のリストから始めます。この例では、

3 4 5 8

次に、隣接する番号の絶対差を取ります

 (8)  3   4   5   8
    5   1   1   3

その後、繰り返します。ループに入ったことに気付くまで繰り返します。そして、一般的にゲームは最初から再び始まります。

3 4 5 8
5 1 1 3
2 4 0 2
0 2 4 2
2 2 2 2
0 0 0 0
0 0 0 0

ほとんどのゲームは負け状態とみなされるすべてゼロの文字列で終了しますが、まれにいくつかのゲームが大きなループでスタックすることがあります。


仕事

Diffyゲームの開始状態を考慮して、ゲームが最終的にすべてゼロの状態に到達するかどうかを判断します。2つの状態ごとにTruthyまたはFalsyの値を出力する必要があります。どちらに対応するかは重要ではありません。

目標は、ソースのバイト数を最小限にすることです。


1
したがって、タスクの言葉遣いは、すべてゼロの状態に到達しないゲームは周期的であることを暗示しているようです。以前は、繰り返しシーケンスに初期状態を含めると定義されています。これは、シーケンスが最終的にすべてゼロまたは初期状態に到達することを意味しますか?
-trichoplax

3
いいえ:ゼロ以外の周期的な状態に正の定数を追加すると、それ自体に戻ったり、すべてゼロになったりしない状態になります。たとえば、1 1 0周期的であるため、その42 42 41ような状態でもあります。
グレッグマーティン

3
確かに、特定の質問に対しては、「定期的な」という概念さえ必要ありません。「最終的にすべてゼロの状態に達する」は自己完結型で明確です。
グレッグマーティン

2
部分的な特性を証明しました:リストの長さnが奇数の場合、すべての数値が等しくなければゲームはゼロになりません。長さが2の累乗の場合、常にゼロになります。
xnor

3
ゼロに到達するためのステップ数の境界:n要素と最大のリストmは多くてもn * bit_length(m)ステップをとります。だから、n*mまた上限です。強い上限はt(n) * bit_length(m)t(n)、はの因数である2の最大の累乗ですn
-xnor

回答:


27

Pyth、6バイト

suaV+e

テストスイート

このプログラムは非常に洗練されています。0(偽)はすべてゼロを意味し、その他(真)はすべてゼロではないことを意味します。

使い方:

suaV+e
suaV+eGGGQ    Variable introduction.
 u       Q    Apply the following function repeatedly to its previous result,
              starting with the input. Stop when a value occurs which has
              occurred before.
  aV          Take the absolute differences between elements at the same indices of
        G     The previous list and
    +eGG      The previous list with its last element prepended.
s             The repeated value is returned. Sum its entries. This is zero (falsy)
              if and only if the entries are all zero.

6
thatsの上品ソリューション
マルタインVissers

14

Mathematica、52バイト

1>Max@Nest[Abs[#-RotateLeft@#]&,#,Max[1+#]^Tr[1^#]]&

入力として非負整数のリストを取り、Trueまたはを返す純関数False

Abs[#-RotateLeft@#]&diffyゲームを1ラウンド実行する関数です。(技術的にはである必要がRotateRightありますが、究極の答えは影響を受けません。そして、フリーバイトです。)ラウンドのdiffyゲームをNest[...,#,R]実行し、結果がすべてゼロかどうかR1>Max@検出します。

実行するdiffy-gameラウンドの数を知るにはどうすればRよいですか 場合はm、入力で最大値であり、予告我々はより大きな整数を生成しないことをm私たちはどのように多くのラウンドに関係なく。でl区切られた非負整数の長さのリストの総数m(m+1)^lです。したがって(m+1)^l、diffyゲームのラウンドを実行する場合、それまでにリストを2回見ることが保証されているため、ゲームの定期的な部分になります。特に、ゲームの(m+1)^lラウンドの結果がすべてゼロのリストである場合にのみ、ゲームはすべてゼロで終了します。その式がMax[1+#]^Tr[1^#]計算されます。


6

ゼリー、13 バイト

Ṁ‘*L
ṙ1ạ
ÇÑ¡Ṁ

すべてゼロの状態に到達する場合は0(偽)を出力します。そうでない場合は、真理値(正の整数)が返されます。

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

使用する最初の観察グレッグ・マーティン製アレイ内の数字は、ドメイン離れることはないことを[0、M] mはそう実行、入力における最大の要素であるが(M + 1)L個のラウンドLは入力の長さ意志です十分です

どうやって?

Ṁ‘*L - Link 1, number of rounds to perform: list a
Ṁ    - maximum of a
 ‘   - incremented
   L - length of a
  *  - exponentiate

ṙ1ạ - Link 2, perform a round: list x
ṙ1  - rotate x left by 1
  ạ - absolute difference (vectorises) with x

ÇÑ¡Ṁ - Main link: list a
  ¡  - repeat:
Ç    -     the last link (2) as a monad
 Ñ   -     the next link (1) as a monad times
   Ṁ - return the maximum of the resulting list

これはxnorのバウンドで改善できますか?
小麦ウィザード

@WheatWizard 1バイトかかると思います。(すべての結果を一意でないまで収集することで、より短い方法を取得することは可能かもしれませんが、私はそれを見つけていません)。
ジョナサンアラン

2

PHP、144バイト

すべてゼロの場合は0を、真の場合は正の整数値を出力します

<?for($r[]=$_GET[0];!$t;){$e=end($r);$e[]=$e[$c=0];for($n=[];++$c<count($e);)$n[]=abs($e[$c-1]-$e[$c]);$t=in_array($n,$r);$r[]=$n;}echo max($n);

オンライン版

拡大

for($r[]=$_GET;!$t;){
    $e=end($r);  # copy last array
    $e[]=$e[$c=0]; # add the first item as last item
    for($n=[];++$c<count($e);)$n[]=abs($e[$c-1]-$e[$c]); # make new array
    $t=in_array($n,$r); # is new array in result array
    $r[]=$n; # add the new array
}
echo max($n); # Output max of last array

1
array_push?しかし、なぜ ?
クリストフ

1
また、$_GET入力として使用する場合は、文字列が含まれていると想定する必要があります。
クリストフ

1
@Christoph ?0[0]=1&0[1]=1&0[2]=0or ?0[]=1&0[]=1&0[]=0は文字列の配列ですが、これは重要ではありません。しかし、あなたは正しいです、?0=1&1=1&2=0なぜàrray_pushを使わないで短くすることができますか?
ヨルグヒュルサーマン

1
array_push($e,$e[$c=0]);はまったく同じで、$e[]=$e[$c=0];すでに構文($r[]=$n)を使用している場合もあります。あなたは既に使用maxあなたも交換する必要がありますので、今すぐend($r)$nあるため$n、常にに等しいend($r)エコーが実行されたとき。
クリストフ

@Christoph昨日は私の日ではなかったようです。ありがとうございました。ヒントセクションの新しいエントリのための私のアイデアに私をもたらしました
ヨルクヒュルサーマン

2

R(3.3.1)、87バイト

すべてゼロで終わるゲームの場合はゼロを返し、それ以外の場合は正の数を返します。

z=scan();sum(Reduce(function(x,y)abs(diff(c(x,x[1]))),rep(list(z),max(z+1)^length(z))))

Greg Martinによる同じ事実を活用し、組み込みdiffを使用してdiffy-ing


xnorのバウンドが(コメントから)正しい場合、これはmax(z)* length(z)を使用することで2バイト短くなる可能性がありますが、私はその正確さを確信していません
ジュゼッペ

1

ローダ、80バイト

f l...{x=[{peek a;[_];[a]}()|slide 2|abs _-_];[sum(x)=0]if[x in l]else{x|f*l+x}}

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

ゴルフをしていない:

function f(l...) { /* function f, variadic arguments */
    x := [ /* x is a list of */
        { /* duplicate the first element of the stream to the last position */
            peek a /* read the first element of the stream */
            [_]    /* pull all values and push them */
            [a]    /* push a */
        }() |
        slide(2) | /* duplicate every element except first and last */
        abs(_-_)   /* calculate the difference of every pair */
    ]
    /* If we have already encountered x */
    if [ x in l ] do
        return sum(x) = 0 /* Check if x contains only zeroes */
    else
        x | f(*l+x) /* Call f again, with x appended to l */
    done
}

1

05AB1E、13バイト

戻り値1を、それがゼロに終了した場合0そう。

Z¹g*F¤¸ì¥Ä}_P

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

説明

ラウンドの上限を使用します:コメントセクションでxnormax(input)*len(input)によって説明されています。

Z              # get max(input)
 ¹g            # get length of input
   *           # multiply
    F          # that many times do:
     ¤         # get the last value of the current list (originally input)
      ¸        # wrap it
       ì       # prepend to the list
        ¥      # calculate deltas
         Ä     # calculate absolute values
          }    # end loop
           _   # negate each (turns 0 into 1 and everything else to 0)
            P  # calculate product

1

J、22バイト

すべてゼロで終了する縮退ゲームの0(実質的falseにJにある)を返します。n番目の反復にゼロ以外の数値が含まれる場合、1true)を返します。nは、元のシーケンスの最大整数にリストの長さを掛けた値に等しくなります。なぜこれが真実であるかを説明するグレッグマーティンの回答を参照してください。

*>./|&(-1&|.)^:(#*>./)

翻訳:

  • サインは何ですか *
  • 最大の価値の >./
  • 以下を何回も繰り返したとき ^:( )
  • リストの長さとリスト内の最大値の#積: *>./
    • の絶対値|&を取る
    • リスト(- )との違い
    • リストを1つ回転 1&|.

例:

   *>./|&(-1&|.)^:(#*>./) 1 1 0
1
   *>./|&(-1&|.)^:(#*>./) 42 42 41
1
   *>./|&(-1&|.)^:(#*>./) 3 4 5 8
0
   *>./|&(-1&|.)^:(#*>./) 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1
0

1
グレッグ・マーティンの主張はそうではありません。ただし、上記のコメントにはxnorの方が優れた境界があります(ただし、最大の整数だけではありません)。最も簡単なのは、最大値に長さを掛けることです。
Ørjanヨハンセン

良いキャッチ。私は十分な注意を払っていませんでした。ソリューションを修正します。
デーン

1

JavaScript(ES6)、95 92 90バイト

f=(a,b=(Math.max(...a)+1)**(c=a.length))=>b?f(a.map((v,i)=>v-a[++i%c]),b-1):a.every(v=>!v)

説明

カウンター(リストの最大値に1を加えたリストの長さ[ = (max + 1)**length] で始まる)がゼロでない限り、それ自体を呼び出す再帰関数。呼び出しごとに、カウンターはデクリメントされ、ゼロに達すると、リスト内のすべての要素がゼロに対してチェックされます。それらがすべてゼロに等しい場合、プログラムはを返しtruefalseそうでない場合は返します。


1

PHP、123 115

for($a=$_GET,$b=[];!in_array($a,$b);){$b[]=$c=$a;$c[]=$c[0];foreach($a as$d=>&$e)$e=abs($e-$c[$d+1]);}echo!max($a);

HTTP経由で入力を取得 ?3&4&5&8数バイト節約ます。

すべてゼロに達するか、それ以外の場合は1を出力します。


for($e=$argv,$r=[];!in_array($e,$r);$q=$e[0]){$e[0]=end($e);$r[]=$e;foreach($e as$k=>&$q)$q=abs($q-$e[$k+1]);}echo!max($e);

コマンドライン経由で引数のリストを取得します。これをさらにゴルフにかけることができると感じています(@Titusを見て)。


1

Python 3.6、101バイト

def f(t):
 x={}
 while x.get(t,1):x[t]=0;t=(*(abs(a-b)for a,b in zip(t,t[1:]+t[:1])),)
 return any(t)

数値のタプルを受け取り、ゼロで終わる場合はFalseを返し、ループする場合はTrueを返します。


0

JavaScript(ES6)、84 83バイト

それ以外の場合trueは、すべてゼロで終わるゲームに対して戻りますfalse

f=(a,k=a)=>k[b=a.map((n,i)=>Math.abs(n-a[(i||a.length)-1]))]?!+b.join``:f(k[b]=b,k)

テスト

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