Ripara le gamme


30

Dato un input di un elenco di numeri interi positivi con alcuni sostituiti con 0, output dell'elenco con i numeri mancanti che sono stati cambiati in 0sostituiti.

Caratteristiche dell'elenco di input:

  • L'elenco avrà sempre una lunghezza di almeno 2.

  • Definiamo la lista di input come ae la "lista originale" (cioè la lista prima che i numeri fossero sostituiti con 0s) come b. Per qualsiasi n, a[n]è b[n]o 0.

  • Per qualsiasi n, b[n]è b[n-1] + 1o b[n-1] - 1. Cioè, i numeri in bcambieranno sempre per 1ogni indice dal precedente. Il primo elemento è, ovviamente, esente da questa regola.

  • Per ogni corsa di zeri a a(cioè, elementi consecutivi sostituiti con 0), con xrappresenta l'indice di inizio della corsa e y che rappresenta la fine, a[x-1]ad a[y+1]saranno sempre unicamente aumentando o diminuendo esclusivamente. Pertanto, ci sarà solo un modo possibile per riempire gli zeri.

    • Ciò significa anche che né il primo né l'ultimo elemento dell'array possono essere zero.

In termini più semplici, per compilare una serie di zero, è sufficiente sostituirlo con un intervallo dal numero precedente al numero che lo segue. Ad esempio, un input di

1 2 0 0 0 6 7

deve produrre

1 2 3 4 5 6 7

Dato che si tratta di , vincerà il codice più breve in byte.

Casi test:

In                      Out
-----------------------------------------------------
1 0 0 0 5 6 0 4 0 0 1 | 1 2 3 4 5 6 5 4 3 2 1
7 6 0 0 3 0 0 0 7 0 5 | 7 6 5 4 3 4 5 6 7 6 5
1 0 3 0 5 0 3 0 5 0 7 | 1 2 3 4 5 4 3 4 5 6 7
14 0 0 0 0 0 0 0 0 23 | 14 15 16 17 18 19 20 21 22 23

Invece del 0nostro programma può assumere un altro valore come null?
Downgoat,

@Downgoat No, i numeri mancanti devono essere indicati come 0.
Maniglia della porta

Risposte:


15

JavaScript (ES6), 72 66 64 54 53 byte

12 byte salvati grazie a @Neil!

Salvato 1 byte grazie a @IsmaelMiguel

a=>a.map((l,i)=>l?b=l:b+=a.find((q,r)=>r>i&&q)>b||-1)

Abbastanza buono per JavaScript.


Provalo online (tutti i browser funzionano)

Spiegazione

a=>  // Function with arg `a`
  a.map((l,i)=>  // Loop through input
    l?             // If nonzero
      b=l          // Set `b` to current number
    :a.find((q,r)=>r>i&q) // Otherwise look for the next nonzero number
     >b?           // If it's increased since nonzero last number   
       ++b:--b)    // Increasing? increase `b` (the previous nonzero number)
                   // otherwise decrease `b`

1
Penso che a.find((q,r)=>r>i&&q)>b?++b:--bsia lo stesso dib+=a.find((q,r)=>r>i&&q)>b||-1
Ismael Miguel

@IsmaelMiguel è intelligente, grazie!
Downgoat

Prego. Sono contento che abbia funzionato per te.
Ismael Miguel

Penso che puoi sostituire && con solo & (ho appena notato che ne hai uno e nella spiegazione e due nella risposta)
Charlie Wynn,

7

MATL , 11 12 byte

fGXzGn:3$Yn

Funziona con la versione corrente (13.0.0) del linguaggio / compilatore.

Provalo online!

f        % implicitly input array. Indices of nonzero elements (*)
GXz      % push input and get its nonzero elements (**)
Gn:      % vector [1,2,...,n], where n is input length (***)
3$Yn     % interpolate at positions (***) from data (**) defined at positions (*)

7

Haskell, 68 61 58 byte

g(a:b:r)=[a..b-1]++[a,a-1..b+1]++g(b:r)
g x=x
g.filter(>0)

Esempio di utilizzo: g.filter(>0) $ [7,6,0,0,3,0,0,0,7,0,5]-> [7,6,5,4,3,4,5,6,7,6,5].

