Estirar la palabra


50

La entrada es una palabra de letras minúsculas no separadas por espacios en blanco. Una nueva línea al final es opcional.

Se debe emitir la misma palabra en una versión modificada: para cada carácter, duplíquelo la segunda vez que aparece en la palabra original, triplíquelo la tercera vez, etc.

Entrada de ejemplo:

bonobo

Salida de ejemplo:

bonoobbooo

Se aplican las reglas estándar de E / S. El código más corto en bytes gana.

Pruebas proporcionadas por @Neil:

tutu -> tuttuu
queue -> queuuee
bookkeeper -> boookkkeeepeeer
repetitive -> repeetittiiveee
uncopyrightables -> uncopyrightables
abracadabra -> abraacaaadaaaabbrraaaaa
mississippi -> misssiisssssssiiipppiiii

Respuestas:


36

Jalea , 4 bytes

;\f"

Pruébalo en línea!

Cómo funciona

;\f"  Main link. Argument: S (string)

;\    Cumulatively reduce by concatenation.
      This yields the array of all prefixes of S.
  f"  Vectorized filter.
      Keep only occurrences of the nth letter in the nth prefix.

21
Bueno, entonces ... rasga a Pyth.
Adnan

2
Este sitio se está convirtiendo en una competencia por el mejor lenguaje de golf de uso general ... no es que sea algo malo.
Shelvacu el

8
@shelvacu Esto último es discutible, 2 amigos a los que les he demostrado que PPCG han dicho algo como "todas las respuestas principales solo usan idiomas de golf" como primera impresión.
Loco

@Insane hay / son. El golf de código es una cosa bastante común. Entonces los idiomas se unen para ese propósito, exclusivamente.
Evan Carslake el

¿Como funciona esto?
Erik the Outgolfer

21

Pyth, 6 bytes

Gracias a @Doorknob por despegar 1 byte.

Gracias a @Maltysen por despegar 5 bytes.

s@VQ._

Pruébalo en línea!

Cómo funciona


Por ejemplo, toma la cuerda "bonobo".

._ hace una lista: ['b', 'bo', 'bon', 'bono', 'bonob', 'bonobo']

VQ._significa "la función anterior vectorizada (aplicada en paralelo) sobre Qy ._", lo que significa que Q(la entrada evaluada) se tratará como una lista: ['b', 'o', 'n', 'o', 'b', 'o']y luego se emparejarán de la @siguiente manera:

     Q      ._         @ (intersect)
0:  'b'     'b'       'b'
1:  'o'     'bo'      'o'
2:  'n'     'bon'     'n'
3:  'o'     'bono'    'oo'
4:  'b'     'bonob'   'bb'
5:  'o'     'bonobo'  'ooo'

Por lo tanto, @VQ._producirá ['b', 'o', 'n', 'oo', 'bb', 'ooo'].

El sentonces les une todo junto, creando una cadena 'bonoobbooo', que a continuación se imprime de manera implícita a convertirse bonoobbooo.


2
Kenny, tu explicación está mal. VQsolo significa for N in Qcuando no está dentro de una función. En este caso, lo que realmente está sucediendo es que @Vsignifica la @función vectorizada (aplicada en paralelo) sobre sus siguientes dos argumentos, Qy ._. Esto falta en los documentos, así que lo arreglaré.
isaacg 05 de

14

Retina , 34 19 bytes

Ahorró 15 bytes inspirándose en la solución de Isaac.

El recuento de bytes asume la codificación ISO 8859-1.


$`¶
(\D)(?!.*\1¶)

Las líneas vacías iniciales y finales son significativas.

Pruébalo en línea!

Explicación


$`¶

Esta es una etapa de reemplazo que coincide con la expresión regular vacía (es decir, cada posición de ancho cero en la cadena) y la sustituye $`¶, donde $`es el prefijo de la coincidencia e inserta un salto de línea. Básicamente, esto calcula todos los prefijos y los coloca en una línea separada junto con el último carácter de ese prefijo:

bb
obo
oboo
kbook
kbookk
ebookke
ebookkee
pbookkeep
ebookkeepe
rbookkeeper

Habrá algunos avances de línea iniciales y finales, pero podemos ignorarlos.

De cada uno de estos prefijos queremos mantener los caracteres que son iguales al último carácter. Para eso usamos otra etapa de reemplazo:

(\D)(?!.*\1¶)

Esto coincide con todo lo que no queremos conservar y lo reemplaza por nada. Hacemos coincidir cualquier carácter ( \Dya que sabemos que no habrá dígitos en la entrada) y luego nos aseguramos de que no haya otra copia de ese carácter al final de la línea.


11

Python, 56 bytes

Parece que estoy atrapado con dos respuestas de la misma longitud:

f=lambda x,*y:x and-~y.count(x[0])*x[0]+f(x[1:],x[0],*y)
f=lambda x,y=0:x[y:]and-~x[:y].count(x[y])*x[y]+f(x,y+1)

Editar: Vea la respuesta de @ pacholik para un enfoque Python más corto y alternativo.


No estoy acostumbrado a golpearte con mis respuestas> <>, estoy esperando una respuesta Gol> <> para arreglar eso;)
Aaron

@Aaron Lástima, yo en realidad iba a golpear a usted volver a> <>: P
SP3000

¿Ruido de línea en Python? ¡Qué herejía !
gato

¿Qué hace - ~ hacer? Sé que no es bit a bit seguido de negación, pero ¿qué estás tratando de hacer para ahorrar algunos bytes?
Nic Hartley

2
@QPaysTaxes Se incrementa +1con una precedencia lo suficientemente alta como para que los padres no sean necesarios
Sp3000

10

Haskell, 39 bytes

f""=""
f x=f(init x)++filter(==last x)x

Ejemplo de uso: f "bonobo"-> "bonoobbooo".

Lo suficientemente diferente de la respuesta de @ Damien . Construye la cadena desde la derecha extrayendo todas las ocurrencias del último carácter de la cadena y anteponiendo una llamada recursiva con todos menos el último carácter.


9

> <> , 27 bytes

