콜라 코스키 감소


27

개요

일부 사용자는 Kolakoski 시퀀스 ( A000002 )를 알고있을 것입니다. 이는 다음과 같은 특성을 갖는 자체 참조 시퀀스입니다.

coolio Kolakoski 속성입니다.

1과 2 만 포함하는 시퀀스이며 1과 2의 각 그룹에 대해 런의 길이를 합하면 길이의 절반 밖에되지 않습니다. 즉, Kolakoski 시퀀스는 시퀀스 자체의 실행 길이를 나타냅니다. 초기 1이 삭제 된 동일한 시퀀스를 제외하고이 작업을 수행하는 유일한 시퀀스입니다. (1과 2로 구성된 시퀀스-Martin Ender로 제한하는 경우에만 해당)


도전

문제는 정수 목록이 주어진다는 것입니다.

  • -1목록이 Kolakoski 시퀀스의 작동 접두사가 아닌 경우 출력 됩니다.
  • 시퀀스가되기 전에 반복 횟수를 출력합니다 [2].

해결 된 예

제공된 이미지를 예로 사용 :

[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1] # Iteration 0 (the input).
[1,2,2,1,1,2,1,2,2,1,2]             # Iteration 1.
[1,2,2,1,1,2,1,1]                   # Iteration 2.
[1,2,2,1,2]                         # Iteration 3.
[1,2,1,1]                           # Iteration 4.
[1,1,2]                             # Iteration 5.
[2,1]                               # Iteration 6.
[1,1]                               # Iteration 7.
[2]                                 # Iteration 8.

따라서 결과 숫자는 8의 입력을위한 것입니다 [1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1].

9 1 인덱싱하는 경우에도 좋습니다.


테스트 스위트 (하위 반복으로 테스트 할 수도 있음)

------------------------------------------+---------
Truthy Scenarios                          | Output
------------------------------------------+---------
[1,1]                                     | 1 or 2
[1,2,2,1,1,2,1,2,2,1]                     | 6 or 7
[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1]       | 8 or 9
[1,2]                                     | 2 or 3
------------------------------------------+---------
Falsy Scenarios                           | Output
------------------------------------------+---------
[4,2,-2,1,0,3928,102904]                  | -1 or a unique falsy output.
[1,1,1]                                   | -1
[2,2,1,1,2,1,2] (Results in [2,3] @ i3)   | -1 (Trickiest example)
[]                                        | -1
[1]                                       | -1

혼란 스러우면 :

Truthy :1 and 이외의 다른 요소가없는 중간 단계없이 2에 도달 2합니다. –Einkorn Enchanter 20 hours ago

Falsy : 종료 값이 아닙니다 [2]. 중간 용어에는 집합 이외의 것이 포함됩니다 [1,2]. 다른 몇 가지 예를 참조하십시오.


이것은 이며 가장 낮은 바이트 수가 승리합니다.


7
그냥 잘못된 값을 사용할 수 있습니까 -1?
mbomb007

1
"Kolakoski 시퀀스의 작동 접두사가 아님"은 무슨 뜻입니까? 나는 당신 [2][2,2,1,1,2,1,2]테스트 케이스를 볼 때까지 목록이 결국 도달하지 않는다는 것을 의미한다고 가정했습니다 .
ngenisis 2016 년

1
@ngenisis 결국에는 1and 이외의 다른 요소가없는 중간 단계없이 2에 도달 2합니다.
위트 마법사

2
[1]테스트 사례 로 추가하는 것이 좋습니다 .
Emigna 2016 년

1
@ mbomb007 어떤 뚜렷한 가치가 있습니다. 양의 정수는 좋지 않습니다. 1 인덱싱 인 경우 0이 좋습니다. "거짓"은 괜찮습니다. 오류는 괜찮습니다. 양수가 아닌 반환 값은 -129.42910입니다.
Magic Octopus Urn

답변:


8

하스켈 , 126 87 79 76 75 바이트

Ørjan Johansen 덕분에 39 바이트 절약

import Data.List
f[2]=0
f y@(_:_:_)|all(`elem`[1,2])y=1+f(length<$>group y)

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