Come funziona: rimuovi gli zeri dall'input, quindi chiama g. Sia ail primo e bpoi il secondo elemento dell'elenco rimanente. Concatena gli elenchi da averso l'alto b-1e averso il basso b+1(uno di questi sarà vuoto) e una chiamata ricorsiva cona interrotta.

Modifica: @Zgarb ha salvato 3 byte. Grazie!


6

Mathematica, 59 byte

#//.{a___,x_,0..,y_,b___}:>{a,##&@@Range[x,y,Sign[y-x]],b}&

Caso di prova

%[{1,0,3,0,5,0,3,0,5,0,7}]
(* {1,2,3,4,5,4,3,4,5,6,7} *)

4

Perl, 47 45 44 39 37 byte

Include +1 per -p

s%\S+%$p+=/\G(0 )+/?$'<=>$p:$&-$p%eg

Si aspetta l'elenco su stdin. Esempio: echo 1 0 3 0 1 | perl -p file.pl


Vedo alcune copie incollate qui .. ;-) Ben fatto tra l'altro.
Kenney,

3

Gelatina, 12 11 byte

ḢWW;ḟ0Ṫr¥\F

Provalo online!

Versione alternativa, 8 byte (non competitiva)

Sfortunatamente, Jelly's popnon è stato lanciato su iterable, nell'ultima versione che precede questa sfida. Questo problema è stato risolto e quanto segue funziona nella versione corrente.

ḟ0Ṫr¥\FḊ

Provalo online!

Come funziona

ḢWW;ḟ0Ṫr¥\F  Main link. Input: A (list)

Ḣ            Pop the first element of A. Let's call it a.
 WW          Yield [[a]].
   ;         Concatenate with the popped A.
             This wraps the first element of A in an array.
    ḟ0       Filter; remove all zeroes.
        ¥    Create a dyadic chain:
      Ṫ        Pop the last element of the left argument.
       r       Call range on the popped element and the right argument.
         \   Reduce the modified A by this chain.
          F  Flatten the resulting list of ranges.

Nella versione alternativa, ḢWW;diventa superfluo. Tuttavia, poiché il primo elemento viene convertito in iterabile prima del pop-up, non viene effettivamente modificato. Il finale rimuove il duplicato del primo elemento.


3

Retina, 39 34 31 byte

3 byte salvati grazie a @Martin.

