Trasforma lentamente una stringa in un'altra


31

La sfida

Date due stringhe / una matrice di stringhe, emette la prima stringa che si restringe lentamente e si espande nuovamente nella seconda stringa.

Puoi presumere che le stringhe inizieranno sempre con lo stesso carattere.

Esempio

Input:
"Test", "Testing"

Output:
Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Per prima cosa hai emesso la prima parola:

Test

Quindi continui a rimuovere una lettera fino a quando la stringa è lunga un carattere:

Tes
Te
T

Quindi continua ad aggiungere una lettera della seconda parola fino al termine:

Te
Tes
Test
Testi
Testin
Testing

(se entrambe le stringhe sono lunghe un carattere, quindi emettine una sola volta).

Casi test

"Hello!", "Hi."
Hello!
Hello
Hell
Hel
He
H
Hi
Hi.

"O", "O"

O

"z", "zz"

z
zz

".vimrc", ".minecraft"

.vimrc
.vimr
.vim
.vi
.v
.
.m
.mi
.min
.mine
.minec
.minecr
.minecra
.minecraf
.minecraft

"     ", "   "

SSSSS
SSSS
SSS
SS
S
SS
SSS

"0123456789", "02468"

0123456789
012345678
01234567
0123456
012345
01234
0123
012
01
0
02
024
0246
02468

(nota: sullo spazio / quarto test case, sostituire la S con spazi)

Regole

  • Questo è , quindi vince la risposta più breve in byte! Tiebreaker è il post più votato. Il vincitore sarà scelto il 09/10/2016.

  • Sono vietate le scappatoie standard.


Saranno consentite 2 nuove righe finali (una riga vuota visibile dopo la sequenza)?
seshoumara,

Risposte:


11

Pyth, 9 byte

j+_._Et._

Un programma che accetta la seconda stringa e quindi la prima stringa, come stringhe tra virgolette su STDIN e stampa il risultato.

Provalo online

Come funziona

j+_._Et._  Program. Inputs: Q, E
   ._E     Yield prefixes of E as a list
  _        Reverse the above
       ._  Yield prefixes of Q as a list (implicit input fill)
      t    All but the first element of above
 +         Merge the two lists
j          Join on newlines
           Implicitly print

14

V , 14 byte

òYp$xhòjòÄ$xhh

Provalo online!

Spiegazione:

ò     ò     "Recursively:
 Yp         "  Yank the current line and paste it
   $        "  Move to the end of the current line
    x       "  Delete one character
     h      "  Move One character to the right.
            "  Because of the way loops work in V, this will throw an error if there
            "  Is only one character on the current line.

Ora, il buffer si presenta così:

0123456789
012345678
01234567
0123456
012345
01234
0123
012
01
0

Dobbiamo solo fare la stessa cosa al contrario per la riga successiva:

j           "Move down one line
 ò     ò    "Recursively (The second ò is implicit)
  Ä         "  Duplicate this line up
   $        "  Move to the end of the current line
    x       "  Delete one character
     hh     "  Move two characters to the right.
            "  Because of the way loops work in V, this will throw an error if there
            "  Is only two characters on the current line.

Soluzione alternativa più interessante :

òÄ$xhòç^/:m0
ddGp@qd

3
È come se vim sia sempre lo strumento giusto per il lavoro
Downgoat

@Downgoat Esattamente. Ecco perché devi iniziare a giocare a golf in V.: P
DJMcMayhem

9

Python, 93 byte

f=lambda a,b,r='',i=2:a and f(a[:-1],b,r+a+'\n')or(len(b)>=i and f(a,b,r+b[:i]+'\n',i+1)or r)

Inizia con la stringa vuota r, aggiunge ae una nuova riga e rimuove l'ultimo carattere da afino a quando aè vuota, quindi aggiunge le parti richieste di be una nuova riga mantenendo un contatore i, che inizia 2fino a quando bviene superata la lunghezza di , quindi ritorna r. Ha una nuova riga finale.

Tutti i test sono su ideone


