Apakah game Diffy saya merosot?

23

Baru-baru ini saya posting sebuah pertanyaan tentang game Diffy yang telah terjawab. Baiklah, pertanyaannya sangat sulit, tetapi saya ingin membuat pertanyaan yang lebih mudah tentang permainan Diffy sehingga kita bisa mendapatkan bola yang menggelinding.


Bagaimana Diffy bekerja

Disalin dari Find Diffy Games

Gim Diffy bekerja seperti berikut: Anda mulai dengan daftar bilangan bulat non-negatif, dalam contoh ini kita akan gunakan

3 4 5 8

Kemudian Anda mengambil perbedaan absolut antara angka-angka yang berdekatan

 (8)  3   4   5   8
    5   1   1   3

Lalu kamu ulangi. Anda ulangi sampai Anda menyadari bahwa Anda telah memasukkan satu lingkaran. Dan kemudian umumnya permainan dimulai dari awal lagi.

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

Kebanyakan gim berakhir dengan serangkaian nol semua, yang dianggap sebagai keadaan kalah, tetapi beberapa gim jarang terjebak dalam loop yang lebih besar.


Tugas

Mengingat keadaan awal permainan Diffy menentukan apakah permainan akhirnya mencapai keadaan nol semua. Anda harus menampilkan nilai Truthy atau Falsy untuk masing-masing dua negara. Yang sesuai dengan yang tidak masalah.

Tujuannya adalah untuk meminimalkan jumlah byte di sumber Anda.

Wisaya Gandum
sumber
1
Oleh karena itu, tugas susunan kata menyiratkan bahwa game apa pun yang tidak mencapai semua nol bersifat berkala. Sebelumnya, periodik didefinisikan sebagai termasuk keadaan awal dalam urutan yang diulang. Apakah ini berarti bahwa setiap urutan akhirnya mencapai semua nol atau keadaan awal?
trichoplax
3
Tidak: menambahkan konstanta positif ke keadaan periodik bukan nol menghasilkan keadaan yang tidak kembali ke dirinya sendiri atau masuk ke semua nol. Misalnya, 1 1 0periodik, begitu 42 42 41juga keadaannya.
Greg Martin
3
Memang, untuk pertanyaan spesifik yang diajukan, seseorang bahkan tidak memerlukan gagasan "periodik". "Akhirnya mencapai keadaan nol" adalah mandiri dan jelas.
Greg Martin
2
Saya telah membuktikan karakterisasi parsial: Jika panjang daftar naneh, permainan tidak pergi ke nol kecuali semua angkanya sama. Jika panjangnya adalah kekuatan 2, selalu menjadi nol.
xnor
3
Batas jumlah langkah untuk mencapai nol: Daftar dengan nelemen dan maksimum mmengambil paling banyak n * bit_length(m)langkah. Jadi, n*mjuga merupakan batas atas. Batas atas yang lebih kuat adalah t(n) * bit_length(m), di mana t(n)kekuatan terbesar 2 adalah faktor n.
xnor

Jawaban:

27

Pyth, 6 byte

suaV+e

Suite uji

Program ini sangat ramah tamah. 0 (falsy) berarti semua nol, yang lainnya (benar) berarti tidak semua nol.

Bagaimana itu bekerja:

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.
isaacg
sumber
6
itu solusi ramah tamah
Martijn Vissers
14

Mathematica, 52 byte

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

Fungsi murni mengambil daftar bilangan bulat negatif sebagai masukan dan pengembalian Trueatau False.

