コラコスキ削減


27

概要

皆さんの中には、コラコスキーシーケンスA000002)を知っている方もいるかもしれません。これは、次のプロパティを持つ自己参照シーケンスです。

クーリオコラコスキプロパティ、ヨーヨー。

これは1と2のみを含むシーケンスであり、1と2の各グループについて、ランの長さを合計すると、長さの半分だけになります。つまり、コラコスキーシーケンスは、シーケンス自体の実行の長さを表します。これは、最初の1が削除された同じシーケンスを除き、これを行う唯一のシーケンスです。(これは、1と2で構成されるシーケンスに自分自身を制限する場合にのみ当てはまります-Martin Ender)


チャレンジ

課題は、整数のリストが与えられることです:

  • -1リストがコラコスキーシーケンスの有効なプレフィックスでない場合に出力します。
  • シーケンスがになるまでの反復回数を出力し[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:やがて以外の要素を持つ中間ステップなしで、最終的に2に到達12ます。–Einkorn Enchanter 20 hours ago

偽:終了値は[2]です。中間用語にはセットのもの以外のものが含まれてい[1,2]ます。他にもいくつかあります。例を参照してください。


これは、最低バイト数が勝者になります。


7
単なるfalseの代わりにfalsey値を使用できます-1か?
mbomb007

1
「コラコスキシーケンスの有効なプレフィックスではない」とはどういう意味ですか?私は[2][2,2,1,1,2,1,2]テストケースを見るまでリストが最終的に到達しないことを意味すると想定していました。
-ngenisis

1
@ngenisis 1や以外の要素を持つ中間ステップなしで、最終的に2に到達し2ます。
小麦ウィザード

2
[1]テストケースとして追加することをお勧めします。
エミグナ

1
@ mbomb007明確な値であれば問題ありません。正の整数はうまくありません。1のインデックスを作成する場合、0で十分です。「False」は問題ありません。エラーは問題ありません。正でない戻り値は、-129.42910でも問題ありません。
魔法のタコUr

回答:


8

Haskell126 87 79 76 75バイト

ØrjanJohansenのおかげで39バイト節約

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

オンラインでお試しください!

不正な入力に関するこのエラー。


f(そしてその結果!)アキュムレータの代わりに遅延生成+ span/ を使用することで大幅に短縮できますlengthオンラインでお試しください!
Ørjanヨハンセン

1
の無限ループに入るようです[1]
エミグナ

1
@エミグナ・ダーン。修正するには6バイトかかりますが、修正しました。
小麦ウィザード

@ØrjanJohansenこれは良いヒントのように思えますが、私はHaskellで何が起こっているのかを理解するには十分ではありません。あなたがそれをあなた自身の答えとして投稿することができますが、少なくともあなたの解決策がどのように機能するかわからない限り、私はそれを私の答えに追加しません。:)
小麦ウィザード

1
それから、これはインポートが実際には短い(そして理解しやすい)ケースであることに気付きましたimport Data.List;f l=length<$>group l。(ここで<$>は同義語mapです。)また、2つの異なる-1ケースを使用する代わりに、@(_:_:_)パターンを使用して、メインケースが長さ> = 2のリストのみに一致するように強制する方が短くなります。オンラインでお試しください!
Ørjanヨハンセン

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:ありがとう、修正!
エミグナ

リンクを更新するのを忘れている可能性があります...
周順周

1
@WeijunZhou:確かに私は持っていた。再びありがとう:)
エミグナ

3

SCALA、290(282?)文字、290(282?)バイト

それはすっごく時間がかかった...しかし、私はついに完了です!

このコードで:

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(コピーはvart考慮されるパラメーターの代わりに変更可能にすることですval-ありがとうScaLa)。数えるべきか教えてください。

十分に難しい。オンラインでお試しください!

PS:再帰的に実行することを考えていましたが、真の再帰的な「サブ関数」のパラメーターとしてカウンターを渡す必要があります。この事実により、2つの関数を宣言することになり、これらの文字/バイトは失われるだけです。

編集:私たちはカウント[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

それは最適化されていません(同じ条件で重複する "out"があります:に到達した[2]ときとparamが[2]別々に扱われるとき)。

新しいコスト= 342(意図的にタイトルを変更しなかった)


1
のための無限ループに入るようです[1]
エミグナ

うん、しかし(私は少なくとも理解されるように)OPによって前記のように、「配列になる前の出力反復回数および「最初の1を削除して、」[2]
V.クルトワ

私の理解で[1]は、決して到達[2]しないため、-1を返す必要があります。
エミグナ

そうですか。だから、私は最初にリッテ条件を置くべきだと思いますか?アドバイスをしてくれてありがとう。
V.クルトワ

私はscalaを知りませんが、リストの長さが2より小さい場合にループが停止するように修正できると仮定します。要素が最後に2であることをすでにチェックしているようです。
エミグナ

2

JavaScript、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中括弧、&& vs if)。Googleのクロージャーコンパイラ(closure-compiler.appspot.com)を使用して、これらの最適化を行うことができます

2

ゼリー26 25 22 21 20バイト

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

オンラインでお試しください!

このコードは実際には20バイトまで正しく機能していなかったので、気づきさえしませんでした。[2,2]テストケースで失敗していました。今完璧に動作するはずです。


2

JavaScriptの(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

Clojure、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

Mathematica、82バイト

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

Functionこれは{2}、未定義のsymbol T、(1つまたは複数の)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

パイソン2184の163 156バイト

  • @Felipe Nardi Batistaは21バイト節約しました!!!! どうもありがとう!!!!
  • Halvard Hummelが7バイト節約しました!! ありがとう

Python 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

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

オンラインでお試しください!

Python 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が返されます。どちらにも当てはまらない場合、関数は(s)として新しいシーケンス(w)で再帰的に呼び出され、カウンター(c)が1増加します。


バイトを節約するために、最初の2行をに結合しようとし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つ以上のエラーをスローします。妥当性チェックは嫌いです。入力が素晴らしかった場合、このコードは非常に洗練されていたかもしれません。入力が1と2のシーケンスである場合でも短くなり、必ずしもコラコスキーシーケンスのプレフィックスではありません。ここでは、初期ベクトル(そうでない場合はテストケース[-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のインデックス付き反復回数またはfalseyとして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.