2 cose 1) Credo che tu abbia contato male i personaggi ed è in realtà 93 e 2) Non devi dirlo r="". Semplice rfunzionerebbe ancora.

Grazie @JackBates. 1. Corretto e aggiornato - probabilmente ho dimenticato il f=. 2. Senza il r=''presente f('test','testing')non funzionerebbe; sì f('test','testing',''), ma dobbiamo seguire le specifiche.
Jonathan Allan,

Perdonami. Stavo solo guardando il codice e non gli esempi.

7

05AB1E , 9 byte

.pRI.p¦«»

Spiegazione

.pR           # prefixes of first word
     I.p       # prefixes of second word
         ¦       # remove first prefix
          «     # concatenate
           »    # join with newlines

Provalo online!


7

Retina, 50 41 26 byte

Grazie a Martin Ender per aver salvato 15 (!) Byte.

M&!r`.+
Om`^.¶[^·]+|.+
A1`

Prende l'input con le due stringhe separate da una nuova riga:

Test
Testing

Provalo online!

Spiegazione

M&!r`.+

La prima riga genera i "passaggi" di entrambe le parole:

Testing
Testin
Testi
Test
Tes
Te
T
Test
Tes
Te
T

Mè per la modalità partita, &considera le partite sovrapposte e !stampa le partite anziché il numero di esse. La ragione per cui è invertita è l' ropzione da destra a sinistra: il motore inizia a cercare i fiammiferi alla fine della corda e continua verso l'inizio.

Om`^.¶[^·]+|.+

Questo ottiene tutto nel giusto ordine: Ocontiene tutte le corrispondenze della regex successiva: un personaggio sulla sua stessa linea e ogni personaggio (comprese le nuove linee) dopo di esso, che corrisponde a tutta la seconda metà come un pezzo, o comunque una linea di caratteri , che corrisponde a ogni singola riga. Queste corrispondenze vengono quindi ordinate per punto di codice, quindi la T seguita dalla nuova riga inizia per prima, seguita dalle linee, crescente per lunghezza.

A1`

Ora abbiamo solo quella prima linea di caratteri in cima, quindi usiamo la Amodalità ntigrep per scartare la prima corrispondenza del regex predefinito .+.

Vecchia versione

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

Prova questa versione online!

Spiegazione

La prima riga è la stessa, quindi vedi la spiegazione sopra.

O`\G..+¶

Ciò inverte le righe della prima metà (seconda parola di input). In realtà Ocontiene le righe e regex limita le corrispondenze: deve essere una riga di due o più caratteri ( ..+) seguita da una nuova riga ( ) che inizia da dove era stata interrotta l'ultima ( \G). Nell'esempio sopra, il singolo Tnel mezzo non corrisponde, quindi nulla dopo può farlo.

Te
Tes
Test
Testi
Testin
Testing
T
Test
Tes
Te
T

Ora abbiamo i due componenti giusti, ma nell'ordine sbagliato.

s`(.*)¶.¶(.*)
$2¶$1

¶.¶corrisponde alla T solitaria nel mezzo, di cui non abbiamo bisogno ma separa le due parti. I due (.*)acquisiscono tutto prima e dopo, compresi i newline grazie alla smodalità ingle-line. Le due acquisizioni vengono sostituite nel giusto ordine con una nuova riga in mezzo.

Ora abbiamo finito, a meno che le stringhe di input non siano lunghe un carattere, nel qual caso l'input non è cambiato. Per eliminare il duplicato, sostituiamo ¶.$(quando l'ultima riga della stringa è un singolo carattere) con nulla.


4

Python 2, 88 82 byte

x,y=input(),input()
for i in x:print x;x=x[:-1]
s=y[0]
for i in y[1:]:s+=i;print s

Accetta due input, ognuno circondato da virgolette.

Grazie @JonathanAllan per aver salvato alcuni byte e segnalato un bug.


1
Non c'è bisogno dell'in len(x)in x=x[:len(x)-1]poiché la divisione dell'offset negativo funziona: puoi semplicemente scrivere x=x[:-1]. L'unico problema è che il codice non gestirà " ", " "molto bene il test case.
Jonathan Allan,

