Rellenar los espacios en blanco

14

Entrada

Un entero no negativo ny una cadena no vacía que scontiene solo caracteres alfanuméricos y guiones bajos _. El primer personaje de sno es _. Los guiones bajos de sse interpretan como espacios en blanco que se pueden rellenar con otros caracteres.

Definimos una secuencia infinita de "cadenas infinitas" de la siguiente manera. La cadena se repite infinitamente muchas veces. Para todos , la cadena se obtiene al llenar sus espacios en blanco con los caracteres de , de modo que el primero de se reemplaza con , el segundo con , y así sucesivamente. Desde la primera carta des1 = s s s...sk > 1sk+1sks1_sks1[0]s1[1]s no es _, cada espacio en blanco se llena eventualmente, y denotamos por la cadena infinita donde cada uno ha sido reemplazado por su valor final.s_

Salida

El primero n caracteres de como una cadena.s

Ejemplo

Considere las entradas n = 30y s = ab_c_. Tenemos

s1 = ab_c_ab_c_ab_c_ab_c_ab_c_ab_c_ab_c_...

Sustituyendo a los espacios en blanco de , tenemoss1s1

s2 = abacbab_ccab_caabbc_abcc_abacbab_cc...

Nuevamente sustituimos a los espacios en blanco, lo que resulta ens1

s3 = abacbabaccabbcaabbc_abcccabacbab_cc...

Una sustitución más:

s4 = abacbabaccabbcaabbcaabcccabacbabbcc...

De esto ya podemos deducir los primeros 30 caracteres de , que sons

abacbabaccabbcaabbcaabcccabacb

Esta es la salida correcta.

Reglas

Puede escribir un programa completo o una función. El conteo de bytes más bajo gana, y las lagunas estándar no se permiten. Fallar en una entrada incorrecta es aceptable.

Casos de prueba

0  "ab__"    -> ""
1  "ab__"    -> "a"
3  "ab__"    -> "aba"
20 "ab"      -> "abababababababababab"
20 "ab__"    -> "abababababababababab"
20 "ab_"     -> "abaabbabaabaabbabbab"
30 "ab_c_"   -> "abacbabaccabbcaabbcaabcccabacb"
50 "ab_a_cc" -> "abaabccabaaaccabbacccabcaaccabbaaccabaaaccabcaccca"
50 "abc____" -> "abcabcaabcbcaaabcbcbcabcaaababccbcbabccabcabcaaaba"
Zgarb
fuente
¿Podemos tomar la entrada en el orden opuesto (en los idiomas donde importa el orden)?
Martin Ender
@ MartinBüttner Claro, lo permitiré.
Zgarb

Respuestas:

4

Pyth, 17

<ussC,cG\_GUQ*zQQ

La entrada debe darse con la cadena en la primera línea y la longitud en la segunda, en STDIN. Por ejemplo:

abc____
50

Pruébalo aquí.

Explicación:

                             Implicit:
                             z = input()              z is the string.
                             Q = eval(input())        Q is the length.

<               Q            First Q characters of
 u         UQ*zQ             Reduce, with an initial value of z repeated Q times, 
                             on the list range(len(Q)).
                             Since the reduce function doesn't use the sequence variable H
                             this function amounts to applying the inner code Q times to
                             the initial value, where the working variable is G.
  ss                         Sum from list of tuples of strings, to tuple of strings,
                             to string.
    C,                       Zip together
      cG\_                   G split on underscores
          G                  with G.
                             This inserts a character of G between every underscore
                             separated group of G, which amounts to replacing the
                             underscores with characters of G, after summation.
isaacg
fuente
7

APL 29 28

{a⊣(b/a)←a↑⍨+/b←'_'=a←⍺⍴⍵}⍣≡

se usa así:

fun←{a⊣(b/a)←a↑⍨+/b←'_'=a←⍺⍴⍵}⍣≡
20 fun 'ab_c_'
abacbabaccabbcaabbca

Explicación:

a←⍺⍴⍵           makes vector long as left argument using repeated chars in right argument
a↑⍨+/b←'_'=a   takes a string from the beginning of string a (a↑⍨), long as the number of _'s in a (+/b←'_'=a)
(b/a)←          puts those chars in place of the _'s in the original vector
a⊣             and returns a
{}⍣≡            repeats function ( {} ) until results doesn't change anymore

Tryapl.org

Moris Zucca
fuente
⍣≡Es una idea ingeniosa. Tal vez debería intentar portar esto a J ...
FUZxxl
7

CJam, 26 24 20 bytes

4 bytes guardados gracias a Peter.

l~:I*{_'_/[\]zsI<}I*

Pruébalo aquí. Toma la cuerda primero y nsegundo en STDIN.

Puede ejecutar todos los casos de prueba pegándolos en la entrada tal como están (incluya el -> outputsi lo desea) y utilizando el siguiente arnés de prueba (que invierte el orden del código):

qN/{"->"/0=S/W%S*

~:I*{_'_/[\]zsI<}I*

]oNo}/

Explicación

l~:I*{_'_/[\]zsI<}I*
l~                       "Read the input and evaluate.";
  :I                     "Store n in I for future use.";
    *                    "Repeat s n times to ensure it's long enough for the output.";
     {           }I*     "Repeat this block n times. This will always be enough passes.";
      _                  "Duplicate the string.";
       '_/               "Split the string on underscores.";
          [\]            "Swap with the other copy, putting both in an array.";
             z           "Zip the two arrays together, interleaving substrings from the split
                          copy with characters from the unsplit copy. Extraneous
                          characters from the unsplit copy just go at the end and
                          can be ignored.";
              s          "Convert the result into a string, flattening the array in the
                          process. This basically joins the two interleaved strings together.";
               I<        "Truncate to n characters.";

El resultado se imprime automáticamente al final del programa.

Una nota sobre [\]: En principio, [recuerda el tamaño actual de la pila y ]recoge todo hasta el último tamaño recordado en una matriz. Sin embargo, si el tamaño de la matriz cae por debajo del tamaño recordado en el medio, entonces el inicio de la matriz se ajusta en consecuencia. Ahora puede pensar que intercambiar los dos elementos superiores de la matriz no afecta en absoluto el tamaño de la matriz, sino que en \realidad muestra dos valores y luego los empuja en orden inverso. Esto es lo que empuja el inicio de la matriz hacia abajo en dos. Por lo tanto, [\]es la forma más corta de envolver los dos elementos superiores de la pila en una matriz. A veces, el efecto secundario de recopilarlos en orden inverso es bastante molesto, pero en este caso, es exactamente lo que necesito.

Martin Ender
fuente
Creo que se podría reemplazar _'_#) gcon I*. Funciona para mí en GolfScript.
Peter Taylor
@PeterTaylor oh, muy buena idea, ¡gracias!
Martin Ender
6

Python 3, 110 bytes

n=int(input())
*b,=input()*n
a=b[:n]
while"_"in a:b,a=b[:],[x*(x!="_")or b.pop(0)for x in a]
print("".join(a))

Necesita un poco más de golf, pero aquí hay algo de locura. Lee nentoncess de STDIN.

La parte divertida es que, en la asignación del bucle que copiamos b, luego comenzamos a aparecer bdurante una comprensión de la lista . Si la tarea fuera al revés, ¡no funcionaría!

Sp3000
fuente
4

k, 30

{{@[x;i;:;(#i:&"_"=x)#x]}/x#y}
tmartin
fuente
4

Java - 162 174

No todos los días puedo usar un bucle do / while al jugar golf en Java: D

Esto solo se repite y completa los espacios en blanco a medida que aparecen. Simplemente continúa hasta que no haya más _en el resultado.

char[]a(int n,char[]s){char[]o=new char[n];if(n>0)do for(int i=0,j=0;i<n;i++)if(o[i]==95|o[i]<1)o[i]=s[j++%s.length];while(new String(o).contains("_"));return o;}

Con saltos de línea:

char[]a(int n,char[]s){
    char[]o=new char[n];
    if(n>0)
        do
            for(int i=0,j=0;i<n;i++)
                if(o[i]==95|o[i]<1)
                    o[i]=s[j++%s.length];
        while(new String(o).contains("_"));
    return o;
}
Geobits
fuente
No iba a responder esto, pero la otra respuesta de Java fue demasiado larga para dejarla en pie;)
Geobits
3

Java 8, 238

(n,s)->{int i=0,j=0;for(s=String.join("",java.util.Collections.nCopies(n,new String(s))).toCharArray();j<1;){for(i=0;i<n;i++){for(;s[++j]!=95&j<n;);if(j<n)s[j]=s[i];}for(j=1,i=0;i<n;)j=s[++i]==95?0:1;}return java.util.Arrays.copyOf(s,n);}

Menos golfizado:

(Integer n, char[] s) -> {
    int i = 0, j = 0;
    for (s = String.join("", java.util.Collections.nCopies(n, new String(s))).toCharArray(); j < 1;) {
        for (i = 0; i < n; i++) {
            for (; s[j] != 95 & j < n; j++);
            if (j < n) {
                s[j] = s[i];
            }
        }
        for (j = 1, i = 0; i < n;) {
            j = s[++i] == 95 ? 0 : 1;
        }
    }
    return java.util.Arrays.copyOf(s, n);
}
Ypnypn
fuente
3

Rubí, 60

->n,s{eval"r=%1$p.chars;s.gsub!(?_){r.next};"*n%s*=n;s[0,n]}

Concatena sa si mismon veces, luego genera ncopias de código que reemplaza los guiones bajos con s, evalúa esas copias y devuelve los primeros ncaracteres del resultado. Como se elimina al menos un guión bajo en cada bucle, se garantiza que nos dará ncaracteres sin guión bajo.

histocrat
fuente
¿Cuál es la sintaxis correcta para ejecutar esto? Cuando lo llamo fy correr puts f[10,"ab_"], me sale el siguiente error: in 'eval': undefined method 'next' for #<Array:.... Sin embargo, parece funcionar cuando no hay guiones bajos en la cadena.
Théophile
Oh, interesante, parece que el comportamiento String#charscambió entre Ruby 1.9.3 y Ruby 2.0; en Ruby 1 devuelve un enumerador cuando no hay bloque, en Ruby 2 una matriz. Puede hacerse insensible a la versión cambiando charsa each_char, a costa de 4 bytes netos más de código.
histocrat
3

Pitón 2, 75

n,s=input()
S='';c=0
for x in s*n:b=x=='_';S+=S[c:c+b]or x;c+=b
print S[:n]

Esto espera una entrada como (30,"ab_c_") .

En Python, las cadenas no permiten la asignación. Por lo tanto, reemplazar los espacios en blanco con el carácter deseado es difícil. Uno puede evitar esto convirtiendo a una lista y viceversa, pero me pareció más corto simplemente generar la cadena de salida desde cero, agregando los caracteres deseados uno a la vez.

La salida que se está construyendo es S, que comienza vacía. Recorremos los caracteres de la entrada scopiados muchas veces para simular un círculo. Verificamos si está en blanco a través del booleano b. Verificamos la igualdadx=='_' lugar de la comparación porque el guión bajo se encuentra entre mayúsculas y minúsculas.

Si el personaje no está en blanco, simplemente lo agregamos S. Si está en blanco, agregamos la siguiente letra no utilizada de la salida hasta ahora S. Rastreamos letras usadas por un puntero índicec que comienza en 0 y se incrementa cada vez que encontramos un espacio en blanco.

Al final, imprimimos los primeros ncaracteres de la cadena resultante.S .

Tenemos que usar S[c:c+b]en lugar del más corto b*S[c]porque este último da un error fuera de los límites cuando Scomienza vacío y ces 0. Nunca importa porque estamos garantizados que el primer carácter sno está en blanco, por lo que esto S[c]nunca es necesario, pero el código no lo sabe. Cambiar oral cortocircuito también podría resolver esto, pero cuesta más personajes.


Pitón 2, 83

Un puerto Pyth-to-Python de la solución de isaacg , que usa splity ziprealiza el reemplazo:

n,s=input()
s*=n
exec"s=''.join(a+b for a,b in zip(s.split('_'),s));"*n
print s[:n]

Resultó más largo porque, sorpresa, los métodos con nombre son largos en Python. Pero tal vez se pueda mejorar revolviendo sy s.split('_')juntos de una manera más corta.

xnor
fuente
¡Agradable! ¡No esperaba que la reconstrucción de la cadena fuera mucho más corta!
Sp3000
3

Haskell (93) 67

No he escrito ningún Haskell en mucho tiempo, por lo que esto puede acortarse mucho. ¡pero fue tan bueno que tuvimos que acortarlo y mejorarlo!

('_':b)&(d:e)=d:b&e;(a:b)&c=a:b&c
f n s=take n$q where q=cycle s&q

Uso:

*Main> f 50 "ab_a_cc"
"abaabccabaaaccabbacccabcaaccabbaaccabaaaccabcaccca"
marinus
fuente
2

Lote - 425

¿Pierdo?

@echo off&setLocal enableDelayedExpansion&set s=%2
if "%3"=="" (for /l %%a in (1,1,%1)do set o=!o!%s%)else set o=%3
set o=!o:~0,%1!&set l=0
:c
if defined s set/al+=1&set "s=%s:~1%"&goto c
set s=%2&set/ap=%1-1
set y=&set c=0&for /l %%a in (0,1,%p%)do set x=!o:~%%a,1!&if !x!==_ (for %%b in (!c!)do set y=!y!!s:~%%b,1!&set/ac+=1)else (set y=!y!!x!)&if !c!==%l% set c=0
if "!y:_=!"=="!y!" echo !y!&goto :EOF
%0 %1 %2 !y!

El lote tiene limitaciones, acepto esto. Por ejemplo; Tuve que usar un bucle for para obtener una sola variable en un formato utilizable debido a las limitaciones de la sintaxis de análisis de variables. for %%b in (!c!)do... simplemente existe para que pueda usar en %%blugar de !c!para poder hacer la manipulación de la cadena!s:~%%b,1! y hacer que las variables se expandan en el momento correcto.

Hay un par de cosas bastante básicas que podría hacer para seguir jugando al golf, pero probablemente no por debajo de los 400 bytes. Tendré otra grieta pronto.

carne sin carne
fuente
3
A menos que alguien más publique una mejor respuesta de Batch, no lo llamaría perder :)
Sp3000
@ Sp3000 Si tan solo alguien lo hiciera.
carne sin carne
2

ECMAScript 6, 78

f=(s,n,i=0)=>[...s.repeat(n)].reduce((s,x)=>s+(x=='_'?s[i++]:x),'').slice(0,n)

Comienza con una cadena vacía y para cada aparición de guión bajo, lo reemplaza con el carácter en el siguiente índice de la cadena actual.

cPu1
fuente
1

Python 2 - 99 97 bytes


Debido a que 4 presentaciones basadas en python no son suficientes ...

n,s=input();S=s=s*n
while"_"in S:x=iter(s);S="".join(j>"_"and j or next(x)for j in S)
print S[:n]

Ejemplo:

$ python2 t.py 
(50, "ab_a_cc")
abaabccabaaaccabbacccabcaaccabbaaccabaaaccabcaccca
matsjoyce
fuente
0

ECMAScript 6, 93 91

(n,s)=>{for(x="_".repeat(n);n=0,/_/.test(x);)x=x.replace(/_/g,a=>s[n++%s.length]);return x}

Afeitado 2 personajes de la primera versión.

(n,s)=>{x="_".repeat(n);while(/_/.test(x)){n=0,x=x.replace(/_/g,a=>s[n++%s.length])}return x}
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
fuente
0

C # - 162

Robé la solución Geobits y la cambié a C #

char[]p(int n,string s){var r=new char[n];if(n>0)do for(int i=0,j=0;i<n;i++)if(r[i]=='_'||r[i]<1)r[i]=s[j++%s.Length];while(r.ToList().IndexOf('_')>=0);return r;}

1 char mejor, para que puedas mejorar Geobits;)

mike m
fuente