Salta come una rana!


12

Dato un array di numeri interi non negativi, il tuo compito è di mantenerne solo alcuni elementi, come descritto di seguito.

  • Diciamo che l'array è [1, 3, 2, 4, 11, 5, 2, 0, 13, 10, 1].

  • Prima ottenere il primo elemento della matrice, n. Conserva i primi nelementi e scarta il successivo (scarta il n+1th). Il nuovo array è [1, 2, 4, 11, 5, 2, 0, 13, 10, 1].

  • Quindi, prendi l'elemento che segue quello rimosso e fai esattamente la stessa cosa. Riapplicando il processo, otteniamo[1, 2, 11, 5, 2, 0, 13, 10, 1]

  • Ripetete il processo fino ad arrivare al di fuori dei limiti dell'array / non ci sono elementi rimasti nell'array. Ci fermiamo perché 11è maggiore della lunghezza dell'array.

  • Ora dovresti produrre il risultato.

L'input / output può essere preso / fornito in qualsiasi forma standard. La matrice non sarà mai vuota e conterrà solo numeri interi non negativi. Sono vietate tutte le scappatoie standard.

Questo è quindi vince il codice più breve in byte!


Casi test

Ingresso -> Uscita

[1, 2, 3, 4, 5] -> [1, 3, 4]

[6, 1, 0, 5, 6] -> [6, 1, 0, 5, 6]

[1, 3, 2, 4, 11, 5, 2, 0, 13, 10, 1] -> [1, 2, 11, 5, 2, 0, 13, 10, 1]

[2, 2, 2, 2, 2, 2] -> [2, 2]

[1, 2, 3, 1, 2, 3, 1, 2, 3] -> [1, 2]

[3, 1, 2, 4, 0] -> [] *

* L'ultimo caso di test comporta 0, quindi ho deciso di pubblicare il processo in modo che sia più chiaro:

[3, 1, 2, 4, 0] --> [3, 1, 2, 0] --> [1, 2, 0] --> [1, 0] --> [0] --> [] )

( Ispirato da questa sfida di Erik the Outgolfer )


Ho scritto tutti i casi di test completamente a mano, per favore avvisami se pensi che ci sia un errore!

1
Perché viene 2rimosso nel primo passaggio anziché 3?
Leaky Nun,

@LeakyNun Il mio errore. Correzione. Ping me se ho fatto altri errori

caso di prova suggerito:[1, 2, 3, 1, 2, 3, 1, 2, 3]
Rod

1
Quindi, per chiarire, quando si passa al nuovo " n", si parte sempre dall'inizio dell'array per mantenere gli nelementi? Non (come pensavo a prima vista) mantenere nelementi in cui il primo elemento è quello nche stai valutando?
Brian J,

Risposte:



5

JavaScript (ES6), 45 byte

f=(a,k=0,x=a[k])=>1/x?f(a.splice(x,1)&&a,x):a

Casi test


4

Haskell , 50 byte

g.pure.(0:)è una funzione anonima che accetta e restituisce un elenco di messaggi Int, usa come (g.pure.(0:))[1,2,3,4,5].

g.pure.(0:)
g(a,_:b:c)=g$splitAt b$a++b:c
g(a,_)=a

Provalo online!

Come funziona

  • La funzione gaccetta un argomento tupla che rappresenta un elenco diviso. aè l'elenco di elementi iniziali conservato nel passaggio precedente, _è l'elemento da scartare, bè l'elemento successivo da utilizzare come lunghezza ed cè gli elementi rimanenti.
    • Se ci sono abbastanza elementi nella seconda parte della tupla per selezionare a b, allora viene eseguita una nuova divisione e si gricorre. Altrimenti, si ferma con ail risultato.
  • La funzione anonima g.pure.(0:)inizia tutto chiamando gcon la tupla ([],0:l), dove si ltrova l'input e 0viene immediatamente scartata g.
    • purequi usa l' Applicativeistanza per le tuple (binarie) e con il tipo di risultato ([Int],[Int])inserisce convenientemente il suo argomento come secondo elemento in una tupla con []come primo elemento.



2

Java 8, 68 byte

Questo lambda accetta un mutabile List<Integer>(supporta remove(int), ad esempio ArrayList). L'output è input mutato. Assegna a Consumer<List<Integer>>.

l->{for(int i=0,f=0;i<l.size();f^=1)i=f>0?l.remove(i)*0+i:l.get(i);}

Provalo online