입력이 잘못되면 오류가 발생합니다.


f(따라서 !) 축 압기 대신에 게으른 생산 + span/ 을 사용하면 많은 시간을 단축 할 수 있습니다 length. 온라인으로 사용해보십시오!
Ørjan Johansen 2016

1
무한 루프에 들어가는 것[1]
Emigna

1
@Emigna Darn. 문제를 해결하는 데 6 바이트가 소요되었지만 수정했습니다.
Wheat Wizard

@ ØrjanJohansen 그것은 좋은 팁처럼 보이지만, 나는 Haskell에서 무슨 일이 일어나고 있는지 이해하기에 충분하지 않습니다. 솔루션을 어떻게 작동하는지 모르는 한 자신의 답변으로 게시 할 수 있기를 원한다면 내 답변에 추가하지 않을 것입니다. :)
밀 마법사

1
그런 다음 가져 오기가 실제로 더 짧고 이해하기 더 쉬운 경우임을 깨달았습니다 import Data.List;f l=length<$>group l. ( 여기서는 <$>동의어입니다 map.) 또한 두 개의 서로 다른 -1경우를 사용하는 대신 @(_:_:_)패턴을 사용 하여 기본 경우가 길이> = 2 목록에만 일치 하도록하는 것이 더 짧습니다 . 온라인으로 사용해보십시오!
Ørjan Johansen 2016 년

6

05AB1E , 22 바이트

[Dg2‹#γ€gM2›iX]2QJiNë®

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

설명

[                        # start a loop
 D                       # duplicate current list
  g2‹#                   # break if the length is less than 2
      γ                  # group into runs of consecutive equal elements
       €g                # get length of each run
         M2›iX           # if the maximum run-length is greater than 2, push 1
              ]          # end loop
               2QJi      # if the result is a list containing only 2
                   N     # push the iteration counter from the loop
                    ë®   # else, push -1
                         # implicitly output top of stack

실패[1,1,2,2,1,2,1,1,2,2,1,2,2,1,1,2,1,1]
Weijun Zhou

@WeijunZhou : 고마워요!
Emigna

링크 업데이트를 잊었을 수도 있습니다 ...
Weijun Zhou

1
@WeijunZhou : 실제로 나는 있었다. 다시 감사합니다 :)
Emigna

3

SCALA, 290 (282?) 자, 290 (282?) 바이트

나에게 sooo loong이 걸렸다. 그러나 나는 마침내 끝났다!

이 코드로 :

var u=t
var v=Array[Int]()
var c= -1
var b=1
if(!u.isEmpty){while(u.forall(x=>x==1|x==2)){c+=1
if(u.size>1){var p=u.size-1
for(i<-0 to p){if(b==1){var k=u(i)
v:+=(if(i==p)1 else if(u(i+1)==k){b=0
if(p-i>1&&u(i+2)==k)return-1
2}else 1)} else b=1}
u=v
v=v.take(0)}else if(u(0)==2)return c}}
c

내가 계산해야하는지 모르겠어요 var u=t바이트에 내가 사용하지 않는 고려 t(복사 그냥 modifyable 얻을 수 있습니다 알고리즘 동안 var대신 매개 변수 t로 간주 val- 감사 스칼라 ). 계산해야하는지 알려주십시오.

충분히 어렵다. 온라인으로 사용해보십시오!

추신 : 나는 그것을 재귀 적으로 생각하고 있었지만, 진정한 재귀 "하위 함수"의 매개 변수로 카운터를 전달해야합니다. 이 사실은 두 가지 함수를 선언하게 하며이 문자 / 바이트는 잃어버린 것입니다.

편집 : 우리는 수를 세어야할지 확실하지 않기 때문에 변경해야합니까 (?) [1]. 그래서 여기 수정 된 코드는 다음과 같습니다

var u=t
var v=Array[Int]()
var c= -1
var b=1
if(!u.isEmpty){try{t(1)}catch{case _=>return if(t(0)==2)0 else -1}
while(u.forall(x=>x==1|x==2)){c+=1
if(u.size>1){var p=u.size-1
for(i<-0 to p){if(b==1){var k=u(i)
v:+=(if(i==p)1 else if(u(i+1)==k){b=0
if(p-i>1&&u(i+2)==k)return-1
2}else 1)} else b=1}
u=v
v=v.take(0)}else if(u(0)==2)return c}}
c

