アヒル、アヒル、ヨセフス


49

整数配列の場合:

  1. 最初の番号から開始
  2. n個の位置にジャンプします。nは現在の位置の値です
  3. 現在の位置を削除し、次の位置を現在の位置にします。
  4. 残りの番号が1つになるまで手順2に進みます
  5. その番号を印刷する

ルール

配列は折り返します(配列の最後の数字の次の数字が最初の数字です)。

ゼロはそれ自体を削除します(明らかに)。

負の数は入力として許可されていません。

テストケース

[1] => 1
[1,2] => 1
[1,2,3] => 3
[1,2,2] => 1
[1,2,3,4] => 1
[6,2,3,4] => 4
[1,2,3,4,5] => 5
[0,1] => 1
[0,0,2,0,0] => 0

ステップバイステップの例

[1,4,2,3,5]
 ^          start from the first position
   ^        jump 1 position (value of the position)
[1,  2,3,5] remove number in that position
     ^      take next position of the removed number (the 'new' 'current' position)
         ^  jump 2 positions
[1,  2,3  ] remove number in that position
 ^          take next position (looping on the end of the array)
     ^      jump 1 position
[1,    3  ] remove number in that position
       ^    take next position (looping)
 ^          jump 3 positions (looping on the end of the array)
[      3  ] remove number in that position
print 3

例2

[4,3,2,1,6,3]
 ^            start from the first position
         ^    jump 4 positions
[4,3,2,1,  3] remove number in that position    
           ^  take next position
     ^        jump 3 positions
[4,3,  1,  3] remove number in that position    
       ^      take next position
           ^  jump 1 positions
[4,3,  1    ] remove number in that position    
 ^            take next position
   ^          jump 4 positions
[4,    1    ] remove number in that position    
       ^      take next position
 ^            jump 1 position
[      1    ] remove number in that position
print 1

これはで、バイト単位の最短回答が勝ちです!


14
素敵な最初の挑戦!
ルイスメンドー

2
@LuisMendoはい..挑戦「...のようにスキップ」
J42161217

2
@Jenny_mathy似たようなものがあるとは思いませんでしたが、ルイスが言ったように、ラップアラウンドアレイはゴルフにとって興味深い挑戦です。私は思う:/
workoverflow

3
@EriktheOutgolfer本当に馬鹿じゃない。そこにある要素は区別できず、ステップサイズは固定されています。ルイスの方がずっと近いですが、それでも十分に違うと思います。
マーティンエンダー

3
実際に最終番号を印刷する必要がありますか、それとも単に返すことができますか?実際に数値を返す必要がありますか、それとも関数を実行した後に配列に数値だけが含まれるように、配列をその場で操作するだけですか?
iamnotmaynard

回答:



7

Haskell54 50 48バイト

f[x]=x
f(x:r)=f$snd<$>zip r(drop(x+1)$cycle$x:r)

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

説明:

  • f[x]=x:指定されたリストがシングルトンリストの場合、その要素を返します。
  • f(x:r)=f$ ...:それ以外の場合f、次のリストに再帰的に適用されます。
    • 現在のリストの要素は無限に循環します(cycle$x:r)、
    • 最初のx+1要素が削除された(drop(x+1)$)、
    • そして、長さに切り捨てられrます。(snd<$>zip rはの短い代替ですtake(length r))。

以前の54バイトバージョン:

f=(%)=<<head
_%[x]=x
n%(x:r)|n<1=f r|s<-r++[x]=(n-1)%s

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



6

MATL、21バイト

1`yy)+ynX\[]w(5Mynq]x

オンラインでお試しください!または、すべてのテストケースを確認します

説明

1        % Push 1: current position in the array
`        % Do...while
  yy     %   Duplicate top two elements in the stack. Takes input implicitly
         %   in the first iteration.
         %   STACK: array, position, array, position
  )      %   Get specified entry in the array
         %   STACK: array, position, selected entry
  +      %   Add
         %   STACK: array, position (updated)
  y      %   Duplicate from below
         %   STACK: array, position, array
  n      %   Number of elements of array
         %   STACK: array, position, number of elements or array
  X\     %   1-based modulus
         %   STACK: array, position (wrapped around)
  []     %   Push empty array
         %   STACK: array, position, []
  w      %   Swap
         %   STACK: array, [], position
  (      %   Write value into specified entry in array. Writing [] removes
         %   the entry
         %   STACK: array (with one entry removed)
  5M     %   Push latest used position. Because of the removal, this now
         %   points to the entry that was after the removed one
         %   STACK: array, position
  y      %   Duplicate from below
         %   STACK: array, position, array
  n      %   Number of elements of array
         %   STACK: array, position, number of elements of array
  q      %   Subtract 1
         %   STACK: array, position, number of elements of array minus 1
]        % End. If top of the stack is nonzero, proceed with next iteration
         % STACK: array (containing 1 entry), position