Abs[#-RotateLeft@#]&adalah fungsi yang mengeksekusi satu putaran permainan dify. (Secara teknis seharusnya RotateRight, tetapi jawaban pamungkas tidak terpengaruh, dan hei, byte gratis.) Jadi Nest[...,#,R]jalankan Rputaran permainan diffy, dan kemudian 1>Max@mendeteksi apakah hasilnya semua nol.

Bagaimana kita tahu berapa banyak putaran permainan yang Rharus dilakukan? Jika mmerupakan nilai terbesar dalam input, perhatikan bahwa kami tidak akan pernah menghasilkan bilangan bulat yang lebih besar daripada mberapa pun putaran yang kami lakukan. Jumlah total daftar panjang lbilangan bulat tidak negatif yang dibatasi oleh semua madalah (m+1)^l. Jadi jika kita melakukan (m+1)^lputaran permainan dify, kita dijamin telah melihat daftar dua kali saat itu, dan dengan demikian akan berada di bagian periodik permainan. Khususnya, permainan berakhir di semua nol jika dan hanya jika hasil (m+1)^lputaran permainan adalah daftar semua-nol. Ekspresi itulah yang Max[1+#]^Tr[1^#]menghitung.

Greg Martin
sumber
6

Jelly , 13 byte

Ṁ‘*L
ṙ1ạ
ÇÑ¡Ṁ

Output 0 (falsey) jika semua keadaan nol akan tercapai, jika tidak nilai kebenaran (bilangan bulat positif) dikembalikan.

Cobalah online!

Menggunakan pengamatan yang pertama kali dilakukan oleh Greg Martin bahwa angka-angka dalam array mungkin tidak pernah meninggalkan domain [0, m] di mana m adalah elemen maksimal dalam input, sehingga melakukan (m + 1) l putaran di mana l adalah panjang input akan cukup.

Bagaimana?

Ṁ‘*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
Jonathan Allan
sumber
Bisakah ini diperbaiki dengan terikat xnor ?
Wheat Wizard
@WheatWizard Saya pikir itu akan menelan biaya satu byte. (Mungkin dimungkinkan untuk mendapatkan metode yang lebih pendek dengan mengumpulkan semua hasil sampai hasilnya tidak unik, tetapi saya belum menemukannya).
Jonathan Allan
2

PHP, 144 Bytes

cetak 0 untuk semua nol dan semua nilai integer positif untuk true

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

Versi Online

Diperluas

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
Jörg Hülsermann
sumber
1
array_push? Tapi kenapa ?
Christoph
1
juga jika menggunakan $_GETsebagai input Anda harus menganggapnya berisi string.
Christoph
1
@ Christoph ?0[0]=1&0[1]=1&0[2]=0atau ?0[]=1&0[]=1&0[]=0array string tetapi ini tidak masalah. Tapi Anda benar saya bisa membuatnya lebih pendek dengan ?0=1&1=1&2=0mengapa tidak àrray_push` Saya yakin Anda atau Titus menemukan cara yang lebih baik untuk mempersingkat ini.
Jörg Hülsermann
1
array_push($e,$e[$c=0]);sama persis dengan $e[]=$e[$c=0];dan Anda bahkan sudah menggunakan sintaks ( $r[]=$n). Anda sudah menggunakan maxsekarang jadi Anda juga harus mengganti end($r)dengan $nkarena $nselalu sama dengan end($r)ketika gema dieksekusi.
Christoph
@Christoph Sepertinya kemarin bukan hari saya. Terima kasih. Anda telah membawa saya ke ide saya untuk entri baru di bagian tips
Jörg Hülsermann
2

R (3.3.1), 87 byte

Mengembalikan nol untuk permainan yang berakhir dengan semua nol, dan angka positif sebaliknya.

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

memanfaatkan fakta yang sama oleh Greg Martin dan menggunakan diff builtin untuk melakukan diff-ing

Giuseppe
sumber
asalkan terikat xnor benar (dari komentar), ini bisa menjadi dua byte lebih pendek dengan menggunakan max (z) * panjang (z) tapi saya tidak yakin dengan kebenarannya
Giuseppe
1

Röda , 80 byte

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

Cobalah online!

Tidak Disatukan:

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
}
fergusq
sumber
1

05AB1E , 13 byte

Mengembalikan 1 jika berakhir dengan nol dan 0 sebaliknya.

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

Cobalah online!

Penjelasan

Gunakan batas atas putaran: max(input)*len(input)dijelaskan oleh xnor di bagian komentar.

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
Emigna
sumber
1

J, 22 byte

Mengembalikan 0(yang secara efektif falsedalam J) untuk permainan degenerasi berakhir di semua nol. Mengembalikan 1( true) jika iterasi ke-n berisi angka bukan-nol, di mana n sama dengan bilangan bulat terbesar dalam urutan asli dikalikan dengan panjang daftar. Lihat jawaban Greg Martin yang menjelaskan mengapa ini benar.

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

Terjemahan:

  • Apa tandanya *
  • dari nilai terbesar >./
  • ketika Anda mengulangi berikut ini sebanyak ^:( )
  • panjang daftar #dikalikan dengan *nilai terbesar dalam daftar >./:
    • ambil nilai absolut |&dari
    • perbedaan antara daftar (- )dan
    • daftar diputar oleh satu 1&|.

Contoh:

   *>./|&(-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
Dane
sumber
1
Bukan itu yang dikatakan Greg Martin. Namun, xnor memiliki batas yang lebih baik dalam komentar di atas (tetapi masih bukan hanya bilangan bulat terbesar). Yang paling sederhana adalah mengalikan nilai terbesar dengan panjangnya.
Ørjan Johansen
Tangkapan yang bagus. Saya tidak cukup memperhatikan. Saya akan memperbaiki solusinya.
Dane
1

JavaScript (ES6), 95 92 90 byte

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)

Penjelasan

Fungsi rekursif yang menyebut dirinya sendiri selama penghitung (yang dimulai pada nilai maksimum dalam daftar ditambah satu dengan kekuatan panjang daftar [ = (max + 1)**length]) bukan nol. Pada setiap panggilan, penghitung dikurangi, dan ketika mencapai nol, semua elemen dalam daftar diperiksa terhadap nol. Jika semuanya sama dengan nol, program kembali true, dan falsesebaliknya.

Luke
sumber
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);

mengambil input melalui HTTP get mis ?3&4&5&8menyimpan beberapa byte.

Mencetak 1 jika mencapai semua nol atau tidak sama sekali.


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

mengambil daftar argumen melalui baris perintah. Saya merasa ini bisa bermain golf lebih jauh (melihat @Titus).

Christoph
sumber
1

Python 3.6, 101 byte

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)

Mengambil tuple angka dan mengembalikan False jika berakhir dengan nol dan Benar jika itu loop.

RootTwo
sumber
0

JavaScript (ES6), 84 83 byte

Kembali trueuntuk permainan yang berakhir dengan semua nol, falsejika tidak.

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)

Uji

Arnauld
sumber