Retour arrière et retaper une liste de mots

38

Voici comment revenir en arrière et retaper d'une chaîne à une autre:

  1. Commencez à la première chaîne.
  2. Supprimez les caractères à la fin jusqu'à ce que le résultat soit un préfixe de la deuxième chaîne. (Cela peut prendre 0 étapes.)
  3. Ajoutez des caractères à la fin jusqu'à ce que le résultat soit égal à la deuxième chaîne. (Cela peut prendre 0 étapes, aussi.)

Par exemple, le chemin de fooabcà fooxyzressemble à:

fooabc
fooab
fooa
foo
foox
fooxy
fooxyz

Tâche

À partir d'une liste de mots, écrivez un programme qui recule et recoupe son chemin de la chaîne vide à tous les mots successivement de la liste, puis revient à la chaîne vide. Affiche toutes les chaînes intermédiaires.

Par exemple, étant donné la liste des entrées ["abc", "abd", "aefg", "h"], le résultat devrait être:

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

h

Règles

Vous pouvez renvoyer ou imprimer une liste de chaînes ou une seule chaîne avec un délimiteur de choix. Vous pouvez éventuellement inclure les chaînes vides initiale et finale. Il est garanti que l’entrée contient au moins un mot et que chaque mot ne contient que des lettres ASCII minuscules ( a- z). Modifier: les chaînes consécutives dans l'entrée sont garanties ne pas être égales.

C'est du ; le code le plus court en octets gagne.

Une implémentation de référence dans Python 3: essayez-le en ligne!

Lynn
la source
4
@ rahnema1> écrivez un programme qui recule et retape à partir de la chaîne vide
Kritixi Lithos
3
Comment serait la sortie pour ["abc","abc"]?
Kritixi Lithos
1
@ Emigna Oups, c'est exactement ça, mais en boucle! Alors je vais aller de l'avant et dire que c'est un duplicata de cela.
Lynn
4
@ Lynn Ce n'est pas exactement la même chose. Celui-ci n'inclut pas la reconnaissance des préfixes communs, il s'agit toujours d'un caractère.
Martin Ender
6
Cas de test: a,abc,abcde,abc,a,abc,abcde
Zgarb

Réponses:

9

Perl, 43 octets

42 octets de code + -n drapeaux.

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

Pour l'exécuter:

perl -nE 'chop$@,say$@while!s/^$@//;s/./say$@.=$&/ge' <<< "abc
abd
aefg
h"
Dada
la source
cela imprime abc 3 fois
izabera
@izabera Il y avait un espace après l' abcavoir fait imprimer 3 fois (mais en réalité, la première et la troisième fois, c'était sans l'espace). Je l'ai enlevé.
Dada
5

Java 8, 144 octets

Celle-ci est similaire à l'implémentation de référence mais combine les deux whileboucles. C'est une expression lambda qui accepte un String[]paramètre.

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

Remerciements

  • -38 octets grâce à la suggestion lambda de CAD97
Jakob
la source
N'est-ce pas moins cher d'utiliser class Bau lieu de interface B? Vous pouvez exécuter à partir d'une classe package-private. Pensez également à utiliser un lambda car vous avez déjà spécifié Java8.
CAD16
@ CAD97 interface B{static void mainest plus court que class B{public static void main.
Kevin Cruijssen le
@ CAD97 Je ne pouvais pas penser à un moyen d'intégrer les lambdas à ce sujet, mais je viens juste d'apprendre à leur sujet hier. Des idées?
Jakob
1
Ah, je suis rouillé. Vous devriez pouvoir faire a->{/*your code*/}, ce qui assignera à une variable de type java.util.function.Consumer<String[]>. Je ne peux pas tester pour le moment, cependant.
CAD16
1
@JakobCornell Par défaut, PPCG autorise les soumissions complètes de programmes ou de fonctions. Pour les langues avec des fonctions anonymes (lambda), la fonction anonyme en elle-même est une réponse acceptable (vous n'avez donc pas à inclure la variable dans laquelle l'enregistrer). (Bien que, dans les soumissions Java, il soit courtois de fournir le type de lambda.)
CAD97
4

Mathematica, 149 octets

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]]&
JungHwan Min
la source
3

Rétine , 39 octets

Le nombre d'octets suppose un codage ISO 8859-1.

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

Essayez-le en ligne!

Les entrées et sorties sont des listes séparées par des sauts de ligne. La sortie inclut les chaînes vides de début et de fin.

Martin Ender
la source
3

Jelly , 31 29 26 octets

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

Essayez-le en ligne!

Comment ça marche

⁷;ç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.
Dennis
la source
2

Haskell , 102 93 91 90 octets

(?)=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
(""!).(++[""])

