Non ho mai visto quel numero prima!


31

Scrivere un programma che passa attraverso una stringa di caratteri che non sono spazi (si potrebbe supporre che essi sono cifre 0a 9, ma nulla nel modo in cui devono essere elaborati dipende da questo) e aggiunge gli spazi secondo le seguenti regole.

  1. Lascia che il token corrente sia la stringa vuota e i token precedentemente emessi siano un set vuoto.
  2. Scorrere i caratteri della stringa. Per ogni personaggio, prima aggiungi il personaggio al token corrente. Quindi, se il token corrente non è già nel set di token precedentemente emessi, aggiungi il token corrente a quel set e lascia che il nuovo token corrente sia la stringa vuota.
  3. Se quando si raggiunge la fine della stringa il token corrente è vuoto, emettere i token precedentemente emessi in ordine di emissione, separati da un carattere spazio. Altrimenti restituire la stringa originale alla lettera.

Ingresso

L'ingresso allo STDIN dovrebbe essere una sequenza di cifre.

Produzione

Il programma dovrebbe stampare il risultato come specificato al passaggio 3.

Campioni

Ingressi campione

2015
10101010
4815162342
101010101010
3455121372425
123456789101112131415
314159265358979323846264338327950288419716939937

Output di esempio

2 0 1 5
10101010
4 8 1 5 16 2 3 42
1 0 10 101 01 010
3 4 5 51 2 1 37 24 25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3 1 4 15 9 2 6 5 35 8 97 93 23 84 62 64 33 83 27 95 0 28 841 971 69 39 937

Questo è il golf del codice, quindi si applicano le regole CG standard. Vince il programma più breve in byte.

(Si prega di richiedere eventuali chiarimenti nei commenti. Sono ancora nuovo a questo. Grazie!)


10
4815162342Vedo cosa hai fatto lì, Brotha .
Fatalizza il

16
Voce OEIS proposta: numeri che sono divisi in almeno due segmenti da questo processo.
Martin Ender,

3
@IsmaelMiguel Il passaggio 5 (come qualsiasi altro passaggio) può avanzare di una cifra alla volta. Una volta che hai 1 0 10 , la prossima iterazione troverà 1(già utilizzato), quindi avanzane uno per trovare 10(già utilizzato), quindi avanzane uno per trovare 101, che è nuovo e verrebbe "aggiunto". Quindi aggiungerebbe uno spazio e arriveresti a uno nuovo 0, che è già stato usato, ma è qui alla fine della stringa. Pertanto, l'output sarebbe 1 0 10 101 0, il che non è valido ( 0viene ripetuto) e lo script deve quindi solo generare la stringa di input. Potrebbe fare solo 1010se 101fosse già stato usato.
Janus Bahs Jacquet,

3
@kasperd No If a unique number cannot be formed at the end of the string, then the input should be printed verbatim10101010 non può essere diviso, quindi viene stampato così com'è.
edc65,

1
Ma quando si entra nel passaggio 5, lo spazio sarebbe dopo il 1, che sarebbe una ripetizione. Quindi, invece, ti sposti a destra uno nello spazio 5, quindi ti sposti di nuovo a destra nel passaggio 4 e inserisci nuovamente il passaggio 5 e crei 101.
Peter Taylor,

Risposte:


9

Pyth, 22 byte

 faW!}=+kTYY~kdz?tkzsY

Lo spazio principale è importante.


13

Retina , 68 61 byte

+`\b(\w+?)(?<!\b\1 .*)(\w+)$
$1 $2
(?=.* (.+)$(?<=\b\1 .+)) 
<empty>

<empty>è una linea vuota. Nota lo spazio finale sulla riga 3. Puoi eseguire il codice sopra da un singolo file con il -sflag.

Spiegazione

+`\b(\w+?)(?<!\b\1 .*)(\w+)$
$1 $2

