Là trò chơi Diffy của tôi thoái hóa?


23

Gần đây tôi đã đăng một câu hỏi về các trò chơi Diffy chưa được trả lời. Đó là tốt, câu hỏi thực sự khó, nhưng tôi muốn đưa ra một câu hỏi dễ dàng hơn về các trò chơi Diffy để chúng tôi có thể có được quả bóng lăn.


Làm thế nào Diffy hoạt động

Sao chép từ trò chơi Tìm Diffy

Trò chơi Diffy hoạt động như sau: Bạn bắt đầu với một danh sách các số nguyên không âm, trong ví dụ này chúng tôi sẽ sử dụng

3 4 5 8

Sau đó, bạn lấy sự khác biệt tuyệt đối giữa các số liền kề

 (8)  3   4   5   8
    5   1   1   3

Sau đó, bạn lặp lại. Bạn lặp lại cho đến khi bạn nhận ra bạn đã bước vào một vòng lặp. Và sau đó nói chung trò chơi bắt đầu lại từ đầu.

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

Hầu hết các trò chơi kết thúc trong một chuỗi tất cả các số không, được coi là trạng thái thua, nhưng một số ít trò chơi bị mắc kẹt trong các vòng lớn hơn.


Bài tập

Đưa ra trạng thái bắt đầu của trò chơi Diffy, xác định xem trò chơi cuối cùng có đạt đến trạng thái của tất cả các số không hay không. Bạn nên xuất giá trị Truthy hoặc Falsy cho mỗi trong hai trạng thái. Cái nào tương ứng với cái nào không quan trọng.

Mục tiêu là để giảm thiểu số lượng byte trong nguồn của bạn.


1
Do đó, từ ngữ nhiệm vụ dường như ngụ ý rằng bất kỳ trò chơi nào không đạt đến trạng thái của tất cả các số 0 là do đó định kỳ. Trước đó, định kỳ được định nghĩa là bao gồm trạng thái ban đầu trong chuỗi lặp lại. Điều này có nghĩa là bất kỳ chuỗi nào cuối cùng cũng đạt đến tất cả các số 0 hoặc trạng thái ban đầu?
trichoplax

3
Không: việc thêm hằng số dương vào bất kỳ trạng thái định kỳ khác nào sẽ dẫn đến trạng thái không trở về chính nó cũng như không chuyển sang tất cả các số không. Ví dụ, 1 1 0là định kỳ, như vậy 42 42 41là một trạng thái.
Greg Martin

3
Thật vậy, đối với câu hỏi cụ thể đang được hỏi, người ta thậm chí không cần một khái niệm "định kỳ". "Cuối cùng đạt đến trạng thái của tất cả các số không" là khép kín và rõ ràng.
Greg Martin

2
Tôi đã chứng minh một đặc tính một phần: Nếu độ dài danh sách nlà số lẻ, trò chơi sẽ không về không trừ khi tất cả các số đều bằng nhau. Nếu độ dài là lũy thừa bằng 2, nó luôn luôn về không.
xnor

3
Giới hạn số bước để đạt đến 0: Một danh sách có ncác phần tử và tối đa mmất tối đa các n * bit_length(m)bước. Vì vậy, n*mcũng là một giới hạn trên. Giới hạn trên mạnh hơn là t(n) * bit_length(m), nơi t(n)có sức mạnh lớn nhất trong 2 đó là một yếu tố n.
xnor

Câu trả lời:


27

Bình thường, 6 byte

suaV+e

Bộ kiểm tra

Chương trình này rất linh hoạt. 0 (falsy) có nghĩa là tất cả các số 0, bất cứ điều gì khác (sự thật) có nghĩa là không phải tất cả các số không.

Làm thế nào nó hoạt động:

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 một ngọt ngào giải pháp
Martijn Vissers

14

Toán học, 52 byte

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

Hàm thuần túy lấy danh sách các số nguyên không âm làm đầu vào và trả về Truehoặc False.

