Lentamente convierta una cuerda en otra


31

El reto

Dadas dos cadenas / una matriz de cadenas, la primera cadena se encoge lentamente y se expande nuevamente en la segunda cadena.

Puede suponer que las cadenas siempre comenzarán con el mismo carácter.

Ejemplo

Input:
"Test", "Testing"

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

Primero saca la primera palabra:

Test

Luego sigue eliminando una letra hasta que la cadena tiene un carácter de longitud:

Tes
Te
T

Luego sigue agregando una letra de la segunda palabra hasta que esté lista:

Te
Tes
Test
Testi
Testin
Testing

(si ambas cadenas tienen un carácter de longitud, simplemente envíe una de ellas una vez).

Casos de prueba

"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: en el espacio / cuarto caso de prueba, reemplace la S con espacios)

Reglas

  • Este es el , ¡así que la respuesta más corta en bytes gana! Tiebreaker es la publicación más votada. El ganador será elegido el 10/09/2016.

  • Las lagunas estándar están prohibidas.


¿Se permitirán o no 2 líneas nuevas (una línea vacía visible después de la secuencia)?
seshoumara

Respuestas:


11

Pyth, 9 bytes

j+_._Et._

Un programa que toma la segunda cadena, y luego la primera cadena, como cadenas citadas en STDIN e imprime el resultado.

Pruébalo en línea

Cómo funciona

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 bytes

òYp$xhòjòÄ$xhh

Pruébalo en línea!

Explicación:

ò     ò     "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.

Ahora, el búfer se ve así:

0123456789
012345678
01234567
0123456
012345
01234
0123
012
01
0

Solo necesitamos hacer lo mismo a la inversa para la siguiente línea:

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.

Solución alternativa más interesante :

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

3
Es como si vim es siempre la herramienta correcta para el trabajo
Downgoat

@Downgoat Exactamente. Es por eso que debes comenzar a jugar golf en V.: P
DJMcMayhem

9

Python, 93 bytes

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)

Comienza con la cadena vacía r, agrega ay una nueva línea y elimina el último carácter ahasta que aesté vacío, luego agrega las porciones requeridas by una nueva línea manteniendo un contador i, que comienza 2hasta que bse excede la longitud de , luego regresa r. Tiene una nueva línea final.

Todas las pruebas están en ideone


2 cosas. 1) Creo que has contado mal los personajes y en realidad son 93 y 2) No necesitas decirlo r="". Simple raún funcionaría.

Gracias @JackBates. 1. Correcto y actualizado: probablemente olvidé el f=. 2. Sin el r=''presente f('test','testing')no funcionaría; Sí lo f('test','testing','')haría, pero debemos seguir las especificaciones.
Jonathan Allan

Perdóname. Solo estaba mirando el código y no los ejemplos.

7

05AB1E , 9 bytes

.pRI.p¦«»

Explicación

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

Pruébalo en línea!


7

Retina, 50 41 26 bytes

Gracias a Martin Ender por guardar 15 (!) Bytes.

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

Toma entrada con las dos cadenas separadas por una nueva línea:

Test
Testing

Pruébalo en línea!

Explicación

M&!r`.+

La primera línea genera los "pasos" de ambas palabras:

Testing
Testin
Testi
Test
Tes
Te
T
Test
Tes
Te
T

Mes para el modo de coincidencia, &considera coincidencias superpuestas e !imprime las coincidencias en lugar del número de ellas. La razón por la que se invierte es la ropción de derecha a izquierda: el motor comienza a buscar coincidencias al final de la cadena y continúa hacia el principio.

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

Esto hace que todo esté en el orden correcto: Oestablece todas las coincidencias de la expresión regular posterior: un carácter en su propia línea y cada carácter (incluidas las nuevas líneas) después, que coincide con la segunda mitad completa como un fragmento, o de lo contrario, una línea de caracteres , que coincide con cada línea individual. Estas coincidencias se ordenan por punto de código, por lo que la T seguida de la nueva línea va primero, seguida de las líneas, ascendiendo por longitud.

A1`

Ahora solo tenemos esa primera línea de caracteres en la parte superior, por lo que usamos el Amodo ntigrep para descartar la primera coincidencia de la expresión regular predeterminada .+.

Versión antigua

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

¡Prueba esta versión en línea!

Explicación

La primera línea es la misma, así que vea la explicación de eso arriba.