>i:0g1+:\
:{-1v!?:<}o
/p${/

Requiere el intérprete oficial que sale con un error al intentar imprimir el punto de código -1. Pruébalo en línea!

El código lee la entrada de un carácter a la vez y utiliza la primera fila del cuadro de código como una gran matriz que almacena la cantidad de veces que se ha visto cada carácter hasta ahora (> <> inicializa las celdas que no son del programa a 0). La segunda fila es un bucle para generar un carácter varias veces.

Alternativamente, aquí hay una versión que sale limpiamente (37 bytes, no correctamente golfizada):

>i:0(?;:0g1+:\
}o:{-1v!?:   <
v  p${<

¡Maldición, eso es bueno! Debería dejar de confiar tanto en el intérprete en línea, nunca habría pensado en usar un código tan grande, y ni siquiera sabía que el intérprete oficial salió en -1 impresión
Aaron

2
@ Aaron Sí, es un corolario de los errores de Python cuando se intenta hacer chr(-1). El intérprete animado es ideal para visualizaciones, pero desafortunadamente algunas de las discrepancias con el intérprete oficial son un poco molestas: /
Sp3000

9

JavaScript (ES6), 48 45 bytes

s=>s.replace(n=/./g,c=>c.repeat(n[c]=-~n[c]))

Editar: Guardado 3 bytes gracias a @ user81655.


8

Haskell, 50 42 41 bytes

Guardado 8 bytes gracias a Lynn

f t=[c|(i,c)<-zip[1..]t,x<-take i t,c==x]

1
Qué tal:f t=[c|(i,c)<-zip[0..]t,j<-[0..i],c==t!!j]
Lynn

8

MATL , 8 bytes

tt!=RsY"

Pruébalo en línea! O verifique todos los casos de prueba a la vez .

Explicación

t    % take input string implictly. Duplicate
t!   % duplicate and transpose into a column
=    % test for equality with broadcast. Gives an NxN array, where N is
     % input string length
R    % upper triangular part: set entries below the diagonal to 0
s    % sum of each column. For each postion in the input, gives how many
     % times that letter has appeared up to that position
Y"   % replicate elements (run-length decoding). Display implicitly

8

Laberinto , 54 25 bytes

<#; "#: ={},>
 }=}(.);("@

Otra colabo con @ MartinBüttner, que en realidad hizo más casi todo el golf para éste. ¡Al renovar el algoritmo, hemos logrado reducir el tamaño del programa bastante!

Pruébalo en línea!

Explicación

Una cartilla rápida de Labrinth:

  • Labyrinth es un lenguaje 2D basado en pila. Hay dos pilas, una pila principal y una pila auxiliar, y el estallido de una pila vacía produce cero.

  • En cada cruce, donde hay múltiples rutas para que el puntero de instrucciones se mueva hacia abajo, se comprueba la parte superior de la pila principal para ver a dónde ir después. Negativo es girar a la izquierda, cero es recto y positivo es girar a la derecha.

Las dos pilas de enteros de precisión arbitraria no tienen mucha flexibilidad en términos de opciones de memoria. Para realizar el recuento, este programa en realidad usa las dos pilas como una cinta, con el cambio de un valor de una pila a otra es similar a mover un puntero de memoria hacia la izquierda / derecha por una celda. Sin embargo, no es exactamente lo mismo, ya que necesitamos arrastrar un contador de bucle con nosotros en el camino hacia arriba.

ingrese la descripción de la imagen aquí

En primer lugar, el <y >en cada extremo muestra un desplazamiento y gira la fila de código que se desplaza por uno hacia la izquierda o hacia la derecha. Este mecanismo se utiliza para hacer que el código se ejecute en un bucle: <aparece un cero y gira la fila actual hacia la izquierda, colocando la IP a la derecha del código, y >aparece otro cero y repara la fila.

Esto es lo que sucede cada iteración, en relación con el diagrama anterior:

[Section 1]
,}    Read char of input and shift to aux - the char will be used as a counter
      to determine how many elements to shift

[Section 2 - shift loop]
{     Shift counter from aux
"     No-op at a junction: turn left to [Section 3] if char was EOF (-1), otherwise
      turn right
(     Decrement counter; go forward to [Section 4] if zero, otherwise turn right
=     Swap tops of main and aux - we've pulled a value from aux and moved the
      decremented counter to aux, ready for the next loop iteration

[Section 3]
@     Terminate

[Section 4]
;     Pop the zeroed counter
)     Increment the top of the main stack, updating the count of the number of times
      we've seen the read char
:     Copy the count, to determine how many chars to output

[Section 5 - output loop]
#.    Output (number of elements on stack) as a char
(     Decrement the count of how many chars to output; go forward to [Section 6]
      if zero, otherwise turn right
"     No-op

[Section 6]
}     Shift the zeroed counter to aux

[Section 7a]
This section is meant to shift one element at a time from main to aux until the main
stack is empty, but the first iteration actually traverses the loop the wrong way!

Suppose the stack state is [... a b c | 0 d e ...].

=     Swap tops of main and aux               [... a b 0 | c d e ...]
}     Move top of main to aux                 [... a b | 0 c d e ...]
#;    Push stack depth and pop it (no-op)
=     Swap tops of main and aux               [... a 0 | b c d e ...]
      Top is 0 at a junction - can't move
      forwards so we bounce back
;     Pop the top 0                           [... a | b c d e ... ]

The net result is that we've shifted two chars from main to aux and popped the
extraneous zero. From here the loop is traversed anticlockwise as intended.

[Section 7b - unshift loop]

#     Push stack depth; if zero, move forward to the <, else turn left
}=    Move to aux and swap main and aux, thus moving the char below (stack depth)
      to aux