1
Puoi rilasciare il secondo input()e utilizzare un formato di input come"<str1>", "<str2>"
LevitatingLion

È possibile modificare la seconda riga in for i in range(x):print x[-i:]e la quarta riga in for i in range(1,y):print y[:-i]. Non sono sicuro che funzionerebbe, però.
clismique,

4

Perl, 34 28 byte

include +2 per-0n

Esegui con le stringhe su righe separate su STDIN:

perl -M5.010 -0n slow.pl
Test
Testing
^D

slow.pl:

/(^..+|
\K.+?)(?{say$&})^/

Lascia che regex backtracking faccia il lavoro ...


3

Cheddar , 76 byte

(a,b,q=s->(|>s.len).map((_,i)->s.head(i+1)))->(q(a).rev+q(b).slice(1)).vfuse

Un po 'più di quanto mi sarebbe piaciuto. Aggiungerò presto una spiegazione

Provalo online!


Cosa fa |>?
Cyoce,

@Cyoce unary |> is range [0, n) binary is [a, b]
Downgoat

3

Brachylog , 32 byte

:1aLtT,Lhbr:Tc~@nw
:2fb
~c[A:B]h

Provalo online!

Spiegazione

Brachylog non ha prefisso incorporato, quindi otterremo i prefissi usando concatenate(Vedi predicato 2): un prefisso Sè Pse Pconcatenato a Q(qualunque cosa sia) si traduca S.

  • Predicato principale:

    :1aL                  L is all prefixes of both elements of the input (see predicate 1)
       LtT,               T is the second element of L
           Lhbr           Remove the first prefix of the first list of L and reverse it
               :Tc        Concatenate with T
                  ~@n     Join with newlines
                     w    Write to STDOUT
    
  • Predicato 1:

    :2f                   Find all prefixes of the input string (see predicate 2)
       b                  Remove the first one (empty string)
    
  • Predicato 2:

    ~c[A:B]               Input is the result of concatenating A to B
           h              Output is A
    

3

Javascript, 103 81 byte

f=(x,y,n=1)=>x?`
`+x+f(x.slice(0,-1),y):n++<y.length?`
`+y.slice(0,n)+f(x,y,n):''

Esempio: f("Test", "Testing")

Produzione:

Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Risposta originale

f=(x,y,n=1)=>x?(console.log(x),f(x.slice(0,-1),y)):n++<y.length?(console.log(y.slice(0,n)),f(x,y,n)):''

3

Java, 188 179 byte

interface E{static void main(String[]a){int i=a[0].length();while(i>1)System.out.println(a[0].substring(0,i--));while(i<=a[1].length())System.out.println(a[1].substring(0,i++));}}

Aggiornare

  • Rimossa la variabile s, salvata 9 byte

Ungolfed :

interface E {

    static void main(String[] a) {
        int i = a[0].length();
        while (i > 1) {
            System.out.println(a[0].substring(0, i--));
        }
        while (i <= a[1].length()) {
            System.out.println(a[1].substring(0, i++));
        }
    }
}

Utilizzo :

$ java E 'test' 'testing'
test
tes
te
t
te
tes
test
testi
testin
testing

3

Haskell, 54 53 47 byte

t[]=[]
t x=x:t(init x)
(.reverse.t).(++).init.t

Esempio di utilizzo: ((.reverse.t).(++).init.t) "Hello" "Hi!" -> ["Hello","Hell","Hel","He","H","Hi","Hi!"].

Qualche magia inutile. È lo stesso di f x y = (init(t x))++reverse (t y)dove tcrea un elenco di tutte le sottostringhe iniziali, ad es. t "HI!"-> ["H","HI","HI!"].


Hm t=reverse.tail.inits?
Bergi,

@Bergi: certo, ma ha initsbisogno import Data.List.
nimi,


3

GNU sed, 57 45 + 2 (flag rn) = 47 byte

:;1{/../p};2G;2h;s/.(\n.*)?$//;/./t;g;s/.$//p