Questo primo passo implementa le regole da 1 a 6. È una sostituzione regex che viene applicata ripetutamente fino a quando la stringa non smette di cambiare (ecco a cosa +serve). In ogni passaggio aggiungiamo un singolo spazio nella stringa da sinistra a destra (seguendo le regole della sfida). Il regex corrisponde alla stringa di cifre più corta che non è stata visualizzata nella parte già elaborata della stringa. Ci assicuriamo che stiamo osservando un prefisso della stringa rimanente con la parola limite \be verificando che possiamo raggiungere la fine della stringa senza passare spazi (\w+)$. Quest'ultimo assicura anche che eseguiamo solo una sostituzione per passaggio.

(?=.* (.+)$(?<=\b\1 .+)) 
<empty>

Questo corrisponde a qualsiasi spazio (che si trova alla fine della regex), a condizione che l'ultimo segmento della stringa sia uguale a qualsiasi altro segmento della stringa e li sostituisca con la stringa vuota. Ossia, annulliamo il primo passaggio se risultava in un segmento finale non valido, implementando la regola 7.


11

Pyth, 24 23 byte

VzI!}=+kNYaY~k"";?kzjdY

Provalo qui .

VzI!}=+kNYaY~k"";?kzjdY    Implicit: z=input(), k='', Y=[], d=' '
Vz              ;          For N in z:
     =+kN                    Append N to k
  I!}    Y                   Is the above not in Y?
          aY k               Append k to Y
            ~k""             After append, reset k to ''
                 ?k        Is k truthy (i.e. not '')
                   z       Print original input
                    jdY    Otherwise print Y joined on spaces

Grazie a @FryAmTheEggman per aver salvato un byte: o)


@FryAmTheEggman Una buona telefonata, sono rimasto piuttosto preso nel tentativo di preservare il valore originale di k
Prese il

8

Python 3, 92 byte

i,n,*o=input(),""
for c in i:n+=c;o,n=[o+[n],o,"",n][n in o::2]
print([" ".join(o),i][n>""])

Fondamentalmente una versione fortemente giocata a golf della soluzione di @ Willem.


[" ".join(o),i][n>""]
FryAmTheEggman,

@FryAmTheEggman Ah bene, ci avevo provato bool(n)ma non ci avevo pensato n>"".
orlp,

6

Python 3, 100 99 byte

o=[];n="";i=input()
for c in i:
 n+=c
 if not n in o:o.append(n);n=""
print(i if n else" ".join(o))

2
Ho corretto il conteggio dei byte. Inoltre, è necessario rimuovere lo spazio da else ".
mbomb007,

1
Alcuni golf comuni Inoltre, il tuo punteggio originale era di 100 byte, credo.
FryAmTheEggman,

Figo, grazie! Non sapevo che lo spazio dopo "else" potesse essere rimosso. Un altro giorno vissuto, un altro giorno imparato :)
Willem,

5

Brachylog , 91 byte