;     Pop the stack depth

7

Perl, 17

(Código de 16 bytes, +1 para -p)

s/./${$&}.=$&/ge

Uso:

perl -pe 's/./${$&}.=$&/ge' <<< 'bonobo'
bonoobbooo

7

Pyth, 7 bytes

s@Led._

Banco de pruebas

Test suite gracias a DenkerAffe

Explicación:

s@Led._
     ._    All prefixes, implicitly applied to the input.
 @L        Filter each prefix for characters equal to
   ed      the last character of the prefix
s          Concatenate and implicitly print.

6

Pitón 3, 52

def f(s):*s,x=s;return s and f(s)+x+x*s.count(x)or x

44
¡Ah, ir desde el final tiene mucho más sentido! Puede hacer esto más corto en un lambda, sin la necesidad de Python 3 específicamente:f=lambda s:s and f(s[:-1])+s[-1]*s.count(s[-1])
Sp3000

Pensé que podría hacerse de esa manera. Pero no me gusta suscribir en Python: P
pacholik

5

PowerShell v2 +, 52 47 bytes

$b=@{};-join([char[]]$args[0]|%{"$_"*++$b[$_]})

Construye una tabla hash vacía, la almacena $b. Este es nuestro "contador" de las letras que hemos visto. Luego tomamos información $args[0], la convertimos como una matriz de caracteres y la enviamos a través de un bucle. Cada iteración, tomamos el carácter actual "$_"y lo multiplicamos por el contador pre-incrementado en el valor dado, lo que hará que la primera aparición se multiplique por 1, la segunda por 2y así sucesivamente. Encapsulamos eso con un, -joinpor lo que se genera una sola palabra.

Ahorré 5 bytes gracias a TessellatingHeckler mediante el uso de una tabla hash en lugar de una matriz, por lo que no tuvimos que disminuir el carácter ASCII 97para alcanzar el índice apropiado. Esto funciona porque el incremento previo del índice hash implícitamente llama .Add()en segundo plano si ese índice no existe, ya que las tablas hash son mutables.

PS C:\Tools\Scripts\golfing> .\stretch-the-word.ps1 tessellatingheckler
tessseelllattingheeeckllleeeer

@TessellatingHeckler De hecho, ¡gracias!
AdmBorkBork

5

Dyalog APL , 6 bytes

∊,\∩¨⊢

TryAPL!

4 funciones es una cima (2 trenes) de una horquilla (3 trenes):

┌──┴──┐  
∊ ┌───┼─┐
  \   ¨ ⊢
┌─┘ ┌─┘  
,   ∩    

Primero (derecha - un no-op) en la cadena dada, dando'bonobo'

Luego ,\(escaneo de concatenación) en la cadena, dando'b' 'bo' 'bon' 'bono' 'bonob' 'bonobo'

Los dos se bifurcan junto con (dados como argumentos derecho e izquierdo para) ∩¨(intersección cada uno), es decir ('b'∩'b') ('bo'∩'o') ('bon'∩'n') ('bono'∩'o') ('bonob'∩'b') ('bonobo'∩'o'), que es'b' 'o' 'n' 'oo' 'bb' 'ooo'

Finalmente, (alistar) se aplica al resultado para aplanarlo, dando'bonoobbooo'

¡Oye, al menos coincide con Pyth ! Obviamente, Jelly es más corto, ya que es una versión de golf de J, que a su vez es un dialecto avanzado de 2 caracteres por función de APL.


4

Pyth, 11 bytes

s.e*b/<Qhkb

Pruébalo aquí!

Explicación

