เกม 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 ให้พิจารณาว่าในที่สุดเกมจะถึงสถานะของศูนย์ทั้งหมดหรือไม่ คุณควรส่งออกค่า 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 (falsy) หมายถึงศูนย์ทั้งหมดสิ่งอื่นใด (ความจริง) หมายถึงศูนย์ทั้งหมด

มันทำงานอย่างไร:

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
นั่นเป็นวิธีที่อ่อนโยน
Martijn Vissers

14

Mathematica, 52 ไบต์

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

ฟังก์ชั่นการถ่ายเพียวรายการของจำนวนเต็มไม่ติดลบเป็น input และกลับหรือTrueFalse

Abs[#-RotateLeft@#]&เป็นฟังก์ชั่นที่รันรอบหนึ่งของเกม diffy (ในทางเทคนิคแล้วควรเป็นRotateRightแต่คำตอบสุดท้ายนั้นไม่ได้รับผลกระทบใด ๆ และไบต์ฟรี) ดังนั้นNest[...,#,R]จะดำเนินการRรอบของเกม diffy แล้ว1>Max@ตรวจพบว่าผลลัพธ์นั้นเป็นศูนย์ทั้งหมดหรือไม่

เราจะรู้ได้อย่างไรว่ามีเกมต่างออกRไปกี่รอบ หากmเป็นค่าที่ใหญ่ที่สุดในอินพุตให้สังเกตว่าเราจะไม่ผลิตจำนวนเต็มมากกว่าmไม่ว่าเราจะปัดเศษเป็นจำนวนเท่าใด จำนวนรวมของรายการของความยาวlของจำนวนเต็มไม่เป็นลบทั้งหมดที่สิ้นสุดโดยมีm (m+1)^lดังนั้นถ้าเรา(m+1)^lเล่นเกม diffy เป็นรอบเรารับประกันว่าจะเห็นบางรายการสองครั้งในตอนนั้นและจะอยู่ในส่วนของเกมเป็นระยะ โดยเฉพาะอย่างยิ่งเกมจะจบลงด้วยเลขศูนย์ทั้งหมดถ้าหากผลลัพธ์ของ(m+1)^lรอบของเกมเป็นรายการศูนย์ทั้งหมด การแสดงออกนั้นเป็นสิ่งที่Max[1+#]^Tr[1^#]คำนวณ


6

เยลลี่ขนาด 13 ไบต์

Ṁ‘*L
ṙ1ạ
ÇÑ¡Ṁ

เอาท์พุท 0 (เท็จ) ถ้าถึงศูนย์ทั้งหมดรัฐมิฉะนั้นจะส่งกลับค่าความจริง (จำนวนเต็มบวก)

ลองออนไลน์!

ใช้การสังเกตครั้งแรกโดย Greg Martinว่าตัวเลขภายในอาร์เรย์อาจไม่เคยออกจากโดเมน[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หรือไม่?
ข้าวสาลีตัวช่วยสร้าง

@Weateat ตัวช่วยสร้างฉันคิดว่ามันต้องเสียค่าไบต์ (อาจเป็นไปได้ที่จะได้รับวิธีที่สั้นกว่าโดยรวบรวมผลลัพธ์ทั้งหมดจนกว่าพวกเขาจะไม่ซ้ำกัน แต่ฉันไม่ได้พบมัน)
Jonathan Allan

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? แต่ทำไม
Christoph

1
ถ้าใช้$_GETเป็นอินพุตคุณควรถือว่ามันมีสตริงอยู่
Christoph

1
@Christoph ?0[0]=1&0[1]=1&0[2]=0หรือ?0[]=1&0[]=1&0[]=0เป็นอาร์เรย์ของสตริง แต่สิ่งนี้ไม่สำคัญ แต่คุณพูดถูกฉันสามารถทำให้มันสั้นลง?0=1&1=1&2=0ได้ด้วยว่าทำไมไม่àrray_push`ฉันแน่ใจว่าคุณหรือติตัสหาทางที่ดีกว่านี้
JörgHülsermann

1
array_push($e,$e[$c=0]);เป็นเพียงเหมือนกับ$e[]=$e[$c=0];และคุณยังใช้ไวยากรณ์แล้ว ( $r[]=$n) คุณใช้maxแล้วดังนั้นคุณควรแทนที่end($r)ด้วย$nเพราะ$nจะเท่ากับเสมอend($r)เมื่อดำเนินการ echo
Christoph

@Christoph ดูเหมือนว่าเมื่อวานนี้ไม่ใช่วันของฉัน ขอขอบคุณ. คุณได้นำฉันมาสู่ความคิดของฉันสำหรับรายการใหม่ในส่วนเคล็ดลับ
JörgHülsermann

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 และใช้ builtin diff ทำ diffy-ing


โดยมีเงื่อนไขว่าขอบเขตของ xnor นั้นถูกต้อง (จากความคิดเห็น) นี่อาจเป็นสองไบต์ที่สั้นลงโดยใช้ max (z) * length (z) แต่ฉันไม่มั่นใจในความถูกต้อง
Giuseppe

1

Röda , 80 ไบต์

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

ลองออนไลน์!

Ungolfed:

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

ลองออนไลน์!

คำอธิบาย

ใช้ขอบเขตบนของรอบ: max(input)*len(input)อธิบายโดยxnorในส่วนความคิดเห็น

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(ซึ่งมีผลเป็นfalseJ) สำหรับเกมที่เลวลงซึ่งลงท้ายด้วยศูนย์ทั้งหมด ส่งคืน1( true) ถ้าการวนซ้ำ nth มีตัวเลขที่ไม่ใช่ศูนย์โดยที่ n เท่ากับจำนวนเต็มที่มากที่สุดในลำดับเดิมคูณด้วยความยาวของรายการ ดูคำตอบของ Greg Martinอธิบายว่าทำไมสิ่งนี้ถึงเป็นจริง

*>./|&(-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 Johansen

จับดี. ฉันไม่ได้ให้ความสนใจเพียงพอ ฉันจะแก้ไขปัญหา
ชาวเดนมาร์ก

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)

คำอธิบาย

ฟังก์ชันเรียกซ้ำที่เรียกตัวเองตราบเท่าที่ตัวนับ (ซึ่งเริ่มต้นที่ค่าสูงสุดในรายการบวกหนึ่งกับกำลังของความยาวของรายการ [ = (max + 1)**length]) ไม่ใช่ศูนย์ ในทุกการโทรตัวนับจะลดลงและเมื่อถึงศูนย์องค์ประกอบทั้งหมดในรายการจะถูกตรวจสอบกับศูนย์ ถ้ามันเท่ากับศูนย์ทั้งหมดโปรแกรมจะส่งคืนtrueและfalseมิฉะนั้น


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)

รับ tuple ของตัวเลขและส่งคืนค่า 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.