Backspace e digitare nuovamente un elenco di parole


38

Ecco come backspace-and-retype da una stringa all'altra:

  1. Inizia dalla prima stringa.
  2. Rimuovi i caratteri alla fine fino a quando il risultato non è un prefisso della seconda stringa. (Questa operazione può richiedere 0 passaggi.)
  3. Aggiungi caratteri alla fine fino a quando il risultato è uguale alla seconda stringa. (Anche questo può richiedere 0 passaggi.)

Ad esempio, il percorso da fooabca fooxyzappare come:

fooabc
fooab
fooa
foo
foox
fooxy
fooxyz

Compito

Dato un elenco di parole, scrivi un programma che si sposta indietro e riscrive dalla stringa vuota, a tutte le parole dell'elenco in successione, di nuovo alla stringa vuota. Emette tutte le stringhe intermedie.

Ad esempio, dato l'elenco di input ["abc", "abd", "aefg", "h"], l'output dovrebbe essere:

a
ab
abc
ab
abd
ab
a
ae
aef
aefg
aef
ae
a

h

Regole

È possibile restituire o stampare un elenco di stringhe o una singola stringa con delimitatore di scelta. Se lo desideri, puoi includere le stringhe vuote iniziali e finali. Si garantisce che l'input contenga almeno una parola e che ogni parola contenga solo lettere ASCII minuscole ( a- z). Modifica: le stringhe consecutive nell'input sono garantite per non eguagliarsi a vicenda.

Questo è ; vince il codice più breve in byte.

Un'implementazione di riferimento in Python 3: provala online!


4
@ rahnema1> scrivi un programma che si sposta indietro e riscrive dalla stringa vuota
Kritixi Lithos

3
Come sarebbe l'output ["abc","abc"]?
Kritixi Lithos,

1
@Emigna Oops, questo è esattamente questo ma in un ciclo! Quindi andrò avanti e dirò che questo è un duplicato di quello.
Lynn,

4
@Lynn Non è esattamente la stessa cosa. Quello non include il riconoscimento dei prefissi comuni, scende sempre a un carattere.
Martin Ender,

6
Caso di prova:a,abc,abcde,abc,a,abc,abcde
Zgarb,

Risposte:



9

Perl, 43 byte

42 byte di codice + -nflag.

chop$@,say$@while!s/^$@//;s/./say$@.=$&/ge

Per eseguirlo:

perl -nE 'chop$@,say$@while!s/^$@//;s/./say$@.=$&/ge' <<< "abc
abd
aefg
h"

questo stampa abc 3 volte
izabera il

@izabera C'era uno spazio dopo abcaverlo fatto stampare 3 volte (ma in realtà, la prima e la terza volta era senza spazio). L'ho rimosso.
Dada,

5

Java 8, 144 byte

Questo è simile all'implementazione di riferimento ma combina i due whileloop. È un'espressione lambda che accetta aString[] parametro.

a->{String c="";int l=0,i;for(String w:a)while((i=w.indexOf(c))!=0||!c.equals(w))System.out.println(c=i!=0?c.substring(0,--l):c+w.charAt(l++));}

Ungolfed

a -> {
    String c = "";
    int l = 0, i;
    for (String w : a)
        while ((i = w.indexOf(c)) != 0 || !c.equals(w))
            System.out.println(c = i != 0 ? c.substring(0, --l) : c + w.charAt(l++));
}

Ringraziamenti

  • -38 byte grazie al suggerimento lambda di CAD97

Non è più economico da usare class Binvece di interface B? È possibile eseguire da una classe pacchetto-privata. Inoltre, considera l'utilizzo di un lambda come hai già specificato Java8.
CAD97