+`1(1*) (?= +((1)\1)?)
$0$1$3$3

Accetta input e fornisce output in modo unario.

Il codice riempie iterativamente ogni posto vuoto (0) con previous_number - 1 + 2 * if_next_nonzero_number_bigger. previous_number - 1è$1 ed if_next_nonzero_number_biggerè $3.

Con l'I / O decimale il codice è lungo 51 byte, come puoi vedere nell'interprete online con tutti i casi di test .


Puoi salvare un altro byte omettendo il primo 1nel lookahead.
Martin Ender,

@ MartinBüttner Right, modificato.
randomra,

2

GNU Sed (con exec estensione usando bash), 61

Il punteggio include +1 per l' -ropzione di sed.

:
s/( 0)+ /../
s/\w+..\w+/{&}/
s/.*/bash -c 'echo &'/e
/ 0/b
  • Trova corse di 0 s e sostituiscile..
  • Metti le parentesi graffe attorno ai numeri degli endpoint per creare un'espansione di parentesi bash come {1..4}per gli endpoint locali. La bellezza delle espansioni di bash brace qui è che la sequenza generata funzionerà sempre nella giusta direzione, indipendentemente dal fatto che l'inizio o la fine siano più grandi.
  • Utilizzare l' eopzione per ils comando per chiamare bash per valutare questa espansione del controvento
  • Se 0vengono trovati altri messaggi, tornare all'inizio.

Ideone.


2

Python 2, 195 111 byte (grazie Alex !)

t=input()
z=0
for i,e in enumerate(t):
 if e:
  while z:t[i-z]=e+z if l>e else e-z;z-=1
  l=e
 else:z+=1
print t

Input: deve essere un [list]ints
Output: [list]of ints


Mi dispiace per quello! Fisso. Grazie per il testa a testa.
vageli,

Nessun problema. Bella soluzione. :) Puoi farlo arrivare a 112 byte usando questo , che è il tuo stesso approccio, solo un po 'di più. Abbiamo anche una raccolta di suggerimenti per giocare a golf in Python qui .
Alex A.

1

Perl, 85 82 byte

include +1 per -p

s/(\d+)(( 0)+) (\d+)/$s=$1;$e=$4;$_=$2;$c=$s;s!0!$c+=$e<=>$s!eg;"$s$_ $e"/e&&redo

Si aspetta l'elenco su stdin. Esempio: echo 1 0 3 0 1 | perl -p file.pl.

Questo utilizza una regexp nidificata. Leggibile:

s/(\d+)(( 0)+) (\d+)                  # match number, sequence of 0, number
 /
    $s=$1;                            # start number
    $e=$4;                            # end number
    $_=$2;                            # sequence of ' 0'
    $c=$s;                            # initialize counter with start number
    s!0! $c += $s <=> $e !eg          # replace all 0 with (in|de)cremented counter
    "$s$_ $e"                         # return replacement
 /e
&& redo                               # repeat until no more changes.

1

Python 2, 92 88 byte

(Rimossa variabile intermedia)

t=filter(bool,input())
print sum([range(o,p,cmp(p,o))for o,p in zip(t,t[1:])],[])+t[-1:]

1

Pyth, 17 byte

u+G+treGHHfTtQ[hQ

Il modo in cui funziona:

u                 reduce
              [hQ     seed: the first element of input, in a list
                      iterable:
          tQ              all except the first element of input
        fT                remove if 0
                      lambda: G is the list to be returned, H is the current item
 +G                       append to return list
    reGH                  a range from the last element of the return list and the current item
   +                      concatenated with
        H                 the last item (this step forms a bidirectional inclusive list)

In altre parole: tutti gli zero vengono rimossi dall'input, quindi viene inserito un intervallo esclusivo tra ogni elemento. Questo intervallo ha lunghezza zero per gli elementi distanti solo uno.



1

Vim: 231 comandi chiave

Nota che qualsiasi ^ che precede un carattere significa che dovresti mantenere il controllo durante la digitazione di quel carattere

mbomayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0wmbyiwo@f @d^V^[@z ^["fc0"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0dd`bAe^[0@e 

Passaggi per poter eseguire anche questo!

  1. Copia la linea in Vim
  2. genere :s/\^V/<Ctrl-V><Ctrl-V>/g e premi Invio (i due s dovrebbero darti un blu ^ V)
  3. genere :s/\^R/<Ctrl-V><Ctrl-R>/g e premi Invio (dovresti vedere blu ^ Rs ora)
  4. genere :s/\^X/<Ctrl-V><Ctrl-X>/g e premi Invio (dovresti vedere blu ^ Xs ora)
  5. genere :s/\^O/<Ctrl-V><Ctrl-O>/g e premi Invio
  6. genere :s/\^A/<Ctrl-V><Ctrl-A>/g e premi Invio
  7. genere :s/\^\[/<Ctrl-V><Ctrl-[>/g e premi Invio (questo comando è leggermente diverso perché avevo bisogno di sfuggire al [)
  8. genere 0"yy$ . Il comando è ora memorizzato nel registro y
  9. Imposta l'input su una riga ed esegui con @y

Se qualcuno conosce un modo migliore per condividere il comando, per favore fatemelo sapere. So che è lungo, ma è il migliore che potrei inventare.

Input Output

La stringa di input deve essere sola su qualsiasi riga del file. 1 0 0 4 3 0 0 0 7

L'output sovrascriverà semplicemente la stringa di input 1 2 3 4 3 4 5 6 7

Spiegazione

Algoritmo

  1. Inizia con un numero diverso da zero, assicurati che non sia l'ultimo numero
  2. Trova il prossimo numero diverso da zero
  3. Fai la differenza. Se la risposta è negativa, è necessario diminuire per riparare l'intervallo, altrimenti incrementare per riparare l'intervallo.
  4. Torna al primo carattere e sostituisci ogni zero incrementando / decrementando il numero precedente.
  5. Ripeti fino ad arrivare all'ultimo personaggio

Macro utilizzate

@e - Controlla la fine. All'ultimo numero verrà aggiunto un e. Se il numero sotto il cursore ha una e alla fine, elimina e e termina l'esecuzione. Altrimenti, avviare un ciclo di interpolazione con @b.

mbyiwo^R"Exe@b^[0fel"ty2ldd`b@t

@b - Inizia il ciclo di interpolazione. Salvare il numero sotto il cursore per un'operazione di sottrazione (@s) e quindi trovare il termine successivo diverso da zero (@f)

mayiwo^R"^V^X ^["sy0dd`a@f

@s - Memorizza il comando di sottrazione da usare in @d. È semplicemente (val)^Xdove(val) trova il numero all'inizio della fase di interpolazione. Questo è impostato dal comando @b.

@f - Trova il prossimo termine diverso da zero. Scrivi il valore corrente nel registro senza nome, quindi scrivi @f @dnella riga successiva, quindi esegui @z. Questo ripeterà questo comando se il numero è zero ed eseguirà @d se non lo è.

wmbyiwo@f @d^[@z

@z - Esegui condizionale se il registro senza nome è 0. Questo comando prevede due comandi su una nuova riga nel formato command1 command2. Se il registro senza nome è 0, command1viene eseguito, altrimenti command2viene eseguito. Si noti che nessuno dei comandi può contenere spazi.

 IB0 B^R" ^OWB0 ^OA B0^[0*w"tyiWdd`b@t`

@t - Registro comandi temporaneo. Memorizza vari comandi per un breve periodo prima di eseguirli. Utilizzato principalmente nelle istruzioni if.

@d - Determina la direzione di interpolazione. Sottrae il primo numero nella sequenza dal numero sotto il cursore (usando @s). Se il risultato è negativo, l'interpolazione deve diminuire in modo che ^ X venga salvato in @a. Altrimenti, dovremmo incrementare in modo che ^ A venga salvato in @a. Una volta salvato, torna all'inizio di questo ciclo di interpolazione ed esegui @i per interpolare effettivamente

yiwo^V^X^R"^[0l@sa^V^A-^[0f-"ayhdd`a@i

@a - Memorizza ^Ao^X per aumentare o diminuire durante la fase di interpolazione. Questo è impostato dal comando @d.

@i - Interpolare. Copia il numero nella posizione corrente su @x e passa al numero successivo. Se quel numero è zero, sostituirlo con @x ed eseguire @a per modificarlo correttamente su o giù, quindi ripetere questo comando. Se il numero non è zero, abbiamo raggiunto la fine di questo ciclo di interpolazione. Uno nuovo dovrebbe essere avviato con questo numero come inizio, quindi esegui @e per verificare la fine ed esegui di nuovo.

"xyiwwmbyiwocw^V^Rx^V^[@a@i @e^[@z

@x - Registro di archiviazione temporaneo. Utilizzato nel comando interpolate (@i)

Abbattere i tasti

mbo :Set b mark to current position and open a new line below to write macros
mayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0 :Write to @b and reset line

yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0 :Write to @d and reset line

mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0 :Write to @e and reset line

wmbyiwo@f @d^V^[@z ^["fc0 :Write to @f and reset line

"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0 :Write to @i and reset line

IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0 :Write to @z and reset line

dd`b :Delete this line and move cursor back to original line

Ae^[ :Append an e to the last number

0@e  :Move to the beginning of the line and run

0

Python 3.5, 159 byte

una soluzione ricorsiva

def f(s):
 h=s[0]
 g=lambda s,h,v:h*(h[-1]==s[0])if len(s)==1else(g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v))*(s[0]==0 or h[-1]==s[0])
 return g(s,[h],1)

Ungolfed

def f(s):
    h=s[0]
    def g(s,h,v):
        if len(s)==1:
            if h[-1]!=s[0]:
                r=[]
            else:
                r=h
        else:
            if s[0]==0:
                r=g(s[1:],h+[h[-1]+v],v)
            elif h[-1]!=s[0]:
                r=[]
            else:
                r=g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v)
        return r
return g(s,[h],1)

Nella soluzione golfizzata, sostituisco le condizioni usando il fatto che h*True=heh*False=[]

Risultato

>>> f([7, 6, 0, 0, 3, 0, 0, 0, 7, 0, 5])
[7, 6, 5, 4, 3, 4, 5, 6, 7, 6, 5]

0

Perl 6 , 54 byte

{$_=$^a;1 while s/:s(\d+) 0 + (\d+)/{+~$0...+~$1}/;$_}

0

MATLAB, 39 38 37 byte

@(a)interp1(find(a),a(a>0),find(a/0))

Funzione anonima che si interpola linearmente tra i punti in a. find(a)è una matrice di indici di elementi diversi da zero ae a(a>0)sono i valori positivi. 1 byte salvato grazie al suggerimento di un amico >piuttosto che ~=.

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.