최적화되지 않았습니다 (동일한 조건에 대해 중복 "출력"이 있습니다 : [2]매개 변수가 [2]분리되어 처리 될 때 ).

새 비용 = 342 (고의로 제목을 수정하지 않았습니다)


1
무한 루프에 들어가는 것[1]
Emigna

그러나 OP에 따르면 (최소한 이해 한 바와 같이) : "처음 1이 삭제 된 상태"및 "시퀀스가되기 전에 반복 횟수 출력 [2]"
V. Courtois

내 이해에 [1]결코 도달하지 못 [2]하므로 -1 반환해야합니다 .
Emigna 2016 년

내가 참조. 내가 처음에 가벼운 조건을 넣어야한다고 생각합니까? 조언 해 주셔서 감사합니다.
V. Courtois 2016 년

스칼라를 모르지만 목록의 길이가 2보다 작을 때 루프를 중지하여 중지 할 수 있다고 가정합니다. 이미 요소의 끝이 2인지 확인한 것으로 보입니다.
Emigna 2016 년

2

자바 스크립트, 146142 바이트

코드 골프에서 먼저 시도하면 더 큰 기능의 "반환"이 매우 지루한 것 같습니다 ...

또한 b = 1 및 b = 2 확인은 몇 바이트를 차지합니다 ...

코드는 다음과 같습니다.

f=y=>{i=t=!y[0];while(y[1]){r=[];c=j=0;y.map(b=>{t|=b-1&&b-2;if(b-c){if(j>0)r.push(j);c=b;j=0}j++});(y=r).push(j);i++}return t||y[0]-2?-1:0^i}

설명

f=y=>{/*1*/}                                        //function definition

//Inside /*1*/:
  i=t=!y[0];                                        //initialization
                                                    //if the first one is 0 or undefined, 
                                                    //set t=1 so that it will return -1   
                                                    //eventually, otherwise i=0
  while(y[1]){/*2*/}                                //if there are 2+ items, start the loop

  //Inside /*2*/:
    r=[];c=j=0;                                     //initialization
    y.map(b=>{/*3*/});                              //another function definition

    //Inside /*3*/:
      t|=b-1&&b-2;                                  //if b==1 or b==2, set t=1 so that the
                                                    //entire function returns -1
      if(b-c){if(j>0)r.push(j);c=b;j=0}             //if b!=c, and j!=0, then push the 
                                                    //count to the array and reset counter
      j++                                           //counting duplicate numbers

    (y=r).push(j);i++                               //push the remaining count to the array
                                                    //and proceed to another stage

  return t||y[0]-2?-1:0^i                           //if the remaining element is not 2, or
                                                    //t==1 (means falsy), return -1,
                                                    //otherwise return the counter i

테스트 데이터 (주어진 테스트 데이터 사용)

l=[[1,1],[1,2,2,1,1,2,1,2,2,1],[1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1],[1,2],[4,2,-2,1,0,3928,102904],[1,1,1],[2,2,1,1,2,1,2],[]];
console.log(l.map(f));
//Output: (8) [1, 6, 8, 2, -1, -1, -1, -1]

편집 1 : 146-> 142 : 바이트 감소에 대한 편집을 취소하면 출력에 영향을 미칩니다. 마지막 문장에 대한 편집


f=a=>{for(i=t=!a[0];a[1];)r=[],c=j=0,a.map(a=>{t|=a-1&&a-2;a-c&&(0<j&&r.push(j),c=a,j=0);j++}),(a=r).push(j),i++;return t||a[0]-2?-1:0^i}5 바이트를 저장합니다 (while 대신 for 루프; 쉼표 대 중괄호; && vs if). Google의 클로저 컴파일러 ( closure-compiler.appspot.com )를 사용하여 이러한 최적화를 수행 할 수 있습니다.
Oki

2

젤리 ,26 25 22 21 20 바이트