se * b / <Qhkb # Q = input

 .e # mapa sobre la entrada con b como valor y k como índice (Q se agrega al final de forma implícita)
      <Qhk # toma los primeros k + 1 caracteres de Q
     / b # cuenta las ocurrencias de b allí
   * b # repite b muchas veces
s # une la lista resultante en una cadena

4

J, 11 bytes

#~+/@(={:)\

Este es un verbo monádico. Pruébalo aquí Uso:

   f =: #~+/@(={:)\
   f 'tutu'
'tuttuu'

Explicación

#~+/@(={:)\
     (   )\  For each non-empty prefix:
       {:      Take last element,
      =        compare for equality to the others and itself
  +/@          and take sum (number of matches).
#~           Replicate original elements wrt the resulting array.

4

05AB1E , 10 bytes

Código:

$vy«Dy¢y×?

Explicación:

$           # Push the number 1 and input
 v          # Map over the input string
  y«        # Concat the letter to the previous string (initial 1)
    D       # Duplicate this string
     y¢     # Count the occurences of the current character in the string
       y×   # Multiply this number with the current character
         ?  # Pop and print without a newline

Utiliza la codificación CP-1252 . Pruébalo en línea!


3

CJam, 14

q:A,{)A<_)--}/

Pruébalo en línea

Explicación:

q:A      read the input and store in A
,        get the string length
{…}/     for each number from 0 to length-1
  )      increment the number
  A<     get the prefix of A with that length
  _      duplicate it
  )      separate the last character
  -      remove it from the rest of the prefix
  -      remove all the remaining characters (different from the last one)
          from the prefix

2

Perl 6, 37 bytes

{.split('').map({$_ x++%.{$_}}).join}

2

> <> , 52 bytes

i:0(?;&l:?!v1-$:&:&=?\}70.>
6f+0.00o:&~/         \:o

Apila cada letra leída, las imprime una y otra vez por cada letra similar en la pila.
Utiliza el &registro, porque tener que manejar 3 variables en la pila (carta de lectura actual, posición en la pila, letra en esta posición) es una molestia.

¡Puedes probarlo aquí !


2

Óxido, 176 bytes

fn s(w:&str)->String{let mut m=std::collections::HashMap::new();w.chars().map(|c|{let mut s=m.remove(&c).unwrap_or(String::new());s.push(c);m.insert(c,s.clone());s}).collect()}

Esto usa un mapa para almacenar una cadena para cada carácter en la entrada. Para cada carácter, la cadena se eliminará del mapa, se concatenará con el carácter, se volverá a insertar en el mapa y se agregará a la salida.

Me hubiera gustado usar en get(...)lugar de remove(...), pero el comprobador de préstamos me hizo cambiar de opinión.


2

Mathcad, 66 bytes

Desafortunadamente, Mathcad no tiene un manejo de cadenas particularmente bueno, por lo que convertí la cadena de entrada a un vector y luego usé un vector (indexado con código de caracteres) para realizar un seguimiento de la cantidad de veces que se encuentra un carácter, agregando el carácter que número de veces a un vector de resultados. Finalmente, el vector resultante se convierte de nuevo en una cadena. Bastante largo por desgracia.

ingrese la descripción de la imagen aquí

Tenga en cuenta que Mathcad utiliza una interfaz 2D "pizarra", con una combinación de texto normal y operadores; los operadores normalmente se ingresan a través de una barra de herramientas o atajo de teclado; por ejemplo, ctl- # ingresa el operador de bucle for, que comprende la palabra clave for, el elemento de símbolo y 3 "marcadores de posición" vacíos para las variables de iteración, rango y expresiones corporales respectivamente. Escribir [después de que un nombre de variable ingrese al modo de índice de matriz, Typing 'ingresa un par de paréntesis coincidentes ( principalmente ... hay excepciones dependiendo de qué más hay en la expresión circundante )


2

Javascript ES6 44 bytes

q=>q.replace(/./g,a=>x[a]=(x[a]||'')+a,x=[])

vieja respuesta