x        % Delete. Implicitly display
         % STACK: array (containing 1 entry)

1
注:ポインターを保持する代わりにリストの回転を使用すると、おそらくこれがはるかに短くなります。
エリックアウトゴルファー

1
@Erikありがとう。しかし、今私は説明を追加したので、私はこのままにしておくと思う
ルイス・メンドー

まあ、あなたはいつでも説明を削除することができます、それは歴史に保存されます:)
エリックアウトゴルファー


5

CJam、15バイト

l~_,({_0=m<1>}*

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

説明

ポインタを追跡する代わりに、現在の要素が常に先頭に来るように、配列を周期的にシフトします。

l~     e# Read and evaluate input.
_,(    e# Get its length L and decrement to L-1.
{      e# Run this block L-1 times...
  _0=  e#   Get the first element X.
  m<   e#   Rotate the array left by X positions.
  1>   e#   Discard the first element.
}*
       e# The final element remains on the stack and gets printed implicitly.

残念ながら、バイトを保存しない楽しい代替手段:

l~_{;m<1>_0=}*;

5

Brain-Flak、88バイト

([[]]()){({}<(({})){({}<({}<([]){({}{}<>)<>([])}{}>)<>{({}[<>[]])<>}<>>[()])}{}{}>())}{}

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

説明

([[]]())                      Push negative N: the stack height - 1
{({}< … >())}{}               Do N times
     (({}))                     Duplicate M: the top of the stack
     {({}< … >[()])}{}          Do M times 
                                  Rotate the stack by 1:
          ({}< … >)               Pop the top of the stack and put it back down after
          ([]){({}{}<>)<>([])}{}  Pushing the rest of the stack on to the other one, in reverse, with the stack height added to each element (to ensure that all are positive)
          <>{({}[<>[]])<>}<>      Push the rest of the stack back, unreversing, and subtracting the stack height from each element
                      {}        Pop the top of stack

1
非常に奇妙なゴルフですが、ここでは88バイトです。
小麦ウィザード

1
@WheatWizardニース、驚いたことに、以前にそのようなことを試しました。
H.PWiz

どうやって人々がそのようにコーディングできるのか、私には決してわかりません!擬似コード変換プログラムなどがありますか?
ワークフロー

1
@workoverflowいいえ、見た目よりも正直に簡単です。実際に始める前は非常に困難でしたが、コマンドがこのように単純な場合、習得するのは簡単です。
H.PWiz

5

Python 2、55バイト

def f(a):
 while a[1:]:l=a[0]%len(a);a[:]=a[-~l:]+a[:l]

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

デフォルトで許可されているシングルトンリストとして出力します。関数引数の変更が許可されていることを思い出させて、デニスのおかげで数バイト節約しました。

使い方

  • def f(a)-パラメータを使用して関数を定義しますa

  • while a[1:]:- a最初の要素が削除されたのは真実ですが、それに続くコードブロックを実行します。1つ以上の要素を持つリストは真実であり、空のリストはPythonでは偽であるためa、長さが1に達すると停止します。

  • l=a[0]%len(a)-最初の要素を取得し、その長さによる除算の残りを取得しaます。結果をに割り当てlます。

  • a[:]=a[-~l:]+a[:l]- 要素をa左に回転さlせ、最初の要素を削除しaます。これを所定の位置に割り当てます。


Python 2、63バイト

f=lambda a,i=0:a[1:]and f(a,a.pop(((a*-~i)[i]+i)%len(a))+1)or a

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

長いですが、これははるかにエレガントに見えます。チャットを手伝ってくれたovsにも感謝します。


1
a,*b=input()(python3)のようなことをして、数バイトを節約できませんでしたか?しかしl、それがスライスにどのように影響するかわからない
ロッド

1
@Rod私もPythonの3で入力を評価する必要があるだろう、そうは思わない
氏Xcoderに





3

Mathematica、36バイト

マーティンのアルゴリズムを使用

#//.l:{x_,__}:>Rest@RotateLeft[l,x]&

Misha Lavrov && Martin Enderから-5バイト

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


1
パターンを使用して最初の要素を選択すると、2バイトを節約できます#//.{x_,y__}:>Rest@RotateLeft[{x,y},x]&。(これは{a}、パターンに一致しなくなったために要素が1つだけになったときに停止します{x_,y__}。)
Misha Lavrov

1
@MishaLavrovは今はテストできませんが、をドロップしてyリスト全体を呼び出しlてからのl代わりに使用することで、さらにテストを短縮できます{x,y}
マーティンエンダー

1
@MartinEnderこういう意味#//.l:{x_,__}:>Rest@RotateLeft[l,x]&ですか?
ミシャラヴロフ

1
@MishaLavrovうん。
マーティンエンダー

3

J21 17バイト

FrownyFrogのおかげで-4バイト

((1<#)}.{.|.])^:_

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

元の:

([:}.{.|.])^:(1<#)^:_

使い方:

^:_ 結果が変化しなくなるまで繰り返します

^:(1<#) リストの長さが1より大きい場合

{.|.] リストを最初のアイテムを左に回す

[:}. 最初の要素をドロップし、フォークにキャップをします

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


@ FrownyFrogありがとう、私はこれを試していない-それははるかに良いです!
ガレンイワノフ

3

JavaScript(ES6)、54 60バイト

@Shaggy Fixedバージョンのおかげで1バイト節約
(+6バイト)

入力配列を変更します。これはシングルトンに削減されます。

f=(a,p=0)=>1/a||f(a,p=(p+a[p%(l=a.length)])%l,a.splice(p,1))

テストケース

どうやって?

チャレンジで説明したアルゴリズムを再帰的に適用します。停止条件のみが1/a少し奇妙に見えるかもしれません。算術演算子を適用する場合:

  • 複数の要素の配列は強制されNaN1/NaNまたNaN(偽)です。
  • 正確に一つの整数のアレイは、いずれかをもたらす、その整数に強制される1/0 = +Infinityか、1/N = positive floatのためにN> 0(両方truthy)。
f = (a, p = 0) =>                 // a = input array, p = pointer into this array
  1 / a ||                        // if a is not yet a singleton:
    f(                            //   do a recursive call with:
      a,                          //     a
      p = (                       //     the updated pointer
        p + a[p % (l = a.length)] //
      ) % l,                      //
      a.splice(p, 1)              //     the element at the new position removed
    )                             //   end of recursive call

splice元の配列を変更するように見るとf=(a,p=0)=>1/a||f(a,p=p+a[p]%a.length,a.splice(p,1))52バイト
Shaggy

それがステップの例により第2のステップのために正しい結果が得られていないようだf=(a,p=0)=>1/a?a:f(a,p=(p%a.length+a[p%a.length])%a.length,a.splice(p,1))okですが、最適化することができる
ナウエルFouilleul

@NahuelFouilleulおっと。ある時点で、括弧をp+a[p]削除できると思いました。もちろん、そうではありません。これを報告していただきありがとうございます!
アーナルド

@Neilがここで私の注意を引いたこのコンセンサスをご覧ください。
シャギー

@Shaggyああ、なるほど。ありがとうございました!(私はあなたのTIOリンクを初めて見逃しました...)
アーナルド


3

Java 8、79バイト

このラムダはa Stack<Integer>を受け入れ、intor を返しますInteger

l->{for(int i=0,s=l.size();s>1;)l.remove(i=(i+l.get(i%s))%s--);return l.pop();}

オンラインで試す

非ゴルフ

l -> {
    for (
        int i = 0, s = l.size()
        ; s > 1
        ;
    )
        l.remove(
            i = (i + l.get(i % s)) % s--
        );
    return l.pop();
}

謝辞

  • -2バイト、Nahuel Fouilleulに感謝

1
i%=sl.get(i)変更された場合は削除される場合がありますl.get(i%s)
ナウエルフイユ

2

Pyth、9バイト

.WtHt.<Zh

ここで試してみてください!

デフォルトで許可されているように、結果をシングルトンリストとして出力します

使い方

.WtHt.<Zh ~ Full program.

.W        ~ Functional while. It takes three arguments, two functions: A and B
            and a starting value, which in this case is automatically assigned
            to the input. While A(value) is truthy, value is set to B(value).
            Returns the ending value. A's argument is H and B's is Z.
  tH      ~ A (argument H): Remove the first element of H. A singleton list
            turns into [], which is falsy and thus breaks the loop. Otherwise,
            it is truthy and the loops goes on until the list reaches length 1.
     .<Zh ~ B (argument Z): Cyclically rotate Z by Z[0] places, whereas Z[0]
            represents the first element of Z.
    t     ~ And remove the first element.

注:これらの括弧を表示したくない場合は、コード全体を追加するhe、コード全体の前に追加してください。



2

Perl 6の46の 45バイト

(Brad Gilbertのおかげで1バイト)

{($_,{(|$_ xx*)[.[0]+(1..^$_)]}...1)[*-1][0]}

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

($_, { ... } ... 1)入力リストで始まり$_、ブレース式によって生成される各連続要素でリストのシーケンスを生成します。リストがスマートマッチした1場合、つまり、長さが1になった時点で終了します。[* - 1]最後の要素と最後の[0]そのシングルトンリストから唯一の要素を取り出します。

(|$_ xx *)現在の要素のフラットで無限に複製されたコピーを生成します。このリストには.[0] + (1 ..^ $_)、シリーズの次の有限リストを抽出するための範囲でインデックスが付けられます。


1
心吹きオブジェクト指向
エイドリアン

[*-1][0][*-1;0]バイトの保存に組み合わせることができます。また、バイト1..$_-11..^$_再度保存するように記述した方がよいでしょう。
ブラッドギルバートb2gills

@ BradGilbertb2gillsを試しましたが[*-1;0]、どういうわけか同等ではないようです。関数は、数値ではなくリストを返します。
ショーン

それは1..^$_最適化を停止しません
Brad Gilbert b2gills

1

Perl 5の47 43 41 + 2(-ap)= 43バイト

$\=splice@F,($_+=$F[$_%@F])%@F,1while@F}{

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

スペースで区切られた数字として入力を受け取ります。


ステップバイステップの例は、以下のとまったく同じではありませんんんが、長くなっているようだ$x%=@F,splice@F,$x=($x+$F[$x])%@F,1while$#F;$_="@F"
ナウエルFouilleul

1
うわー、私のゲームを起動する必要があります。
エイドリアン



1

Java 8、325バイト

ゴルフ:

static void n(Integer[]j){Integer[]h;int a=0;h=j;for(int i=0;i<j.length-1;i++){if(h.length==a){a=0;}a=(a+h[a])%h.length;h[a]=null;h=m(h);}System.out.print(h[0]);}static Integer[] m(Integer[]array){Integer[]x=new Integer[array.length-1];int z=0;for(int i=0;i<array.length;i++){if(array[i]!=null){x[z]=array[i];z++;}}return x;}

ゴルフをしていない:

 interface ArrayLeapFrog {
static void main(String[] z) throws Exception {
    Integer[] j = {6, 2, 3, 4};
    n(j);
}

static void n(Integer[] j) {
    Integer[] h;
    int a = 0;
    h = j;
    for (int i = 0; i < j.length - 1; i++) {
        if (h.length == a) {
            a = 0;
        }
        a = (a + h[a]) % h.length;
        h[a] = null;
        h = m(h);
    }
    System.out.print(h[0]);
}

static Integer[] m(Integer[] array) {
    Integer[] x = new Integer[array.length - 1];
    int z = 0;
    for (int i = 0; i < array.length; i++) {
        if (array[i] != null) {
            x[z] = array[i];
            z++;
        }
    }
    return x;
  }
}

4
ようこそ!いくつかのヒント:staticここでキーワードを数える必要はありません。通常、マルチメソッドソリューションはクラスの非静的メンバーとして実装されmain、テスト用のインスタンスを作成します。また、そのようにすると、Java 7をサポートし、単に「Java」ソリューションとして送信できます。将来の参照のために、入力形式はここで非常に柔軟になる傾向があるため、たとえば、入力をList(この問題に非常に役立ちます)として選択することができます。
ヤコブ

1

APL + WIN、36バイト

¯1↑⍎¨(1⌈¯1+⍴v←,⎕)⍴⊂'v←(1<⍴v)↓v[1]⌽v'

説明:

画面入力のプロンプト。

'v←(1<⍴v)↓v[1]⌽v' Loop logic as a string

 (1<⍴v)↓ only drop the first when number of elements n>1

 (1⌈¯1+⍴v←,⎕)⍴⊂ create a nested vector of logic of length 1 max n-1

 ⍎¨ execute each element of the nested vector in turn

¯1↑ take answer from executing final element

1

Python 2、61バイト

def f(x):
 while x[1:]:y=x[0]%len(x);x=x[y+1:]+x[:y]
 print x

1
たくさんのpythonの回答が存在することは知っていますが、自分で追加することも考えました。
Rɪᴋᴇʀ

1

JavaScript、58 56 59バイト

let f =

a=>{for(i=0,k=a.length;k>1;)i+=a[i%=k],a.splice(i%=k--,1)}
<h2>Test</h2>
Enter or paste a valid array literal within square brackets and click Run.
<blockquote>
   <input id = "array" type="text" length="20">
   <button type="button" onclick="run()">Run</button>
</blockquote>
Result: <pre id="o"></pre>

<script>
    function run() {
       let a = JSON.parse(array.value);
       f(a);
       o.textContent = a;
    }
</script>

その場で更新される入力配列に残っている唯一の要素として結果を返します。

forループ本体でブロックステートメントの代わりにコンマ区切りステートメントを使用することで2バイトが節約されました!配列の最後で削除された要素からスキップするために失われた3バイト(:

少ないゴルフ:

a => {
    for(i=0,k=a.length;k>1;) // once less than array length
        i+=a[i%=k],          // the new index
        a.splice(            // delete an element
           i%=k--,           // ensuring index is within array,
                             // and post decrement loop count
           1
        )
}

これはに対する間違った答えを与えるようです[3, 5, 7, 9]
ニール

間違ってい[3,5,7,9]ます。期待値5
edc65

機能は...その上、それはできない仕事は自分なので、バイトカウントは、念頭に置いていることを適切に保っている場合、私はわからないんだけど、値を返さない
ブライアンH.

@ edc65およびNeil、ありがとう-配列の最後で削除された要素のインデックスは、短縮された配列の先頭に調整されていませんでした。
traktor53

@BrianH。関数はそのパラメーターを変更し、そのcodegolf.meta.stackexchange.com/a/4942/21348
edc65

1

Brain-Flak、104バイト

H.PWizにはここで短い回答がありますが、私はそれを手伝いましたので、チェックしてみてください。

([[]]()){({}()<(({})){({}[()]<({}<(([])<{{}({}<>)<>([])}{}<>>)<>>)<>{({}[()]<({}<>)<>>)}{}<>>)}{}{}>)}{}

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

説明

([[]]())   #Push 1 minus stackheight
{({}()<    #N times
 (({}))    #Get a copy of the top
 {({}[()]< #N times
  ({}<(([])<{{}({}<>)<>([])}{}<>>)<>>)<>{({}[()]<({}<>)<>>)}{}<>
           #Roll the top to the bottom (From the wiki)
 >)}{}     #End loop
 {}        #Remove one value
>)}{}      #End loop

競争すると思った。それから私は私がほぼ正確だったことに気づいたあなたと同じ間隔で異なる「トップロール」から、
H.PWiz

私はそれを観た ;)。すべてが非負であるという事実を使用するのはかなり賢いです。
小麦ウィザード


1

R 111の117 126バイト

whileループに変更して11バイトのゴルフをしてくれた@Giuseppeに感謝します。関数を削除し、ユーザー入力を直接読み取ってさらに4バイトを取得しました。

そこにたどり着くのに何が必要か気に入らない-よりエレガントなソリューションが存在すると確信している。

i=scan();m=1;while((l=sum(i|1))-1){j=i[m];p=`if`(j+m>l,j%%l+!m-1,j+m);p=`if`(!p,m,p);i=i[-p];m=`if`(p-l,p,1)};i

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

未ゴルフコード

i=scan()
m=1
while((l=sum(i|1))-1){
  j=i[m]
  p=`if`(j+m>l,j%%l+!m-1,j+m)
  p=`if`(!p,m,p)
  i=i[-p]
  m=`if`(p-l,p,1)
}
i

117バイト -これは再帰関数であるため、名前f=を含める必要があることに注意してください
ジュゼッペ

1
配列を回転させない1ベースのインデックス言語では、これは非常に難しい課題であることがわかりました。これはwhileループを使用すると1〜3バイト短くなる可能性があります。
ジュゼッペ


f=再帰関数の一部を忘れていたため、以前の115バイトは無効でした。:(
ジュゼッペ

再帰性を反映するために古いスコアと新しいスコアを更新しました:) 'while'ループでは、スキャンを使用してさらに4バイトをゴルフしました。
マーク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.