O`\G..+¶

Esto invierte las líneas de la primera mitad (segunda palabra de entrada). En realidad, Omarca las líneas y la expresión regular limita las coincidencias: debe ser una línea de dos o más caracteres ( ..+) seguida de una nueva línea ( ) que comienza donde quedó la última ( \G). En el ejemplo anterior, el sencillo Ten el medio no coincide, por lo que nada después puede.

Te
Tes
Test
Testi
Testin
Testing
T
Test
Tes
Te
T

Ahora tenemos los dos componentes correctos, pero en el orden incorrecto.

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

¶.¶coincide con la T solitaria en el medio, que no necesitamos pero separa las dos partes. Los dos (.*)capturan todo antes y después, incluidas las nuevas líneas gracias al smodo de línea ingle. Las dos capturas se sustituyen en el orden correcto con una nueva línea en el medio.

Ahora hemos terminado, a menos que las cadenas de entrada tengan un carácter de longitud, en cuyo caso la entrada no ha cambiado. Para deshacernos del duplicado, reemplazamos ¶.$(cuando la última línea de la cadena un solo carácter) con nada.


4

Python 2, 88 82 bytes

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

Toma dos entradas, cada una entre comillas.

Gracias @JonathanAllan por guardar algunos bytes y señalar un error.


1
No es necesario el len(x)in x=x[:len(x)-1]ya que el corte en offset negativo funciona: solo puede escribir x=x[:-1]. El único problema es que su código no manejará " ", " "muy bien el caso de prueba.
Jonathan Allan

1
Puede soltar el segundo input()y usar un formato de entrada como"<str1>", "<str2>"
LevitatingLion

Puede cambiar la segunda línea a for i in range(x):print x[-i:], y la cuarta línea a for i in range(1,y):print y[:-i]. Sin embargo, no estoy seguro de que funcione.
clismique

4

Perl, 34 28 bytes

Incluye +2para-0n

Ejecutar con las cadenas en líneas separadas en STDIN:

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

slow.pl:

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

Deje que regex backtracking haga el trabajo ...


3

Cheddar , 76 bytes

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

Un poco más de lo que me hubiera gustado. Agregaré una explicación pronto

Pruébalo en línea!


¿Qué |>hacer?
Cyoce

@Cyoce unary |> es rango [0, n) binario es [a, b]
Downgoat

3

Brachylog , 32 bytes

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

Pruébalo en línea!

Explicación

Brachylog no tiene prefijo incorporado, por lo tanto, obtendremos los prefijos usando concatenate(Ver predicado 2): un prefijo de Ses Psi se Pconcatena a Q(lo que sea) da como resultado S.

  • Predicado principal:

    :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
    
  • Predicado 1:

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

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

3

Javascript, 103 81 bytes

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

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

Salida:

Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Respuesta original

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 bytes

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

Actualizar

  • Se eliminó la variable s, se guardaron 9 bytes

Sin golf :

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

Uso :

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

3

Haskell, 54 53 47 bytes

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

Ejemplo de uso: ((.reverse.t).(++).init.t) "Hello" "Hi!"-> ["Hello","Hell","Hel","He","H","Hi","Hi!"].

Un poco de magia sin puntos. Es lo mismo que f x y = (init(t x))++reverse (t y)where thace una lista de todas las subcadenas iniciales, por ejemplo, t "HI!"-> ["H","HI","HI!"].


Hm, t=reverse.tail.inits?
Bergi

@ Bergi: claro, pero initsnecesita import Data.List.
nimi


3

GNU sed, 57 45 + 2 (rn flags) = 47 bytes

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

Correr:

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

La entrada debe ser las dos cadenas separadas por una nueva línea. El código lo ejecuta sed para cada línea.

El bucle :elimina un carácter del final de la cadena de forma iterativa. La salida relacionada con la primera cadena se imprime directamente, excepto el primer carácter: 1{/../p}. La salida para la segunda cadena se almacena en el espacio de espera en orden inverso ( 2G;2h) durante la eliminación y se imprime al final.


3

C (gcc) , 102 97 95 93 bytes

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

Pruébalo en línea!

El primer bucle sobrescribe la cadena con 0 bytes a partir del final, y se utiliza puts()para imprimir la cadena. El segundo ciclo no puede simplemente sobrescribir desde el principio, sino que debe almacenar el valor anterior para que pueda volver a colocarlo; el byte 0 solo camina hacia el final.

¡Gracias a @homersimpson y @ceilingcat por cada recorte de 2 bytes!


1
Puede guardar un par de bytes al declarar ncomo int global como: n;f(char*a,char*b){n=strlen(a).... Y probablemente pueda hacerlo n=*a=0como una tarea encadenada en el cuerpo de su bucle for.
homersimpson

Gracias @homersimpson. Pero n = * a = 0 no es lo mismo que n = * a, * a = 0.
G. Sliepen

2

Python 3, 104 bytes

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

Gracias a @DJMcMayhem por jugar 21 bytes de descuento.

Ideone it!


1
Puede tomar 5 bytes de si lo hace n='\n'y usar n en lugar de '\n'. Puede quitar otros 8 si usa una lambda en lugar de imprimir: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)))
DJMcMayhem

2

REPL / Javascript, 109 bytes

Utiliza una cadena falsa para reducir la cadena original

Abusa de la subcadena con números más grandes para hacer crecer la segunda, se detiene cuando está a punto de imprimir la misma palabra que la última vez.

(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)}}

Manifestación:

> ((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
es 1 byte más corto para hacer a=>b=>...y llamar a la función con (a) (b)
Zwei

2

Brainfuck, 38 55 bytes

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

Editar: líneas nuevas incluidas en la salida


No puedo hacer que tu código funcione. ¿La entrada está separada por una nueva línea? ¿Qué intérprete estás usando?
acrolith el

2

Dyalog APL , 20 13 bytes

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

matrificar

(⌽,\⍞)invertido ( ) concatenación acumulativa ( ,\) de entrada de caracteres ( )

, antepuesto a

1↓ un elemento caído de

,\⍞ concatenación acumulativa de entrada de caracteres

TryAPL en línea!


2

Raqueta 193 bytes

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

Pruebas:

(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."

Debería eliminar el último carácter de la cadena de entrada, no el primero.
agilob

2

Floroide , 69 bytes

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)

Es un comienzo. Toma la entrada de STDIN.

Casos de prueba

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

Input: O O
Output: O

1

JavaScript (ES6), 92 bytes

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

Las replacedeclaraciones crean un triángulo de cadenas, que es exactamente lo que se requiere para la segunda mitad de la salida, sin embargo, la primera mitad debe invertirse y eliminarse la línea duplicada de un solo carácter. Nota: genera una nueva línea inicial si la primera cadena es un solo carácter. Si esto no es deseable, para un byte adicional, esta versión siempre genera una nueva línea final:

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

1

C, 142 bytes

#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))}

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


1

TI-Basic, 56 bytes

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

Ejemplo de uso

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 bytes

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

Programa de prueba sin golf

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 bytes

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

Más legible, pero dos bytes más largos:

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


Salida:

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

1

J, 18 bytes

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

Sin golf:

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

Este es un tren de 7:

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

El tren más interno [: |. ]\@[consiste en un límite [:a la izquierda, por lo que aplicamos |.(inverso) al resultado de ]\@[, que está ]\(prefijos) sobre [(argumento izquierdo).

Esto es lo que se ve en la testing, testentrada:

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

Esto nos da la primera porción, casi. El 5-tren fuera de eso es ([: }: ([: |. ]\@[)), que se aplica }:(betail, remove last element) a la expresión anterior:

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

(Esto se debe a que no podemos tener un punto medio duplicado).

La parte exterior es finalmente:

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

Esto se compone de ]\@](prefijos de argumento izquierdo) y ,~(agregue lo que está a la izquierda con lo que está a la derecha), dejándonos con el resultado deseado:

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

Casos de prueba

   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

Puede reorganizarlo a 14 bytes usando(,~}:@|.)&(]\)
millas

1

PHP, 117109 bytes

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 bytes (no funciona con cadenas que contienen 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 bytes

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

Prueba sin golf

#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 bytes

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

Pruébalo aquí

La entrada toma las dos cadenas separadas por un salto de línea.

Primer programa con brianfuck y primer código de golf, así que estoy seguro de que hay mucha optimización por hacer. Aunque me divertí mucho haciéndolo.

Sin golf

,[>,] 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
    >
]

Bienvenido a PPCG! Impresionante primer post!
Rɪᴋᴇʀ
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.