:_:_{h:0<|bhN,?hh:NrcH,?hB(l1,-1=A;BbA),?rhL:I(mH:Ar:[L]c:1&;:[H]:\"~w \"w,L:[H]c:_:Ar:1&)}

Questo mi ha fatto capire che ci sono molte cose sulla sintassi che devo cambiare ...

Spiegazione

:_:_              § Creates a list [Input,[],[]] 
{...}             § Define a new predicate between the brackets and call it with the previous list as input
h:0<              § If the head of the input is negative, stop
|                 § Else
bhN,              § Second element of Input is called N
?hh:NrcH,         § N concatenated with the first element of Input is H
?hB(l1,-1=A;BbA), § Remaining digits A are either -1 if there's only one digit left or all the digits but the head otherwise
?rhL:I            § List of used integers is called L
(
   mH:Ar:[L]c:1&  § If H is already in L, call the predicate with input [A,H,L]
   ;              § Else
   :[H]:\"~w \"w, § Print H followed by a space
   L:[H]c:_:Ar:1& § Call the predicate with input [A,[],M] where M is L with H appended to it
)

4

CJam, 26 byte

LLq{+_a2$&{a+L}|}/:X+X!S**

Provalo qui.

Spiegazione

L        e# Push an empty array to keep track if the previous segments.
L        e# Push an empty array to build the current segment.
q{       e# For each character in the input...
  +      e#   Add it to the current segment.
  _a2$&  e#   Duplicate and check if it's already in the segment list.
  {      e#   If not...
    a+L  e#     Add it to the list and push a new empty array for the next segment.
  }|
}/
:X+      e# Store the trailing segment in X and add it's *characters* to the list.
         e# For valid splittings, this trailing segment will be empty, so that the
         e# list remains unchanged.
X!       e# Push X again and take the logical NOT.
S*       e# Get that many spaces, i.e. 1 for valid segments and 0 otherwise.
*        e# Join the list with this string between elements.

3

JavaScript (ES6), 109

Il mio formato di output non è esattamente lo stesso dei campioni di output nel questioin (c'è uno spazio iniziale). Non lo vedo come un difetto, poiché il formato di output non è specificato (solo il programma dovrebbe stampare il numero dopo il numero ... )

Prova a eseguire lo snippet di seguito in un browser compatibile con EcmaScript 6. Sviluppato con Firefox, testato e funzionante con l'ultimo Chrome.

/* Test: redirect console.log */ console.log=x=>O.innerHTML+=x+'\n';

F=s=>{for(z=s,b=l=o=' ';s[+l];)~o.search(b+(n=s.slice(0,++l)+b))||(s=s.slice(l),o+=n,l=0);console.log(s?z:o)}

/* Test cases */
test = [
  '2015',
,'10101010'
,'4815162342'
,'101010101010'
,'3455121372425'
,'123456789101112131415'
,'11312123133'
,'314159265358979323846264338327950288419716939937']

test.forEach(t=>{console.log('\n'+t);F(t)})
<pre id=O></pre>


2

GNU sed, 83 77 73 71 byte

(Segna un extra perché richiediamo la -rbandiera)

h
s/./&_/
:
/(\b[^ ]+).*\b\1_/{
s/_(.)/\1_/
t
g
}
s/_(.)/ \1_/
t
s/_//

Il ciclo interno verifica una sequenza ripetuta e aggiunge i caratteri secondo necessità fino a quando non appare un numero univoco dopo il separatore _. L'anello esterno si muove _lungo.

Versione estesa, con annotazioni:

#!/bin/sed -rf

# Stash original in hold space
h

# Add separator
s/./&_/

:
# If current candidate is a duplicate, ...
/(\b[^ ]+).*\b\1_/{
#  ...then attempt to lengthen it ...
s/_(.)/\1_/
# ... and repeat if we succeeded, ...
t
# ... otherwise, restore original string
g
}
# Insert a space, and move our separator along
s/_(.)/ \1_/
t

# Remove the separator if we still have it
s/_//

Potresti combinare entrambi tin uno.
Utente112638726

Inoltre /((\b[^ ]+).*\b\2)_/{può essere riscritto come /(\b[^ ]+).*\b\1_/{, nessun motivo per 2 gruppi di acquisizione.
Utente112638726

Nessun problema :), è necessario modificare il riferimento \1però!
Utente 1101238726

1

Rubino, 57 + 1 = 58 byte

s=''
l={}
$_.chars{|c|l[s<<c]||=s=''}
l[s]||$_=l.keys*' '

Utilizza il flag della riga di comando -p(o plse l'input ha una nuova riga finale). Sfrutta diversi tratti dei dizionari Ruby Hash: puoi mutare in sicurezza la stringa che hai usato per definire una chiave senza che cambi la chiave (che non funziona per altri tipi mutabili), .keysrestituisce le chiavi nell'ordine in cui sono state inserite e l' []||=operatore fornisce un modo conciso di diramare se una determinata chiave è già lì.


1

Haskell, 105 byte

f lo fa.

e""s""=unwords s
e t s""=concat s++t
e t s(c:r)|t&c`elem`s=e(t&c)s r|0<1=e""(s&(t&c))r
a&b=a++[b]
f=e""[]

1

PHP - 148 byte

Bella sfida, molto divertente!

$x=fgets(STDIN);$w=array();$k='';$l='';for($i=0;$i<strlen($x);$i++){$k.=$x[$i];if(!isset($w[$k])){$l.=$k.' ';$w[$k]=1;$k='';}}echo strlen($k)?$x:$l;
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.