FQœ-2R¤
ŒgL€µÐĿṖ-LÇ?

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

이 코드는 실제로 20 바이트가 될 때까지 제대로 작동하지 않았으며 알아 차리지 못했습니다. [2,2]테스트 케이스 에서 실패했습니다 . 지금 완벽하게 작동합니다.


2

자바 스크립트 (ES6) 127 126 95 80 바이트

g=(a,i,p,b=[])=>a.map(x=>3>x&0<x?(x==p?b[0]++:b=[1,...b],p=x):H)==2?i:g(b,~~i+1)

인덱스가 0입니다. 오류 "ReferenceError: X is not defined""InternalError: too much recursion"잘못된 입력합니다.

테스트 사례


1

클로저, 110 바이트

#(if-not(#{[][1]}%)(loop[c % i 0](if(every? #{1 2}c)(if(=[2]c)i(recur(map count(partition-by + c))(inc i))))))

loop엣지 케이스를 사전 점검 하는 기본 사항 . nil유효하지 않은 입력을 반환 합니다. 모르는 내가 (= [2] '(2))있다 true: O


1

Python 2, 146 바이트 (기능 만)

f=lambda l,i=0:i if l==[1]else 0if max(l)>2or min(l)<1else f([len(x)+1for x in"".join(`v!=l[i+1]`[0]for i,v in enumerate(l[:-1])).split("T")],i+1)

잘못된 입력에 대해 0을 반환합니다 (1 색인이므로 OK). 간단히 다음과 같이 사용하십시오.

print(f([1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1]))

1

수학, 82 바이트

FixedPointList[#/.{{2}->T,{(1|2)..}:>Length/@Split@#,_->0}&,#]~FirstPosition~T-1&

Function{2}정의되지 않은 symbol T, 다음 반복이있는 (하나 이상의) 1s 및 2s 의 목록 및 0고정 소수점에 도달 할 때까지의 다른 항목 을 반복해서 대체 한 다음 결과 빼기 FirstPosition의 기호 를 반환합니다 . 출력은 어디에 (이다 도달하는 데 필요한 반복 -indexed) 번호 truthy 사건과 falsy 경우에이.TFixedPointList1{n}n1{2}-1+Missing["NotFound"]

출력이 n아닌 {n}이면 3 바이트가 더 필요합니다.

Position[FixedPointList[#/.{{2}->T,{(1|2)..}:>Length/@Split@#,_->0}&,#],T][[1,1]]-1&

1

파이썬 2 , 184163156 바이트

  • @Felipe Nardi Batista가 21 바이트를 절약했습니다 !!!! 고마워 !!!!
  • Halvard Hummel이 7 바이트를 절약했습니다 !! 감사

파이썬 2 , 156 바이트

a,c=input(),0
t=a==[]
while 1<len(a)and~-t:
 r,i=[],0
 while i<len(a):
	j=i
	while[a[j]]==a[i:i+1]:i+=1
	r+=[i-j]
 a=r;c+=1;t=any(x>2for x in a)
print~c*t+c

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

설명:

a,c=input(),0                             #input and initialize main-counter 

t=a==[]                                   #set t to 1 if list's empty. 

while len(a)>1:                           #loop until list's length is 1.

 r,i=[],0                                 #Initialize temp. list and 
                                          #list-element-pointer 

 while i<len(a):                          #loop for the element in list 

  j=0                                     #set consecutive-item-counter to 0   

  while(i+j)<len(a)and a[i]==a[i+j]:j+=1  #increase the consec.-counter

  r+=[j];i+=j                             #add the value to a list, move the 
                                          #list-element-pointer 

 a=r;c+=1;t=any(x>2for x in a)            #update the main list, increase t 
                                          #the counter, check if any number 
 if t:break;                              #exceeds 2 (if yes, exit the loop)

print[c,-1][t]                            #print -1 if t or else the 
                                          #counter's 
                                          #value 



1

파이썬 2 , 122 바이트

def f(s,c=2,j=0):
 w=[1]
 for i in s[1:]:w+=[1]*(i!=s[j]);w[-1]+=i==s[j];j+=1
 return(w==[2])*c-({1,2}!=set(s))or f(w,c+1)

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

파이썬 3 , 120 바이트

def f(s,c=2,j=0):
 w=[1]
 for i in s[1:]:w+=[1]*(i!=s[j]);w[-1]+=i==s[j];j+=1
 return(w==[2])*c-({1,2}!={*s})or f(w,c+1)

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

설명

다음 반복 감소를 저장하기 위해 새로운 시퀀스 (w)가 초기화된다. 카운터 (c)는 반복 횟수를 추적하기 위해 초기화됩니다.

원래 순서의 모든 항목이 이전 값과 비교됩니다. 값이 같으면 (w)의 마지막 항목 값이 1 씩 증가합니다. 값이 다르면 순서 (w)가 [1]으로 확장됩니다.

w == [2]이면 카운터 (c)가 반환됩니다. 그렇지 않으면, 원래 순서 (들)에 1과 2 이외의 다른 항목이 있으면 값 -1이 리턴됩니다. 두 경우 모두에 해당하지 않으면 새 시퀀스 (w)와 카운터 (c)가 1 씩 증가하면서 함수가 재귀 적으로 호출됩니다.


바이트를 절약하기 위해 처음 두 줄을로 결합하려고 시도 def f(s,c=2,j=0,w=[1]):하지만 결과가 다릅니다. 아무도 왜 그런지 설명 할 수 있습니까?
Jitse


@JoKing 감사합니다!
Jitse

0

R, 122 바이트

a=scan()
i=0
f=function(x)if(!all(x%in%c(1,2)))stop()
while(length(a)>1){f(a)
a=rle(a)$l
f(a)
i=i+1}
if(a==2)i else stop()

모든 테스트 사례를 통과합니다. 그렇지 않으면 하나 이상의 오류가 발생합니다. 나는 유효성 검사를 싫어한다; 입력이 좋았다면이 코드는 너무 골치 거리였다. 입력이 1과 2의 시퀀스 인 경우에도 Kolakoski 시퀀스의 접두사 일 필요는 없습니다. 여기서는 초기 벡터 (그렇지 않으면 테스트 케이스 [-2,1])가 통과했을 것이고 결과 벡터 (그렇지 않은 경우 )를 모두 확인해야합니다 [1,1,1].


0

루비 , 81 77 바이트

f=->a,i=1{a[1]&&a-[1,2]==[]?f[a.chunk{|x|x}.map{|x,y|y.size},i+1]:a==[2]?i:0}

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

편집 : 재귀 람다로 변환하여 4 바이트를 절약했습니다.

1- 인덱싱 된 반복 횟수 또는 0을 거짓으로 반환합니다.

Ruby 열거 형 청크 방법을 사용합니다.이 방법은 우리가 정확히 필요한 것입니다. 연속 된 동일한 수의 런을 그룹화합니다. 런의 길이는 다음 반복에 대한 배열을 구성합니다. 배열이 1 요소보다 길고 1과 2 이외의 숫자가없는 동안 계속 반복합니다.


0

Pyth , 45 바이트

L?||qb]1!lb-{b,1 2_1?q]2b1Z.V0IKy~QhMrQ8*KhbB

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

이것은 여전히 ​​골프입니다. .?내가 원하는 방식으로 작동하면 확실히 골프를 칠 수 있습니다 ( else가장 바깥 쪽이 아닌 가장 안쪽에있는 구조)

L?||qb]1!lb-{b,1 2_1?q]2b1Z # A lambda function for testing an iteration of the shortening
L                           # y=lambda b:
 ?                          # if
    qb]1                    #    b == [1]
   |    !lb                 #      or !len(b)
  |         {b              #        or b.deduplicate()
           -  ,1 2          #             .difference([1,2]):
                  _1        #               return -1
                    ?q]2b1Z # else: return 1 if [2] == b else Z (=0)

.V0                         # for b in range(0,infinity):
   IKy~Q                    # if K:=y(Q :=        (applies y to old value of Q)
        hM                  #    map(_[0],
          rQ8               #               run_length_encode(Q)):
             *Khb           #    print(K*(b+1))
                 B          #    break

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.