La dernière ligne est une fonction anonyme, qui prend et retourne une liste de chaînes. Essayez-le en ligne!

Explication

Ma solution est récursive. Premièrement, il ?y a une fonction infixe auxiliaire: a?bdonne les premiers length acaractères de b, ou la totalité de bsi aest plus long. Ensuite, je définis une fonction infixe !. L'idée est que a!x, où se atrouve une chaîne et xune liste de chaînes, produit le chemin de ala première chaîne à l' xintérieur et revient à la fin de x. Sur la dernière ligne, je définis une fonction anonyme qui ajoute la chaîne vide, puis s’applique !à la chaîne vide et à l’entrée.

Explication de !:

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.
Zgarb
la source
2

Python 2, 118 107 103 97 93 92 octets

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'entrée est donnée comme ['abc', 'abcdef', 'abcfed'], ou comme [ "abc", "abcdef", "abcfed"].

Révision 1: -11 octets. Le mérite en revient à @xnor pour son article sur les astuces concernant le golf Python, et à @Lynn pour avoir trouvé l’astuce pour moi et pour moi pour être intelligent. Deux modifications ont été apportées: au lieu de not s.startswith(i), j'ai utilisé s.find(i)et au lieu de i!=sutilisé i>s.

Révision 2: -4 octets. Le crédit me revient en réalisant que j'ai commis une erreur vraiment stupide. Plutôt que d'utiliser l'indentation à un seul onglet et à deux onglets, j'ai utilisé l'indentation à un espace et à un seul onglet.

Révision 3: -6 octets. Le crédit va à @ mbomb007 pour avoir suggéré de mettre les whiles sur une seule ligne. J'ai aussi corrigé un bug en changeant s.find(i)pouri.find(s) .

Révision 4: -4 octets. Le mérite revient à @xnor pour avoir réalisé que je n'avais pas besoin de stocker l'entrée dans une variable.

Révision 5: -1 octet. Le mérite me revient d’avoir réalisé que ['']c’est la même chose que [s]lorsqu’il est ajouté à l’entrée.

HyperNeutrino
la source
Mettez les whiles chacun sur une seule ligne. En outre, vous pouvez utiliser <1au lieu de not.
mbomb007
Bonne réponse! Xnor a un bon conseil à éviterstartswith .
Lynn
@ Lynn Oh, merci pour le lien! Je l'ai trouvé vraiment utile!
HyperNeutrino
@ mbomb007 Je suis désolé, je ne comprends pas ce que vous voulez dire en plaçant le whiles sur une seule ligne. Tu veux dire comme while s.find(i):s=s[:-1];print s? Merci également pour la suggestion <1, mais j'ai changé pour quelque chose d'encore plus court, grâce à l'un des conseils de xnor sur le fil des conseils Python.
HyperNeutrino
@ AlexL. Oui, le temps est comme ça.
mbomb007
1

GNU M4, 228 ou 232 octets¹

(¹ selon qu'il faut dnl\nou non terminer le fichier - je suis encore novice en golf et en 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),$@)')

De plus, 3 octets pourraient être sauvegardés en remplaçant le deuxième argument de substrfrom 0par la chaîne vide, mais cela produirait de nombreux avertissements sur 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

Usage:

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

PHP, 116 111 101 83 octets

Remarque: utilise le codage Windows-1252.

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

Courez comme ça:

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

Explication

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.

Tweaks

  • 5 octets enregistrés en utilisant trim($c^$w,"\0")pour vérifier la correspondance de sous-chaîne au lieu de $c&&strpos($w,$c)!==0.
  • Sauvegardé 2 octets en utilisant ~ÿpour renvoyer une chaîne avec un octet NUL au lieu de"\0"
  • Sauvegardé 8 octets en utilisant $c=$c.ÿ&$wsuffixe $cavec le caractère suivant de$w
  • Sauvegardé de 18 octets en combinant la logique des 2 boucles internes en une seule boucle
  • Correction d'un bug avec un test à partir des commentaires, aucune modification du nombre d'octets
aross
la source
1

Lot, 296 291 octets

@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

Le calcul du préfixe commun était fastidieux.

Neil
la source
0

PHP, 153 octets

terriblement long :(

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

Courez avec php -nr '<ode>' <text1> <text2> ....

Titus
la source
0

JavaScript (ES6), 135 octets

Défi intéressant! Utilisation: g(["abc", "abd", "aefg", "h"]). Il me semblait impossible de sauver des octets en écrivant cela comme une fonction, donc deux. Les nouvelles lignes ne sont pas incluses dans le nombre d'octets.

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

Je suis sûr que cela peut être réduit beaucoup plus. Ajoutera une version non-golfée plus tard.

Chris M
la source
0

Javascript, 98 octets

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

Réponse Java du port de Jakob

SuperStormer
la source