Anatra, Anatra, Giuseppe Flavio


49

Dato un array intero:

  1. Inizia dal primo numero
  2. Salta in avanti di n posizioni dove n è il valore della posizione corrente
  3. Elimina la posizione corrente, trasformando la posizione successiva nella posizione corrente.
  4. Andare al passaggio 2 fino a quando rimane un numero
  5. Stampa quel numero

Regole

L'array si avvolge (il numero successivo all'ultimo numero dell'array è il primo numero).

Uno zero si rimuove (ovviamente).

I numeri negativi non sono ammessi come input.

Casi test

[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

Esempio passo-passo

[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

Esempio n. 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

Questo è , vince la risposta più breve in byte!


14
Bella prima sfida!
Luis Mendo,

2
@LuisMendo Sì .. le sfide "salta come un ..."
J42161217

2
@Jenny_mathy Non pensavo che ce ne sarebbe stato uno simile, ma come ha detto Luis, l'array avvolgente rappresenta una sfida interessante per il golf. Penso: /
workoverflow

3
@EriktheOutgolfer Non proprio un imbecille. Gli elementi sono indistinguibili e la dimensione del gradino è fissa. Luis è molto più vicino, ma penso che sia sufficientemente diverso.
Martin Ender,

3
Deve davvero stampare il numero finale o può semplicemente restituirlo? Deve effettivamente restituire il numero o può semplicemente operare sull'array sul posto in modo che dopo l'esecuzione della funzione l'array contenga solo il numero?
iamnotmaynard,

Risposte:


9

Buccia , 7 byte

Ciò restituisce il risultato come un elenco singleton

ΩεSotṙ←

Provalo online!

Spiegazione

Ω               Until
 ε              the result is a singleton list
     ṙ          Rotate left by
  S   ←         the first element
   ot           Then remove the first element  

7

Haskell , 54 50 48 byte

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

Provalo online!

Spiegazione:

  • f[x]=x: Se l'elenco specificato è un elenco singleton, restituisce il suo elemento.
  • f(x:r)=f$ ...: Altrimenti si applicano ricorsivamente fal seguente elenco:
    • Gli elementi dell'elenco corrente sono ciclicamente infiniti ( cycle$x:r),
    • con i primi x+1elementi rimossi ( drop(x+1)$),
    • e troncato alla lunghezza di r. ( snd<$>zip rè un'alternativa più breve a take(length r)).

Versione a 54 byte precedente:

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

Provalo online!



6

MATL , 21 byte

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

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

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
Nota: l'uso delle rotazioni dell'elenco invece di mantenere un puntatore probabilmente lo renderà molto più breve.
Erik the Outgolfer,

1
@Erik Grazie. Ma ora che ho aggiunto la spiegazione penso che la lascerò così
Luis Mendo il

Bene, puoi sempre rimuovere la spiegazione, che sarà conservata nella storia :)
Erik the Outgolfer,

6

Python 3 , 54 51 byte

f=lambda x:x and f((x+x*x[0])[x[0]:][1:len(x)])or x

L'output è un elenco singleton.

Provalo online!


Completamente indipendente, ma mi piace il tuo cappello da unicorno, Dennis. xD (E bella risposta ovviamente, come sempre!)
Kevin Cruijssen il

5

CJam , 15 byte

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

Provalo online!

Spiegazione

Invece di tenere traccia di un puntatore, sposto l'array ciclicamente in modo che l'elemento corrente sia sempre in primo piano.

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.

Un'alternativa divertente che purtroppo non salva alcun byte:

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

5

Brain-Flak , 88 byte

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

Provalo online!

Spiegazione

([[]]())                      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
Un golf molto strano ma eccolo qui in 88 byte .
Wheat Wizard

1
@WheatWizard Nice, sorprendentemente ho provato qualcosa del genere prima.
H.Piz,

Non riesco mai a sapere come la gente possa programmare così! c'è un traduttore pseudo-codice o qualcosa del genere?
workoverflow

1
@workoverflow no, è onestamente più semplice di quanto sembri. È stato molto scoraggiante prima di iniziare, ma quando i comandi sono così semplici, è facile da imparare.
H.Piz,

5

Python 2 , 55 byte

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

Provalo online!

Output come elenco singleton, come consentito per impostazione predefinita . Ho salvato qualche byte grazie a Dennis , ricordandomi che è consentito modificare l'argomento della funzione.

Come funziona

  • def f(a)- Definisce una funzione con un parametro a.

  • while a[1:]:- Mentre acon il primo elemento rimosso è vero, eseguire il blocco di codice da seguire. Una lista con uno o più elementi è vera, e le liste vuote sono false in Python, quindi questo si fermerà una volta che araggiungerà una lunghezza di 1.

  • l=a[0]%len(a)- Prendi il primo elemento e ottieni il resto della divisione per la lunghezza di a. Assegna il risultato a l.

  • a[:]=a[-~l:]+a[:l]- Ruota aa sinistra di lelementi e rimuovi il primo, mentre assegni questo ain posizione.


Python 2 , 63 byte

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

Provalo online!

Anche se più lungo, questo sembra molto più elegante. Grazie anche a ovs per l'aiuto nella chat.


1
Non potresti fare qualcosa come a,*b=input()(python3) e salvare pochi byte? Tuttavia non sono sicuro di come ciò influirebbe le la fetta
Rod

1
@Rod Non credo, avrei bisogno di valutare anche l'input in Python 3
Mr. Xcoder,


4

Gelatina , 9 byte

ṙḷ/ḊµL’$¡

Provalo online!

-2 byte grazie a user202729

Spiegazione

ṙḷ/ḊµL’$¡  Main Link
     L’$¡  Repeat <length - 1> times
ṙ          Rotate left by
 ḷ/        The first element (from JHT; thanks to user202729)
   Ḋ       Take all but the first element



3

Mathematica, 36 byte

usa l'algoritmo di Martin

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

-5 byte da Misha Lavrov && Martin Ender

Provalo online!


1
È possibile salvare due byte utilizzando il modello per selezionare il primo elemento #//.{x_,y__}:>Rest@RotateLeft[{x,y},x]&. (Questo si interrompe quando c'è un solo elemento perché {a}non corrisponde più al modello {x_,y__}.)
Misha Lavrov,

1
@MishaLavrov non può testare in questo momento, ma probabilmente puoi accorciarlo ulteriormente facendo cadere il y, chiamando l'intero elenco le quindi usando linvece di {x,y}.
Martin Ender,

1
@MartinEnder Intendi in questo modo - #//.l:{x_,__}:>Rest@RotateLeft[l,x]&?
Misha Lavrov,

1
@MishaLavrov yep.
Martin Ender,

3

J , 21 17 byte

-4 byte grazie a FrownyFrog

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

Provalo online!

Originale:

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

Come funziona:

^:_ ripetere fino a quando il risultato non smette di cambiare

^:(1<#) se la lunghezza dell'elenco è maggiore di 1

{.|.] ruota l'elenco a sinistra il primo elemento volte

[:}. rilasciare il primo elemento e tappare la forcella

Provalo online!


@ FrownyFrog Grazie, non ho provato questo - è molto meglio!
Galen Ivanov,

3

JavaScript (ES6), 54 60 byte

Salvato 1 byte grazie alla versione fissa @Shaggy
(+6 byte)

Modifica l'array di input , che è ridotto a un singleton.

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

Casi test

Come?

Applichiamo ricorsivamente l'algoritmo descritto nella sfida. Solo la condizione di arresto 1/apuò sembrare un po 'strana. Quando si applica un operatore aritmetico:

  • Le matrici di più di un elemento sono costrette a NaNed 1/NaNè anche NaN(falsa).
  • Le matrici di esattamente un numero intero sono costrette a quel numero intero, portando a uno 1/0 = +Infinityo 1/N = positive floata N> 0 (entrambi verità).
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

Visto che splicemodifica l'array originale, potresti farlo f=(a,p=0)=>1/a||f(a,p=p+a[p]%a.length,a.splice(p,1))per 52 byte
Shaggy

sembra che non dia il risultato giusto per il secondo esempio passo dopo passo, f=(a,p=0)=>1/a?a:f(a,p=(p%a.length+a[p%a.length])%a.length,a.splice(p,1))va bene ma può essere ottimizzato
Nahuel Fouilleul,

@NahuelFouilleul Oops. A un certo punto ho pensato che le parentesi intorno p+a[p]potessero essere rimosse. Il che - ovviamente - non è il caso. Grazie per aver segnalato questo!
Arnauld,

Vedi questo consenso , che @Neil ha portato alla mia attenzione qui .
Shaggy,

@Shaggy Oh, capisco. Grazie! (Ho perso il tuo link TIO la prima volta ...)
Arnauld


3

Java 8, 79 byte

Questo lambda accetta un Stack<Integer>e restituisce un into Integer.

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

Provalo online

Ungolfed

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

Ringraziamenti

  • -2 byte grazie a Nahuel Fouilleul

1
i%=spuò essere rimosso se l.get(i)modificato dal.get(i%s)
Nahuel Fouilleul il

2

Pyth , 9 byte

.WtHt.<Zh

Provalo qui!

Ciò restituisce il risultato come un elenco singleton, come consentito per impostazione predefinita .

Come funziona

.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.

Nota: se non vuoi vedere quelle parentesi, aggiungi ho eprima di tutto il codice.


2

Rapido , 87 byte

func f(a:inout[Int]){var i=0,c=0;while(c=a.count,c>1).1{i=(i+a[i%c])%c;a.remove(at:i)}}

Restituisce come un elenco singleton dalla modificando l'ingresso . Provalo online!

Spiegazione

func f(a:inout[Int]){
  var i=0,c=0;            // Set the index i to 0
  while(c=a.count,c>1).1{ // While the length of the list > 0:
    i=(i+a[i%c])%c;       //  Add a[i] to i and loop back using modulo
    a.remove(at:i)        //  Remove a[i]
  }
}

2

Perl 6 , 46 45 byte

(-1 byte grazie a Brad Gilbert)

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

Provalo online!

($_, { ... } ... 1)genera una sequenza di elenchi, a partire dall'elenco di input $_, ogni elemento successivo generato dall'espressione parentesi graffa e termina quando l'elenco smart-match 1--ie, ha una lunghezza di 1. Il trailing [* - 1]ottiene l'elemento finale e il finale[0] elimina l'unico elemento dall'elenco singleton.

(|$_ xx *)genera una copia piatta, replicata all'infinito dell'elemento corrente. Questo elenco è indicizzato con l'intervallo .[0] + (1 ..^ $_)per estrarre il prossimo elenco finito nella serie.


1
mente soffiato oO
Adrian

[*-1][0]può essere combinato per [*-1;0]salvare un byte. Inoltre 1..$_-1è meglio scrivere come 1..^$_salvare di nuovo un byte.
Brad Gilbert b2gills

@ BradGilbertb2gills Ho provato [*-1;0], ma in qualche modo non sembra essere equivalente. La funzione restituisce quindi un elenco anziché un numero.
Sean,

Ciò non ferma l' 1..^$_ottimizzazione
Brad Gilbert b2gills il

1

Perl 5 , 47 43 41 + 2 ( -ap) = 43 byte

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

Provalo online!

Accetta input come numeri separati da spazio.


sembra che non sia esattamente lo stesso dell'esempio seguente, ma è più lungo$x%=@F,splice@F,$x=($x+$F[$x])%@F,1while$#F;$_="@F"
Nahuel Fouilleul,

1
wow oO Devo alzare il gioco.
Adrian,



1

Java 8 , 325 byte

golfed:

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;}

Ungolfed:

 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
Benvenuto! Un paio di suggerimenti: non è necessario contare le staticparole chiave qui. Tipicamente le soluzioni multi-metodo sono implementate come membri non statici di una classe e maincreano un'istanza per il test. Inoltre, se lo fai in questo modo, supporti Java 7 e puoi inviarlo semplicemente come una soluzione "Java". Per riferimento futuro, il formato di input tende ad essere abbastanza flessibile qui, quindi ad esempio potresti scegliere di prendere l'input come List(che è abbastanza utile per questo problema).
Jakob,

1

APL + WIN, 36 byte

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

Spiegazione:

Richiede l'inserimento dello schermo.

'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 byte

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

1
So che esistono un sacco di risposte in pitone, ma ho pensato che avrei potuto aggiungere anche le mie.
Rɪᴋᴇʀ

1

JavaScript, 58 56 59 byte

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>

Restituisce il risultato come unico elemento rimasto nell'array di input che viene aggiornato in posizione.

Due byte salvati utilizzando un'istruzione separata da virgola anziché un'istruzione di blocco nel corpo del ciclo for! Tre byte persi per saltare da un elemento eliminato alla fine dell'array (:

Meno golf:

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

Questo sembra dare la risposta sbagliata per [3, 5, 7, 9].
Neil,

Sbagliato per [3,5,7,9]. Valore atteso 5
edc65

La funzione non restituisce il valore, non sono sicuro che il conteggio dei byte sia corretto tenendo conto di ciò, dal momento che non può funzionare da solo ...
Brian H.

@ edc65 e Neil, grazie - l'indice di un elemento cancellato alla fine dell'array non veniva adattato all'inizio dell'array abbreviato.
Traktor53,

@BrianH. la funzione modifica il suo parametro, c'è consenso su quel codegolf.meta.stackexchange.com/a/4942/21348
edc65

1

Brain-Flak , 104 byte

H.PWiz ha una risposta più breve qui che ho aiutato a fare, dovresti dare un'occhiata.

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

Provalo online!

Spiegazione

([[]]())   #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

Pensavo di competere . Poi mi sono reso conto che il mio era quasi esattamente uguale al tuo , a parte un diverso "tiro in alto"
H.Pwiz,

L'ho visto ;). Usare il fatto che tutto sia non negativo è piuttosto intelligente.
Mago del grano


1

R , 111 117 126 byte

Grazie a @Giuseppe per il golf di 11 byte passando a un ciclo while, ne ho ottenuti altri 4 rimuovendo la funzione e leggendo direttamente l'input dell'utente.

Non mi sento benissimo per quello che ci è voluto per arrivarci - sono sicuro che esiste una soluzione più elegante.

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

Provalo online!

Codice Ungolfed

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 byte - si noti che poiché si tratta di una funzione ricorsiva, è f=necessario includere il nome
Giuseppe,

1
Ho trovato questa sfida piuttosto difficile con un linguaggio a indice 1 senza rotazioni di array; questo è potenzialmente 1-3 byte più corto con un whileciclo, credo.
Giuseppe,


il mio precedente 115 byte non era valido poiché entrambi abbiamo dimenticato la f=parte della funzione ricorsiva. :(
Giuseppe

Ho aggiornato il vecchio punteggio e il nuovo punteggio per riflettere la ricorsività :) Con il ciclo 'while' ho golfato altri 4 byte usando la scansione.
Segna il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.