@ CAD97 interface B{static void mainè più corto di class B{public static void main.
Kevin Cruijssen,

@ CAD97 Non riuscivo a pensare a un modo per portare lambdas in questo, ma ho appena imparato a conoscerli ieri. Qualche idea?
Jakob,

1
Ah, sono arrugginito. Dovresti essere in grado di fare a->{/*your code*/}, che verrà assegnato a una variabile di tipo java.util.function.Consumer<String[]>. Non posso testare al momento, tuttavia.
CAD97

1
@JakobCornell Per impostazione predefinita, PPCG consente l'invio completo di programmi o funzioni. Per le lingue con funzioni anonime (lambda), la funzione anonima di per sé è una risposta accettabile (quindi non è necessario includere la variabile per memorizzarla). (Anche se nelle osservazioni Java è cortese fornire il tipo di lambda.)
CAD97

4

Mathematica, 149 byte

Reap[Fold[n=NestWhile;s=StringMatchQ;r=StringReplace;n[k=#2;Sow@r[k,#~~a_~~___:>#<>a]&,n[Sow@r[#,a___~~_:>a]&,#,!s[k,#~~___]&],k!=#&]&,"",#]][[2,1]]&

3

Retina , 39 byte

Il conteggio dei byte presuppone la codifica ISO 8859-1.

M!&r`.+
%)`\G.
¶$`$&
+`((.*).¶)\2¶\1
$1

Provalo online!

Input e output sono elenchi separati da avanzamento riga. L'output include la stringa vuota iniziale e finale.


3

Gelatina , 31 29 26 byte

⁷œ|;\
ÇṚðfḢṭḟ;ḟ@ḊðÇ}
⁷;ç2\

Provalo online!

Come funziona

⁷;ç2\           Main link. Argument: A (string array)

⁷;              Prepend a linefeed to A. 
                This is cheaper than prepending an empty string.
  ç2\           Reduce all overlapping pairs by the second helper link.


ÇṚðfḢṭḟ;ḟ@ḊðÇ}  Second helper link. Arguments: s, t (strings)

Ç               Call the first helper link with argument s.
 Ṛ              Reverse the results.
            Ç}  Call the first helper link with argument t.
  ð        ð    Combine everything in between into a dyadic chain, and call it
                with the results to both sides as arguments.
                Let's call the arguments S and T.
   f            Filter; get the common strings of S and T.
    Ḣ           Head; select the first one.
      ḟ         Filterfalse; get the strings in S that do not appear in T.
     ṭ          Tack; append the left result to the right one.
        ḟ@      Filterfalse swap; get the strings in T that do not appear in S.
       ;        Concatenate the results to both sides.
          Ḋ     Dequeue; remove the first string.


⁷œ|;\           First helper link. Argument: s (string)

⁷œ|             Linefeed multiset union; prepend a linefeed to s unless it already
                has a linefeed in it (the first string does).
   ;\           Concatenate cumulative reduce; generate all prefixes of the result.

2

Haskell , 102 93 91 90 byte

(?)=take.length
a!x@(b:c)|a==b=b!c|a/=a?b=a:init a!x|d<-'?':a=a:d?b!x
_!x=x
(""!).(++[""])

L'ultima riga è una funzione anonima, che accetta e restituisce un elenco di stringhe. Provalo online!

Spiegazione

La mia soluzione è ricorsiva. Innanzitutto, ?è una funzione di infissione helper: a?bfornisce i primi length acaratteri bo l'intero bse aè più lungo. Quindi definisco una funzione infix !. L'idea è che a!x, dove ac'è una stringa e xun elenco di stringhe, produce il percorso dalla aprima stringa xe si ricorre alla coda di x. Nell'ultima riga definisco una funzione anonima che aggiunge la stringa vuota, quindi si applica !alla stringa vuota e all'input.

Spiegazione di !:

a!x@(b:c)        -- a!x, where x has head b and tail c:
  |a==b          -- If a equals b,
    =b!c         -- recurse to x.
  |a/=a?b        -- If a is not a prefix of b,
    =a:          -- produce a and
    init a!x     -- continue with one shorter prefix of a.
  |              -- Otherwise a is a proper prefix of b.
   d<-'?':a      -- Let d be a with an extra dummy element,
    =a:          -- produce a and
    d?b!x        -- continue with one longer prefix of b.
_!x=x            -- If x is empty, return x.

2

Python 2, 118 107 103 97 97 93 92 byte

s=''
for i in input()+[s]:
 while i.find(s):s=s[:-1];print s
 while i>s:s+=i[len(s)];print s

L'input è dato come ['abc', 'abcdef', 'abcfed'], o come ["abc", "abcdef", "abcfed"] .

Revisione 1: -11 byte. Il merito va a @xnor per il suo post sui consigli di golf di Python, e a @Lynn per aver trovato il consiglio per me, e per me per essere intelligente. Sono state apportate due modifiche: invece di not s.startswith(i), ho usato s.find(i)e invece di i!=saver usatoi>s .

Revisione 2: -4 byte. Il merito va a me rendermi conto che ho fatto un errore davvero stupido. Invece di utilizzare il rientro a scheda singola e doppia, ho usato il rientro a spazio singolo e a scheda singola.

Revisione 3: -6 byte. Il merito va a @ mbomb007 per aver suggerito di mettere i whiles su una sola riga. Ho anche corretto un bug cambiando s.find(i)in i.find(s).

Revisione 4: -4 byte. Il merito va a @xnor per aver realizzato che non avevo bisogno di memorizzare l'input in una variabile.

Revisione 5: -1 byte. Il merito va a me per aver realizzato che ['']è la stessa cosa che [s]quando si aggiunge all'input.


Metti le whiles su un'unica riga. Inoltre, puoi usare <1invece di not.
mbomb007,

Bella risposta! C'è un bel consiglio di xnor su come evitarestartswith .
Lynn,

@Lynn Oh, grazie per il link! L'ho trovato davvero utile!
HyperNeutrino,

@ mbomb007 Mi dispiace, non capisco cosa intendi mettendo la whiles su una sola riga. Vuoi dire come while s.find(i):s=s[:-1];print s? Inoltre, grazie per il suggerimento in merito <1, ma sono passato a qualcosa di ancora più breve grazie a uno dei suggerimenti di xnor sul thread dei suggerimenti di Python.
HyperNeutrino,

@AlexL. Sì, metti il ​​tempo è così.
mbomb007,

1

GNU M4, 228 o 232 byte¹

(¹ a seconda se terminare il file con dnl\no meno — sono ancora nuovo sia per il golf che per M4)

define(E,`ifelse(index($2,$1),0,`T($1,$2)',`$1
E(substr($1,0,decr(len($1))),$2)')')define(T,`ifelse($1,$2,,`$1
T(substr($2,0,incr(len($1))),$2)')')define(K,`ifelse($2,,$1,`E($1,$2)K(shift($@))')')define(M,`K(substr($1,0,1),$@)')

Inoltre, è possibile salvare 3 byte sostituendo il secondo argomento per substrfrom0 a stringa vuota, ma ciò produrrebbe molti avvisi su stderr.

Ungolfed:

define(erase_til_prefix, `dnl arguments: src dst; prints src and chops one char off of it until src == dst, at which point it calls type_til_complete instead
ifelse(dnl
index($2, $1), 0, `type_til_complete($1, $2)',dnl
`$1
erase_til_prefix(substr($1, 0, decr(len($1))), $2)dnl
')')dnl
define(type_til_complete, `dnl arguments: src dst; types src, does not type `dst' itself
ifelse(dnl
$1, $2, ,dnl
`$1
type_til_complete(substr($2, 0, incr(len($1))), $2)'dnl
)')dnl
define(main_, `dnl
ifelse(dnl
$2, , $1, dnl no arguments left
`erase_til_prefix($1, $2)main_(shift($@))'dnl
)')dnl
define(main, `main_(substr($1, 0, 1), $@)')dnl

Uso:

$ m4 <<<"include(\`backspace-golfed.m4')M(abc, abd, aefg, abcdefg, h)"

1

PHP, 116 111 101 83 byte

Nota: utilizza la codifica Windows-1252.

for(;$w=$argv[++$i];)for(;$c!=$w;)echo$c=($c^$c^$w)==$c?$c.ÿ&$w:substr($c,0,-1),~õ;

Esegui in questo modo:

php -r 'for(;$w=$argv[++$i];)for(;$c!=$w;)echo$c=($c^$c^$w)==$c?$c.ÿ&$w:substr($c,0,-1),~õ;' -- abc abd aefg h 2>/dev/null
> a
> ab
> abc
> ab
> abd
> ab
> a
> ae
> aef
> aefg
> aef
> ae
> a
>
> h

Spiegazione

for(                       # Outer loop.
  ;
  $w=$argv[++$i];          # Loops over the input words.
)
  for(                     # Second inner loop.
    ;
    $c!=$w;                # Loop until the word was output.
  )
    echo $c=
      ($c^$c^$w)==$c?      # Check if last output string is a substring
                           # match with the next word to output.
        $c.ÿ&$w:           # ... If yes, suffix the string with the next
                           # char of the word, and output the result.
        substr($c,0,-1),   # ... If not, remove a char and output.
      ~õ;                  # Output newline.

Ritocchi

  • 5 byte salvati utilizzando trim($c^$w,"\0")per verificare la corrispondenza della sottostringa anziché $c&&strpos($w,$c)!==0.
  • Salvato 2 byte usando ~ÿper produrre una stringa con un byte NUL anziché"\0"
  • Salvato 8 byte usando il $c=$c.ÿ&$wsuffisso $ccon il carattere successivo di$w
  • Salvato 18 enormi byte combinando la logica dei 2 loop interni in un singolo loop
  • Risolto un bug con un testcase dai commenti, nessuna modifica nel conteggio dei byte

1

Lotto, 296 291 byte

@echo off
set f=
set t=%1
:t
set f=%f%%t:~,1%
set t=%t:~1%
echo(%f%
if not "%t%"=="" goto t
shift
set t=%1
set s=%f%
set p=
:h
if %s:~,1%==%t:~,1% set p=%p%%t:~,1%&set s=%s:~1%&set t=%t:~1%&goto h
:b
set f=%f:~,-1%
echo(%f%
if not "%f%"=="%p%" goto b
if not "%1"=="" goto t

Il calcolo del prefisso comune era ingombrante.


0

PHP, 153 byte

terribilmente lungo :(

for($s=$argv[$k=1];$t=$argv[++$k];){for(;$s>""&&strstr($t,$s)!=$t;$s=substr($s,0,-1))echo"$s
";for($i=strlen($s);$s<$t;$s.=$t[$i++])echo"$s
";echo"$s
";}

Corri con php -nr '<ode>' <text1> <text2> ....


0

JavaScript (ES6), 135 byte

Sfida interessante! Uso: g(["abc", "abd", "aefg", "h"]). Non riesco a salvare alcun byte scrivendo questo come una funzione, quindi è due. Newline non incluse nel conteggio dei byte.

f=a=>console.log(([,...z]=[x,y]=a)[0])||
y?f(a=(x==y.slice(0,-1))?z:([y.match(x)
?x+y[x.length]:x.slice(0,-1),...z])):1;
g=a=>f(['',...a])

Sono sicuro che questo può essere ridotto molto di più. Aggiungerà la versione non golfata più tardi.


0

Javascript, 98 byte

a=>{c="",l=0;for(w of a)while((i=w.indexOf(c))!=0||c!=w)alert(c=i!=0?c.substring(0,--l):c+w[l++])}

La risposta Java di Port of Jakob

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.