Javascript ES6 46 bytes

q=>(x=[...q]).map(a=>x[a]=(x[a]||'')+a).join``

//thanks user81655 for -1 byte

1
Puede guardar un byte moviéndose xa la matriz de entrada ->q=>(x=[...q]).map(a=>x[a]=(x[a]||'')+a).join``
user81655

2

Julia, 38 35 bytes

!s=[]==s?s:[!s[1:end-1];ss[end]]

I / O está en el origen de las matrices de caracteres. Pruébalo en línea!

Cómo funciona

¡Nosotros (re) definimos el operador monádico ! para nuestros propósitos.

Cuando ! se llama, comprueba si su argumento s está vacío. Si es así, devuelve su argumento.

Si s no está vacío, intersectamos s con su último carácter ( s[end]), que produce todas las apariciones de ese carácter en s . Este resultado se concatena con el valor de retorno de una llamada recursiva a ! con s menos su último carácter ( s[1:end-1]) como argumento.


2

PHP, 54 51 50 47 bytes

for(;$C=$argn[$X++];)echo str_repeat($C,++$$C);

Corre así:

echo abracadabra | php -nR 'for(;$C=$argn[$X++];)echo str_repeat($C,++$$C); echo"\n";'

Ajustes

  • Guardado 3 bytes mediante el uso de variables variables. Se cambiaron las variables usadas a mayúsculas para evitar colisiones
  • Guardado un byte mediante la eliminación de conversión de tipo nullde intde desplazamiento de cadena, como se echa a compensar int todos modos cuerdas
  • Guardado 3 bytes usando en $argnlugar de $argv(thx Titus)

Use $argncon -Rpara guardar tres bytes más.
Titus

Ah, y -ndebería hacer lo mismo que su -d error_reporting: nsignifica no config file, y los avisos están desactivados en la configuración predeterminada; entonces -nr(respectivamente -nR) debería ser suficiente.
Titus

@Titus 2 años de edad, pero gracias de todos modos :)
Aross

1

Mathematica, 57 bytes

StringReplace[Clear@c;c@_=0;#,x_:>x~StringRepeat~++c[x]]&

Usamos c[x]como una tabla de búsqueda de la frecuencia con la que el personaje xya ha ocurrido. Esto se incrementa cada vez que se recupera x~StringRepeat~++c[x]. Desafortunadamente, para que la función sea reutilizable, necesitamos restablecer la tabla de búsqueda cada vez Clear@c;c@_=0;, lo cual es bastante costoso.


1

awk, 72 bytes

BEGIN{FS=""}{for(i=1;i<=NF;i++){a[$i]++;for(j=0;j<a[$i];j++)printf $i}}

La idea es almacenar el recuento del carácter que aparece en una matriz asociativa e imprimir el carácter este recuento veces.


1

Viga, 32 33 42 bytes

Esto debería haber sido más pequeño, pero perdí algunos bytes al inicializar las ranuras de memoria a 0. Intercambiar algunas direcciones de flujo logró eliminar mucho espacio vacío.

 >+\
vus/
>rnH
  >g'\
(@v's/
^`<

Pruébalo en este fragmento

Explicacion general.

  • Establezca todas las ranuras de memoria de 0-255 a 0
  • Lea el valor ASCII de entrada en la viga
  • Si la viga es 0 alto (viga = almacenar)
  • Obtenga el valor de la memoria [haz] en la tienda, increméntelo y guarde de nuevo
  • Disminuya la tienda a 0 imprimiendo el carácter de la viga
  • Repetir

1

Python, 66 62 bytes

Pruébalo aquí

Golfed

def s(w,o=[],n=""):
 for x in w:o+=x;n+=x*o.count(x)
 return n

Sin golf

def stretch(word):
    occurrences = []
    newWord = ""
    for w in word:
        occurrences.append(w)
        newWord += w * occurrences.count(w)
    return newWord
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.