Correre:

echo -e "Test\nTesting" | sed -rnf morphing_string.sed

L'input dovrebbe essere le due stringhe separate da una nuova riga. Il codice è gestito da sed per ogni riga.

Il ciclo :elimina un carattere dalla fine della stringa in modo iterativo. L'uscita collegata alla prima stringa viene stampata direttamente, tranne il primo carattere: 1{/../p}. L'output per la seconda stringa viene memorizzato nello spazio di attesa in ordine inverso ( 2G;2h) durante la cancellazione e stampato alla fine.


3

C (gcc) , 102 97 95 93 byte

n;f(char*a,char*b){for(n=strlen(a);n;puts(a))a[n--]=0;for(a=b+1;*a++;*a=n)n=*a,*a=0,puts(b);}

Provalo online!

Il primo ciclo sovrascrive la stringa con 0 byte a partire dalla fine e utilizza puts() per stampare la stringa. Il secondo ciclo non può semplicemente sovrascrivere dall'inizio, deve memorizzare il vecchio valore in modo da poterlo rimettere; lo 0 byte sta camminando verso la fine.

Grazie a @homersimpson e @ceilingcat per ogni rasatura di 2 byte!


1
È possibile salvare un paio di byte dichiarando ncome int globale come: n;f(char*a,char*b){n=strlen(a).... E probabilmente puoi fare n=*a=0come incarico incatenato nel corpo del tuo ciclo.
Homersimpson,

Grazie @homersimpson. Ma n = * a = 0 non è uguale a n = * a, * a = 0.
G. Sliepen,

2

Python 3, 104 byte

Meh.

n='\n';lambda x,y:x+n+n.join(x[:-i]for i in range(1,len(x)-1))+n+n.join(y[:i]for i in range(1,len(y)+1))

Grazie a @DJMcMayhem per giocare a golf con 21 byte di sconto.

Ideone esso!


1
Se lo fai, puoi prendere 5 byte n='\n'e usare n invece di '\n'. Potresti n='\n';lambda x,y:n.join(x+n+n.join(x[:-i]for i in range(1,len(x)-1))+n+n.join(y[:i]for i in range(1,len(y)+1)))
toglierne

2

REPL / Javascript, 109 byte

Usa una stringa falsa per ridurre la stringa originale

Abusa la sottostringa con numeri più grandi per far crescere la seconda, si interrompe quando sta per stampare la stessa parola dell'ultima volta.

(a,b)=>{l=console.log;z='substring';for(c=a.length;d=a[z](0,c--);){l(d)}for(c=2;d!=(n=b[z](0,c++));){l(d=n)}}

demo:

> ((a,b)=>{l=console.log;z='substring';for(c=a.length;d=a[z](0,c--);){l(d)}for(c=2;d!=(n=b[z](0,c++));){l(d=n)}})("asdf","abcd")
[Log] asdf
[Log] asd
[Log] as
[Log] a
[Log] ab
[Log] abc
[Log] abcd

1
è più breve di 1 byte a=>b=>...e chiama la funzione con (a) (b)
Zwei

2

Brainfuck, 38 55 byte

>++++++++++>,[>,]<[<]>>[[.>]<[-]<[<]>.>],.[[<]>.>[.>],]

Modifica: include nuove righe nell'output


Non riesco a far funzionare il tuo codice. L'input è separato da una nuova riga? Quale interprete stai usando?
acrolith,

2

Dyalog APL , 20 13 byte

↑(⌽,\⍞),1↓,\⍞

matrify

(⌽,\⍞)concatenazione cumulativa ( ,\) inversa ( ) di input di carattere ( )

, anteposto a

1↓ un elemento è caduto da

,\⍞ concatenazione cumulativa di input di caratteri

ProvaAPL online!


2

Racchetta 193 byte

(define(f l)
(let*((s(list-ref l 0))
(x(string-length s)))
(for((n x))
(println(substring s 0(- x n))))
(set! s(list-ref l 1))
(for((n(range 1(string-length s))))
(println(substring s 0(add1 n))))))

test:

(f(list "Test" "Testing"))

"Test"
"Tes"
"Te"
"T"
"Te"
"Tes"
"Test"
"Testi"
"Testin"
"Testing"


(f(list "Hello!" "Hi."))

"Hello!"
"Hello"
"Hell"
"Hel"
"He"
"H"
"Hi"
"Hi."

Dovrebbe eliminare l'ultimo carattere dalla stringa di input, non il primo.
agilob,

2

Floroide , 69 byte

a,b=L.J
c=1
NZ(a)!=1:z(a);a=a[:-1]
z(a)
NZ(a)!=Z(b):c+=1;a=b[:c];z(a)

È un inizio Prende l'input da STDIN.

Casi test

Input: Test Testing
Output:
Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Input: O O
Output: O

1

JavaScript (ES6), 92 byte

(s,t)=>s.replace(/./g,`
$\`$&`).split`
`.slice(2).reverse().join`
`+t.replace(/./g,`
$\`$&`)

Le replaceistruzioni costruiscono un triangolo di stringhe, che è esattamente ciò che è richiesto per la seconda metà dell'output, tuttavia la prima metà deve essere invertita e la riga duplicata a carattere singolo rimossa. Nota: genera una nuova riga iniziale se la prima stringa è un singolo carattere. Se ciò non è desiderabile, per un byte aggiuntivo questa versione genera sempre una nuova riga finale:

(s,t)=>s.replace(/./g,`
$\`$&\n`).split(/^/m).slice(1).reverse().join``+t.replace(/./g,`
$\`$&\n`)

1

C, 142 byte

#define _(x,y) while(y)printf("%.*s\n",d,x-c);
f(char*a,char*b){int c=1,d=strlen(a)+1;while(*++a==*++b)c++;_(a,--d>=c)d++;_(b,d++<strlen(b-c))}

Fornire f(char* str1, char* str2).


1

TI-Basic, 56 byte

Prompt Str1,Str2
Str1
While 1<length(Ans
Disp Ans
sub(Ans,1,length(Ans)-1
End
For(I,1,length(Str2
Disp sub(Str2,1,I
End

Esempio di utilizzo

Str1=?Test
Str2=?Testing
Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Str1=?O
Str2=?O
O

Str1=?z
Str2=?zz
z
zz

1

Java, 168 136 byte

(s,d)->{int i=s.length()+1;while(i-->1)System.out.println(s.substring(0,i));while(i++<d.length())System.out.println(d.substring(0,i));};

Programma di test non golfato

public static void main(String[] args) {

    BiConsumer<String, String> biconsumer = (s, d) -> {
        int i = s.length() + 1;
        while (i-- > 1) {
            System.out.println(s.substring(0, i));
        }
        while (i++ < d.length()) {
            System.out.println(d.substring(0, i));
        }
    };

    biconsumer.accept("Test", "Testing123");

}

1

(Lambdabot) Haskell - 41 byte

f=(.drop 2.inits).(++).reverse.tail.inits

Più leggibile, ma due byte in più:

a!b=(reverse.tail$inits a)++drop 2(inits b)


Produzione:

f "Hello" "Hi!"
["Hello","Hell","Hel","He","H","Hi","Hi!"]

1

J, 18 byte

]\@],~[:}:[:|.]\@[

Ungolfed:

]\@] ,~ [: }: [: |. ]\@[

Questo è un treno 7:

]\@] ,~ ([: }: ([: |. ]\@[))

Il treno più interno è [: |. ]\@[costituito da un cappuccio [:a sinistra, quindi applichiamo |.(retromarcia) al risultato di ]\@[, che è]\ (prefissi) su [(argomento di sinistra).

Ecco come appare testing, testnell'input:

   'testing' ([: |. ]\@]) 'test'
test
tes
te
t

Questo ci dà quasi la prima parte. Il 5-train al di fuori di questo è ([: }: ([: |. ]\@[)), che si applica }:(betail, rimuove l'ultimo elemento) all'espressione sopra:

   'testing' ([: }: [: |. ]\@]) 'test'
test
tes
te

(Questo perché non possiamo avere un punto medio duplicato.)

La parte esterna è finalmente:

]\@] ,~ ([: }: ([: |. ]\@[))

Questo è composto da ]\@](prefissi dell'argomento sinistro) e,~ (aggiungi ciò che è a sinistra con ciò che è a destra), lasciandoci con il risultato desiderato:

   'testing' (]\@] ,~ ([: }: ([: |. ]\@[))) 'test'
testing
testin
testi
test
tes
te
t
te
tes
test

Casi test

   k =: ]\@] ,~ ([: }: ([: |. ]\@[))
   'o' k 'o'
o
   k~ 'o'
o
   'test' k 'test'
test
tes
te
t
te
tes
test
   k~ 'test'
test
tes
te
t
te
tes
test
   '. . .' k '...'
. . .
. .
. .
.
.
..
...
   'z' k 'zz'
z
zz

Puoi riorganizzarlo a 14 byte usando(,~}:@|.)&(]\)
miglia