Il flusso di controllo per questo problema è molto fastidioso. Ogni iterazione dobbiamo rimuovere un elemento e riportare l'elemento nella posizione successiva, ed entrambe queste operazioni richiedono un controllo della portata (ed entrambe possono innescare il completamento del programma). Una strategia è quella di eseguire entrambe le operazioni in un'unica iterazione a ciclo continuo, con l'aggiornamento dell'indice protetto dal proprio controllo della portata. Un'altra strategia, che si è rivelata più breve, è quella di alternare tra le operazioni ogni iterazione del ciclo, che è ciò che fa questa soluzione.


1

APL (Dyalog Classic) , 32 byte

1∘{n∇⍣(n≤≢w)⊢w←⍵/⍨(n1+⍺⊃⍵)≠⍳≢⍵}

Spiegazione

1∘{                             } bind 1 as starting left argument (⍺)
                             ⍳≢⍵  generate indexes for right argument (⍵)
                   (n1+⍺⊃⍵)      n is 1+item at position  
              w←⍵/⍨              w is  with item at n removed
   n∇⍣(n≤≢w)⊢                     recurse with n as left and w as right arg if n <= length of w

Provalo online!



1

Haskell, 99 byte (88 senza rientro)

f x y
 |y>=l=f x$l-1
 |e>=l=x
 |True=f (take e x ++ drop (1+e) x) e
 where e=x!!y
       l=length x

Probabilmente potrei salvare 1 byte usando "1 = 1" invece di "Vero", anche forse i due spazi vicino a "++" potrebbero essere rimossi
Giacomo Tecya Pigani,

1

VI, 31 25 byte

O@0kdd<C-v><C-a>Y<C-v><C-x>gg@a<Esc>"add<C-a>Y<C-x>@a

<C-?>corrisponde Control + ?, e <Esc>di Escapeovviamente. Ognuno di questi conta per 1 byte (vedi meta ).

Ingresso

Il file di input deve contenere 1 numero intero per riga + 1 riga vuota alla fine, ad esempio:

1
2
3
4
5
⁣

Possiamo vedere ogni riga del file di input come un elemento array, come, ad esempio 1 :: 2 :: 3 :: 4 :: 5 :: [], in alcune lingue (ad esempio caml).

Lanciare

Puoi avviare vi con il seguente comando e digitare il tratto tratto per tratto:

vi -u NONE input

Puoi anche usare questo one-liner:

vi -u NONE -c ':exec "norm O@0kdd\<C-v>\<C-a>Y\<C-v>\<C-x>gg@a\<Esc>\"add\<C-a>Y\<C-x>@a"' -c ":w output" -c ':q' input

Ciò dovrebbe produrre un file outputcon il risultato corretto da un file di input input.

spiegazioni

Per introdurre la soluzione, presenterò prima una soluzione di 19 byte che funziona solo per array senza 0. Questa soluzione utilizza una macro ricorsiva, utilizzata con poche modifiche nella soluzione finale:

Yqa@0ddYgg@aquggY@a

Spiegazione di una soluzione parziale

Y                       # yank first line (first integer + line break) to "0 register
 qa                     # start recording a macro ("a register)
   @0                   # jump n lines, where n is the content of the "0 register
     dd                 # delete the current line (n+1th line)
       Y                # yank current line (integer after the previously deleted line)
        gg              # go back to the first line
          @a            # recurse on macro "a"
            q           # finish recording the macro
             u          # cancel modifications done by the execution of the macro
              gg        # go back to the first line
                Y@a     # apply the recorded macro with first parameter equal to the first integer

Il trucco qui è usare il "0registro per memorizzare l'intero corrente (e l'interruzione di linea, molto importante). Pertanto, il comando @0consente di saltare le nlinee (chiamare nil valore di "0). Se il salto supera il numero di righe nel file, la macro fallirà, quindi il programma si fermerà (al di fuori dei limiti dell'array, come richiesto).

Ma questa soluzione non funziona se l'input contiene 0. In effetti, se il "0valore del registro è uguale 0, allora @0salterà una riga (a causa dell'interruzione di riga), non 0come ci piaceva. Quindi il comando successivo ( dd) non cancellerà il numero intero 0, ma il primo (non corretto).