Abs[#-RotateLeft@#]&là một chức năng thực thi một vòng của trò chơi diffy. (Về mặt kỹ thuật là như vậy RotateRight, nhưng câu trả lời cuối cùng không bị ảnh hưởng, và hey, byte miễn phí.) Vì vậy, Nest[...,#,R]thực hiện các Rvòng của trò chơi diffy, và sau đó 1>Max@phát hiện xem kết quả có phải là số không.

Làm thế nào để chúng ta biết có bao nhiêu vòng trò chơi khác nhau Rđể làm gì? Nếu mlà giá trị lớn nhất trong đầu vào, lưu ý rằng chúng ta sẽ không bao giờ tạo ra một số nguyên lớn hơn mbất kể chúng ta làm bao nhiêu vòng. Tổng số danh sách độ dài lcủa các số nguyên không âm tất cả giới hạn bởi m(m+1)^l. Vì vậy, nếu chúng tôi thực hiện các (m+1)^lvòng của trò chơi diffy, chúng tôi được đảm bảo đã thấy một số danh sách hai lần sau đó, và do đó sẽ nằm trong phần định kỳ của trò chơi. Cụ thể, trò chơi kết thúc ở tất cả các số không khi và chỉ khi kết quả của các (m+1)^lvòng của trò chơi là danh sách tất cả các số không. Biểu hiện đó là những gì Max[1+#]^Tr[1^#]tính toán.


6

Thạch , 13 byte

Ṁ‘*L
ṙ1ạ
ÇÑ¡Ṁ

Kết quả 0 (falsey) nếu đạt được tất cả trạng thái 0, nếu không sẽ trả về giá trị trung thực (số nguyên dương).

Hãy thử trực tuyến!

Sử dụng quan sát đầu tiên được thực hiện bởi Greg Martin rằng các số trong mảng có thể không bao giờ rời khỏi miền [0, m] trong đó m là phần tử tối đa trong đầu vào, do đó, thực hiện (m + 1) l trong đó l là độ dài của đầu vào sẽ đủ.

Làm sao?

Ṁ‘*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

Điều này có thể được cải thiện với ràng buộc của xnor ?
Thuật sĩ lúa mì

@WheatWizard Tôi nghĩ rằng nó sẽ tốn một byte. (Có thể có được một phương pháp ngắn hơn bằng cách thu thập tất cả các kết quả cho đến khi chúng không phải là duy nhất, nhưng tôi không tìm thấy nó).
Jonathan Allan

2

PHP, 144 byte

in 0 cho tất cả 0 và bất kỳ giá trị nguyên dương nào cho đúng

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

Phiên bản trực tuyến

Mở rộng

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? Nhưng tại sao ?
Christoph

1
ngoài ra nếu sử dụng $_GETlàm đầu vào, bạn nên giả sử nó chứa một chuỗi.
Christoph

1
@Christoph ?0[0]=1&0[1]=1&0[2]=0hoặc ?0[]=1&0[]=1&0[]=0là một chuỗi các chuỗi nhưng điều này không quan trọng. Nhưng bạn đã đúng Tôi có thể làm cho nó ngắn hơn với ?0=1&1=1&2=0lý do tại sao không àrray_push` Tôi chắc chắn rằng bạn hoặc Titus tìm ra những cách tốt hơn để rút ngắn điều này.
Jörg Hülsermann

1
array_push($e,$e[$c=0]);chỉ đơn giản là chính xác giống như $e[]=$e[$c=0];và bạn thậm chí sử dụng cú pháp đã ( $r[]=$n). Bạn đã sử dụng maxngay bây giờ để bạn cũng nên thay thế end($r)với $n$nluôn bằng end($r)khi tiếng vang được thực thi.
Christoph

@Christoph Có vẻ như hôm qua không phải là ngày của tôi. Cảm ơn bạn. Bạn đã đưa tôi đến ý tưởng của tôi cho một mục mới trong phần mẹo
Jörg Hülsermann

2

R (3.3.1), 87 byte

Trả về 0 cho một trò chơi kết thúc bằng tất cả các số không và một số dương khác.

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

thúc đẩy sự thật tương tự của Greg Martin và sử dụng diffin để thực hiện diffy-ing


với điều kiện ràng buộc của xnor là chính xác (từ các bình luận), điều này có thể ngắn hơn hai byte bằng cách sử dụng độ dài tối đa (z) * (z) nhưng tôi không bị thuyết phục về tính chính xác
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}}

Hãy thử trực tuyến!

Ung dung:

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 byte

Trả về 1 nếu kết thúc bằng 0 và 0 khác.

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

Hãy thử trực tuyến!

Giải trình

Sử dụng giới hạn trên của các vòng: được max(input)*len(input)giải thích bởi xnor trong phần bình luận.

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 byte

Trả về 0(có hiệu quả falsetrong J) cho một trò chơi suy biến kết thúc ở tất cả các số không. Trả về 1( true) nếu lần lặp thứ n chứa số khác không, trong đó n bằng số nguyên lớn nhất trong chuỗi ban đầu nhân với độ dài của danh sách. Xem câu trả lời của Greg Martin giải thích tại sao điều này là đúng.

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

Dịch:

  • Dấu hiệu là gì *
  • của giá trị lớn nhất >./
  • khi bạn lặp lại như sau nhiều lần ^:( )
  • độ dài của danh sách #nhân với *giá trị lớn nhất trong danh sách >./:
    • lấy giá trị tuyệt đối |&của
    • sự khác biệt giữa danh sách (- )
    • danh sách được xoay bởi một 1&|.

Ví dụ:

   *>./|&(-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
Đó không phải là những gì yêu cầu của Greg Martin. Tuy nhiên, xnor có giới hạn tốt hơn trong các nhận xét ở trên (nhưng vẫn không chỉ là số nguyên lớn nhất). Đơn giản nhất là nhân giá trị lớn nhất với chiều dài.
Ørjan Johansen

Nắm bắt tốt. Tôi đã không chú ý đầy đủ. Tôi sẽ sửa giải pháp.
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)

Giải trình

Hàm đệ quy tự gọi nó miễn là bộ đếm (bắt đầu ở giá trị tối đa trong danh sách cộng với một với sức mạnh của độ dài của danh sách [ = (max + 1)**length]) không bằng không. Trên mỗi cuộc gọi, bộ đếm được giảm dần và khi nó về 0, tất cả các thành phần trong danh sách được kiểm tra bằng không. Nếu tất cả đều bằng 0, chương trình trả về true, và falsenếu không.


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

lấy đầu vào qua HTTP get, ví dụ ?3&4&5&8tiết kiệm một vài byte.

In 1 nếu nó đạt đến tất cả các số không hoặc không có gì khác.


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

lấy danh sách các đối số thông qua dòng lệnh. Tôi có cảm giác điều này có thể được chơi gôn hơn nữa (nhìn vào @Titus).


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)

Lấy một bộ số và trả về Sai nếu nó kết thúc bằng số không và True nếu nó lặp.


0

JavaScript (ES6), 84 83 byte

Trả về truecho một trò chơi kết thúc trong tất cả các số không, falsenếu không.

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)

Kiểm tra

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.