1

PHP, 117 109 byte

for($i=strlen($a=$argv[1]);$i>1;)echo" ".substr($a,0,$i--);
for(;$j<strlen($b=$argv[2]);)echo" ".$c.=$b[$j++];

for($i=strlen($a=$argv[1]);$i>1;)echo substr($a,0,$i--)." ";
for(;$i<=strlen($b=$argv[2]);)echo substr($b,0,$i++)." ";

PHP, 107 byte (non funzionante con stringhe contenenti 0)

for($a=$argv[1];$a[$i];)echo substr($a.a,0,-++$i)." ";
for($b=$argv[2];$b[$j];)echo substr($b,0,++$j+1)." ";

1

C, 111 byte

f(char*a, char*b){int l=strlen(a),k=1;while(*a){printf("%s\n",a);a[--l]=0;}while(b[k]) printf("%.*s\n",++k,b);}

Test non golfato

#include <stdio.h>
#include <string.h>

f(char*a, char*b) {
  int l=strlen(a), k=1;
  while(*a) {
    printf("%s\n",a);
    a[--l]=0;
  }
  while(b[k])
    printf("%.*s\n",++k,b);
}

int main() {
  char a[10] = {0};
  char b[10] = {0};

  for (int i=0; i<5; ++i) {
    a[i] = 'a' + i;
    b[i] = 'a' + i*2;
  }

  f(&(a[0]), &(b[0]));
}

