내 Diffy 게임이 퇴화됩니까?


23

최근에 나는 답이없는 Diffy games에 관한 질문을 게시 했습니다 . 괜찮습니다. 질문은 정말 어렵지만 Diffy 게임에 대해 더 쉬운 질문을해서 볼을 굴릴 수있게하고 싶습니다.


Diffy의 작동 방식

Diffy 게임 찾기 에서 복사

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

대부분의 게임은 잃어버린 상태로 간주되는 모든 0의 문자열로 끝나지 만 드문 게임은 더 큰 루프에 빠집니다.


태스크

Diffy 게임의 시작 상태가 주어지면 게임이 결국 0의 상태에 도달하는지 여부를 결정하십시오. 두 상태 각각에 대해 Truthy 또는 Falsy 값을 출력해야합니다. 어느 것이 중요하지 않습니다.

목표는 소스의 바이트 수를 최소화하는 것입니다.


1
작업 문구는 모든 0의 상태에 도달하지 않은 게임이 주기적이라는 것을 암시하는 것 같습니다. 이전에는 주기적으로 반복되는 초기 상태를 포함하는 것으로 정의됩니다. 이것은 어떤 시퀀스가 ​​결국 모두 0 또는 초기 상태에 도달한다는 것을 의미합니까?
trichoplax

3
아니오 : 0이 아닌주기 상태에 양의 상수를 추가하면 상태가 자체로 돌아 가지 않고 모든 0으로 돌아 가지 않습니다. 예를 들어, 1 1 0주기적이므로 42 42 41그러한 상태도 있습니다.
Greg Martin

3
실제로, 특정 질문에 대해서는 "주기적인"이라는 개념조차 필요하지 않습니다. "결국 모든 0의 상태에 도달합니다"는 독립적이며 명확합니다.
Greg Martin

2
부분 특성화를 증명했습니다. 목록 길이 n가 홀수이면 모든 숫자가 같지 않으면 게임이 0이되지 않습니다. 길이가 2의 거듭 제곱이면 항상 0이됩니다.
xnor

3
0에 도달하는 단계 수의 한계 : n요소가 있는 목록 과 최대 값 m은 최대 n * bit_length(m)단계입니다. 따라서 n*m상한이기도합니다. 더 강한 상한은이며 t(n) * bit_length(m), 여기서 t(n)2의 최대 거듭 제곱은의 인수입니다 n.
xnor

답변:


27

Pyth, 6 바이트

suaV+e

테스트 스위트

이 프로그램은 매우 무섭습니다. 0 (거짓)은 모두 0을 의미하고 다른 것 (거짓)은 모두 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
그건 suave 솔루션
Martijn Vissers

14

매스 매 티카, 52 바이트

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

입력 및 반환 등의 음이 아닌 정수의 목록 복용 순수 기능 True또는 False.

Abs[#-RotateLeft@#]&diffy 게임의 한 라운드를 실행하는 기능입니다. (기술적으로이어야 RotateRight하지만 궁극적 인 대답은 영향을받지 않으며, 여유 바이트입니다.) 따라서 diffy 게임 라운드를 Nest[...,#,R]실행 R한 다음 1>Max@결과가 모두 0인지 여부 를 감지합니다.

얼마나 많은 diffy-game 라운드 R를 해야하는지 어떻게 알 수 있습니까? m입력에서 가장 큰 값 이면 m라운드 수에 관계없이 더 큰 정수를 생성 하지 않습니다. l음이 아닌 정수 길이 의 총 목록 수는 모두로 묶 m입니다 (m+1)^l. 그래서 (m+1)^l우리가 diffy 게임 라운드를 수행한다면 , 우리는 그때까지 두 번 목록을 보았으므로 게임의 주기적 부분에있을 것입니다. 특히 게임 (m+1)^l라운드 결과가 모두 0 인 경우에만 게임은 모두 0으로 끝납니다 . 그 표현은 Max[1+#]^Tr[1^#]계산하는 것입니다.


6

젤리 , 13 바이트

Ṁ‘*L
ṙ1ạ
ÇÑ¡Ṁ

모두 0 상태에 도달하면 0 (거짓)을 출력하고 그렇지 않으면 정확한 값 (양의 정수)을 반환합니다.

온라인으로 사용해보십시오!

배열 내 숫자가 도메인 [0, m]을 떠나지 않을 수 있다는 Greg Martin의 첫 번째 관찰을 사용합니다 . 여기서 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 바이트 비용이들 것 같습니다. (모든 결과가 고유하지 않을 때까지 모든 결과를 수집하여 더 짧은 방법을 얻을 수는 있지만 찾지 못했습니다).
Jonathan Allan

2

PHP, 144 바이트

모든 0에 대해 0을 인쇄하고 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);

온라인 버전

넓히는

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örg Hülsermann

1
array_push($e,$e[$c=0]);는 정확히 정확히 동일하며 $e[]=$e[$c=0];이미 구문 ( $r[]=$n)을 사용합니다 . 이미 사용 중이므로 에코가 실행될 때 와 항상 같으 므로 로 max바꿔야 합니다. end($r)$n$nend($r)
Christoph

@Christoph 어제는 내 하루가 아닌 것 같습니다. 고맙습니다. 당신은 팁 섹션에 새로운 항목에 대한 내 아이디어를 가져왔다
Jörg Hülsermann

2

R (3.3.1), 87 바이트

0으로 끝나는 게임의 경우 0을, 그렇지 않으면 양수를 반환합니다.

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 바이트가 짧을 수 있지만 정확성을 확신하지 못합니다.
Giuseppe

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과 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으로 끝나는 퇴행성 게임에 대한 리턴 값 0( falseJ에 효과적으로 있음). n 번째 반복에 0이 아닌 숫자가 포함 된 경우 1( true)를 반환합니다 . 여기서 n은 원래 시퀀스에서 가장 큰 정수와 목록의 길이를 곱한 값과 같습니다. 이것이 사실 인 이유를 설명하는 Greg Martin의 답변을 참조하십시오 .

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

잘 잡았습니다. 나는 충분히주의를 기울이지 않았다. 나는 해결책을 고칠 것이다.
Dane

1

자바 스크립트 (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] 의 1의 배수로 시작 함 )가 0이 아닌 한 자체 호출하는 재귀 함수입니다 . 모든 호출에서 카운터가 감소하고 0에 도달하면 목록의 모든 요소가 0과 비교하여 검사됩니다. 모두 0과 같으면 프로그램에서을 반환 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 get을 통해 입력을 받으면 ?3&4&5&8몇 바이트를 절약 할 수 있습니다.

모두 0에 도달하거나 그렇지 않으면 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

파이썬 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)

숫자의 튜플을 가져 와서 0으로 끝나는 경우 False를 반환하고 반복되면 True를 반환합니다.


0

자바 스크립트 (ES6), 84 83 바이트

그렇지 않으면 true0으로 끝나는 게임을 반환 합니다 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.