Una soluzione valida per gestire 0è incrementare sempre il numero intero prima di strapparlo e diminuirlo subito dopo. Pertanto, il @0comando salterà le n+1righe ( nè l'attuale numero intero che è stato incrementato). È kquindi necessario un comando per passare alla riga n(riga precedente). Usando questo trucco, è necessaria una riga vuota alla fine del file di input, per evitare di saltare all'esterno dell'array (quindi, terminando il programma), poiché ora saltiamo sempre le n+1linee, prima di saltare alla riga precedente.

Spiegazione della soluzione finale

O                                                       # insert a new line at the beginning of the file, enter insert mode to write the macro content
 @0                                                     # jump n lines                                                       
   k                                                    # go to the previous line
    dd                                                  # delete this line
      <C-v><C-a>                                        # type Control+A (C-v is needed because we are in insert mode) to increment the current integer
                Y                                       # yank the incremented integer
                 <C-v><C-x>                             # decrement the current integer
                           gg                           # go to the first line
                             @a                         # recurse on macro "a"
                               <Esc>                    # exit insert mode : at this step, the first line of the file contains the macro content @0kdd^AY^Xgg@a
                                    "add                # copy @0kdd^AY^Xgg@a line to the register "a and delete the line
                                        <C-a>           # increment the first integer
                                             Y          # yank it (into "0)
                                              <C-x>     # decrement the first integer
                                                   @a   # apply macro in a" (initial @0 will jump n+1 lines, since we incremented the first integer before calling the macro)

Scrivere il contenuto della macro all'interno del file prima di registrarlo consente di salvare alcuni byte:

  • evita di scrivere qa...qe annullare tutte le modifiche dopo la registrazione
  • evita :let @a="...")

Le modifiche

1 #

  • scrivere il contenuto della macro sulla prima riga (anziché sull'ultima riga)
  • cambia input (1 riga vuota alla fine)
  • aggiungere una riga per eseguire il test nella riga di comando

0

Pyth, 32 byte

VlQIgNlQBK@QNI!K=QYBIgKlQB.(QK;Q

Provalo online


Pyth può essere molto più elegante di così :) #VlQ.(Q@QN;Qfa il lavoro in 12 byte, e sono abbastanza sicuro che possa essere giocato a golf ancora di più
Dave

Mantenendo l'approccio Pythonic della vecchia scuola si può fare W<Zl=Q+<Q@QZ>Qh@QZ=Z@QZ)Q(25). L'approccio di pizzakingme è molto meglio però.

4
@KaranElangovan niente di cui scusarsi, stanno solo cercando di aiutarti.
Leaky Nun,

1
Fissato per il caso di test finale, si esce a 15 byte: #VlQ .(Q@QN)%;Q. Il feedback dei golfisti di Pyth sarebbe il benvenuto, sto ancora imparando anche!
Dave,

2
Questo approccio non è valido. Non solo non stampa solo il risultato, ma fallisce anche i casi di test (almeno il secondo ultimo). Puoi per favore cancellare questa risposta / ripararla?

0

C # (.NET Core) , 74 byte

n=>{for(int i=n[0];i<n.Count;){n.RemoveAt(i);i=i<n.Count?n[i]:n.Count+1;}}

Provalo online!

Questo contiene un elenco di ints e lo modifica. Ho visto alcune risposte Java che aggirano le importazioni usando il nome completo nella definizione dell'argomento Lambda. Se ciò non è consentito, posso rimuovere questa risposta.


Se ti riferisci all'omissione dei tipi di parametro nelle definizioni lambda, è consentito .
Jakob,

@Jakob Lo capisco. Mi sento solo un po 'sporco per System.Collections.Generic.List<int>invece di using System.Collections.Generice aggiungendolo al conteggio dei byte. Ma suppongo che non sia diverso dall'uso di un array.
jkelm,

Oh, capisco. Bene, puoi usare usingse vuoi; fintanto che la lambda stessa non si basa sull'istruzione non è necessario includerla nel conteggio dei byte. Personalmente uso sempre nomi completi nel codice di test solo in modo che sia chiaro e facilmente verificabile ciò che importa utilizzando lambda.
Jakob,

0

R , 64 53 byte

f=function(a,i=1,d=a[i]+1)"if"(is.na(d),a,f(a[-d],d))

Funzione ricorsiva. Ha un input obbligatorio a, l'elenco da saltare. iè l'indice del numero di elementi da saltare (impostazione predefinita 1), ed dè l'indice dell'elemento successivo dopo la rimozione del valore richiesto, che è anche l'indice dell'elemento da rimuovere. Restituisce numeric(0), un vettore vuoto, per output vuoto.

Provalo online!

Ungolfed:

f <- function(a, i = 1, d = a[i] + 1) {
  if(is.na(d)) {   # d is NA if and only if a[i] is out of bounds
    a
  } else {
    f( a[-d], d, a[d] + 1 )   # a[-d] is a with the item at index d removed
  }
}
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.