1

Brainfuck, 162 byte

,[>,]++++++++++[[-<]>[->]<]++++++++++[<[+<]<[+<]>[+>]>[+>]<---]<[<]<[<]>[[.>]++++++++++.----------<[-]<[[->+<]<]>>]>[<+>-]>[[<+>-]<[<]>[.>]++++++++++.---------->]

Provalo qui

L'input prende le due stringhe separate da un avanzamento di riga.

Primo programma con brianfuck e primo codice golf quindi sono sicuro che ci sia molta ottimizzazione da fare. Mi sono divertito a farlo però.

Ungolfed

,[>,] Read all input
++++++++++ Flag for 10
[                   Subtract 10 from each cell to flag space for blank
    [-<]            
    >
        [->]
        <
]
++++++++++ Flag for 10
[                   Add 10 back to each cell with value in it
    <[+<]<[+<]
    >[+>]>[+>]<---
]
<[<]<[<]>               goto first cell in first string string      

[                           Print first word subtracting one each time
    [.>]                    Print first string
    ++++++++++.----------   Print new line
    <[-]                    Kill last letter of first string
    <                       Back one
    [                       Move each first string character up one
          [->+<]
          <
    ]>>
]
>[<+>-]>                    Move to first letter of scond string back one goto second letter
[                               
    [<+>-]                  Move next letter back
    <[<]>                   Move to start of string
    [.>]                    Print string
    ++++++++++.----------   Print new line
    >
]

Benvenuti in PPCG! Primo post impressionante!
Rɪᴋᴇʀ
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.