Espaldazo ^ H ^ H ^ H ^ H ^ H ^ Hspaces


47

En algunos terminales, presionar la tecla de retroceso genera el código de control ^Hpara eliminar el carácter anterior. Esto dio lugar a un idioma sarcástico donde las ediciones están fingidas para lograr un efecto cómico :

Sé amable con este tonto ^ H ^ H ^ H ^ Hgentleman, él está visitando desde la sede corporativa.

Dada una cadena con uno o más ^H, genera el resultado del retroceso en cada uno ^H. La entrada utilizará solo caracteres imprimibles (ASCII 32-126) y ^solo aparecerá como ^H. Los espacios de retroceso nunca sucederán en texto vacío.

No puede suponer que el entorno de salida admite códigos de control, en particular el código de retroceso \x08.

>> Horse^H^H^H^H^HCow
Cow

>> Be nice to this fool^H^H^H^Hgentleman, he's visiting from corporate HQ.
Be nice to this gentleman, he's visiting from corporate HQ.

>> 123^H45^H^H^H78^H
17

>> Digital Trauma^H^H^H^H^H^H^H^H^H^H^H^H^H^HMaria Tidal Tug^H^H^H^H^H^H^H^H^H^H^H^H^H^H^HDigital Trauma
Digital Trauma

Tabla de clasificación

Aquí hay una tabla de clasificación por idioma, cortesía de Martin Büttner .

Para asegurarse de que su respuesta se muestre, comience con un título, usando la siguiente plantilla de Markdown:

# Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes


44
Es AAA^HB^H^Hvalido?
Nathan Merrill

@NathanMerrill Sí, y da como resultado A.
xnor

3
Sospecho que a la retina le iría bien aquí.
Claudiu

1
@Fatalize: "Los espacios de retroceso nunca sucederán en texto vacío".
Maltysen

16
@Maria Tidal Tug regresa para perseguirme
Trauma digital

Respuestas:


69

GNU sed, 11 bytes

:;s/.^H//;t

Prueba de salida:

$ echo "Horse^H^H^H^H^HCow
Be nice to this fool^H^H^H^Hgentleman, he's visiting from corporate HQ.
123^H45^H^H^H78^H
Digital Trauma^H^H^H^H^H^H^H^H^H^H^H^H^H^HMaria Tidal Tug^H^H^H^H^H^H^H^H^H^H^H^H^H^H^HDigital Trauma" | sed ':;s/.^H//;t'
Cow
Be nice to this gentleman, he's visiting from corporate HQ.
17
Digital Trauma
$ 

55
¡Mira quién apareció! Es Maria Tidal Tug ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ ¡Trauma digital!
Alex A.

@AlexA. ¿Me estoy perdiendo una broma?
user253751

@immibis: Vea el comentario de Digital Trauma sobre la pregunta.
Alex A.

sed -r ':;s/(^|.)\^H//;t'- esto funciona a expensas de 6 bytes adicionales
aragaer

@aragaer ¿Por qué es eso necesario? El OP dice "Los espacios de retroceso nunca sucederán en texto vacío ". Creo que ^Hel comienzo de la cadena es un retroceso en el texto vacío.
Digital Trauma

19

Pyth, 11 bytes

.U+PbZcz"^H

Demostración.

.U+PbZcz"^H
               Implicit: z = input()
      cz"^H    z.split("^H")
.U             reduce, with the first element of the list as the initial value.
   Pb          Remove the last character of what we have so far.
  +  Z         And add on the next segment.
               Print implicitly.

17

Gema, 6 bytes

?#\^H=

Ejecución de muestra:

bash-4.3$ gema -p '?#\^H=' <<< 'pizza is alright^H^H^H^H^H^Hwesome'
pizza is awesome

CW, porque el ejemplo de tonto contra caballero lleva demasiado tiempo. (Asesinado después de un día. ¿Tal vez una falla en el intérprete? Todos los demás ejemplos aquí se procesan en fracciones de segundos.) El patrón recursivo de Gema no parece verse afectado por el nivel de recursión, pero la cantidad de texto que no coincide aumenta exponencialmente el tiempo de procesamiento .


¿Hay un enlace al idioma? Una búsqueda rápida en Github apareció bastantes
Sp3000

Seguro. gema.sourceforge.net (.. Por cierto, el proyecto Gema se registró 2003-10-27, mientras GitHub se puso en marcha 2008-04-10 Esa puede ser una razón para lo encuentra allí)
manatwork

Creo que la profundidad de recursión es igual a la longitud de la cadena no coincidente, porque se repetirá una y otra vez hasta los \^Hmaches, haciendo coincidir un carácter a la vez con el ?.
isaacg

15

C, 52 bytes

j;f(char*s){for(j=0;*s=s[j];s[j]==94?s--,j+=3:s++);}

Definimos una función fque toma un puntero a la cadena como entrada. Después de la llamada a la función, ese puntero contendrá una cadena modificada.

Una prueba simple:

int main(int argc, char** argv) {
    char buf[300] = "Digital Trauma^H^H^H^H^H^H^H^H^H^H^H^H^H^HMaria Tidal Tug^H^H^H^H^H^H^H^H^H^H^H^H^H^H^HDigital Trauma";
    f(buf);
    printf(buf);
    return 0;
}

Las impresiones anteriores:

Digital Trauma

1
Esto fue realmente inteligente. Noté un par de cosas: los globales ya están inicializados a cero, por lo que no es necesario iniciar jen su forciclo (por supuesto, es de un solo uso, pero no veo nada al respecto en las reglas :)). También puede combinar la asignación con la disminución: j;f(char*s){for(;s[j]==94?*s--=s[j],j+=3:s++);}(47 bytes)
Cole Cameron


@undergroundmonorail dang, solo estaba revisando dos veces para ver si me perdí eso. Todavía soy nuevo en el código de golf, pero lo recordaré para el futuro :). Gracias por la info!
Cole Cameron

1
@ColeCameron Eso tiene una modificación y acceso sin secuencia (UB), y desafortunadamente causa EXC_BAD_ACCESS en mi compilador / máquina.
BrainSteel

1
@Quentin Lo intenté, pero debido a la coma s--, j+=3y la precedencia del operador, no funciona bien.
BrainSteel

14

Haskell, 47 bytes

h(a,_:_:b)=f$init a++b;h(x,_)=x
f=h.span(/='^')

Define una función f :: String -> String. Cómo funciona:

    f "ab^Hc^Hd"
=== h ("ab", "^Hc^Hd")   (find ^H)
=== f ("a" ++ "c^Hd")    (backspace)
=== f "ac^Hd"            (join)
=== h ("ac", "^Hd")      (find ^H)
=== f ("a", "d")         (backspace)
=== f "ad"               (join)
=== h ("ad", "")         (find ^H)
=== "ad"                 (no ^H: base case)

1
Creo que puede guardar un byte intercambiando los dos casos hy haciendo h(x,_)=xel caso de la cadena vacía.
Zgarb

12

CJam, 14 13 bytes

q"^H"/{W\ts}*

Cómo funciona

q                   e# Read the entire input
 "^H"/              e# Split it on occurrences of string "^H"
      {    }*       e# Reduce on the split array
       W\t          e# This is the tricky part. We know that if there are two parts that we
                    e# are reducing on, they must be separated by "^H". Which in turn means
                    e# that from the first part, last characters needs to be deleted
                    e# So we simply put the second part in place of the last character of the
                    e# first part.
          s         e# Doing the above makes it a mixed array of character and string.
                    e# So we convert it to a single string, ready to be served as first part
                    e# in next reduce iteration

ACTUALIZACIÓN: 1 byte guardado gracias a jimmy23013

Pruébalo en línea aquí


2
1 byte más corto: W\ts.
jimmy23013

11

Retina, 13 bytes

Retina

+`.\^H(.*)
$1

Las dos líneas deben ir a sus propios archivos, pero puede ejecutar el código como un archivo con la -sbandera.

En cada paso eliminamos la primera coincidencia de .\^Hla cadena. Repetimos esto (con el +modificador) hasta que no se elimine.


Solo una curiosidad: ¿por qué la captura de (.*), ya que parece ser simplemente puesta sin cambios?
manatwork

1
@manatwork De esta manera solo capturamos el primero .\^Hen un solo paso. De abc^H^H^Hlo contrario resultaría ab^después del primer paso.
randomra

44
Disculpas por no implementar un límite de reemplazo todavía (lo que probablemente permitiría algo así +1`.\^H). ;)
Martin Ender

10

JavaScript ( ES6 ), 39 bytes

f=s=>(t=s.replace(/.\^H/,''))!=s?f(t):t

// TEST

Out=x=>O.innerHTML+=x+'\n'

Test=_=>(Out(I.value + "\n-> " + f(I.value)),I.value='')

;["Horse^H^H^H^H^HCow"
,"Be nice to this fool^H^H^H^Hgentleman, he's visiting from corporate HQ."
,"123^H45^H^H^H78^H"
,"Digital Trauma^H^H^H^H^H^H^H^H^H^H^H^H^H^HMaria Tidal Tug^H^H^H^H^H^H^H^H^H^H^H^H^H^H^HDigital Trauma"]
.forEach(t => Out(t + "\n-> " + f(t)))
#I { width:400px }
<pre id=O></pre>
<input id=I><button onclick='Test()'>-></button>


10

Perl, 20 16 15 bytes

(Código de 14 caracteres + opción de línea de comando de 1 carácter).

s/.\^H//&&redo

Ejecución de muestra:

bash-4.3$ perl -pe 's/.\^H//&&redo' <<< "Be nice to this fool^H^H^H^Hgentleman, he's visiting from corporate HQ."
Be nice to this gentleman, he's visiting from corporate HQ.

1
Guardar 4 personajes:1while s/.\^H//
Kevin Reid

¡Guauu! Eso es genial @KevinReid. Gracias.
manatwork

1
Uno más:s/.\^H//&&redo
Dennis

Gracias @ Dennis. redode alguna manera no llegó a mi conjunto de habilidades. Tendrá que cambiar eso.
manatwork

2
Tenga en cuenta que la versión de @ Dennis solo funcionará (según lo previsto) si es la única instrucción dentro de un bucle o un { }bloque. (La razón por la que funciona perl -pes que el -pinterruptor envuelve automáticamente su código dentro de un whilebucle). La versión de Kevin funciona en cualquier entorno.
Ilmari Karonen

9

Julia, 58 42 41 bytes

¡Ahorré 16 bytes gracias a manatwork y 1 gracias a Glen O!

f(s)='^'s?f(replace(s,r".\^H","",1)):s

Esto crea una función recursiva que acepta una cadena y devuelve una cadena.

Esto reemplaza una aparición de ^Ha la vez con una cadena vacía mientras la entrada contiene ^.

Ejemplos:

julia> f("123^H45^H^H^H78^H")
"17"

julia> f("pizza is alright^H^H^H^H^H^Hwesome")
"pizza is awesome"

Esta es la primera vez que veo a Julia en la naturaleza. ¡Agradable!
Ogaday

8

REGXY, 10 bytes

Utiliza REGXY , un lenguaje basado en la sustitución de expresiones regulares. Reemplaza cualquier carácter seguido de ^ H con nada. Luego se ejecuta la segunda línea, que es solo un puntero a la línea anterior, repitiendo la sustitución hasta que no coincida.

/.\^H//
//

Esto compila y se ejecuta correctamente con el intérprete de muestra en el enlace anterior, pero la solución es quizás un poco descarada ya que se basa en una suposición en la imprecisión de la especificación del lenguaje. La especificación establece que el primer token en cada línea (antes de /) actúa como una etiqueta, pero se supone que un puntero de etiqueta nulo apuntará de nuevo al primer comando en el archivo con una etiqueta nula (o en otras palabras, ese 'nulo' es una etiqueta válida). Una solución menos descarada sería:

a/.\^H//
b//a

Lo que equivale a 13 bytes.


7

Python 3, 53 bytes

o=""
for x in input().split("^H"):o=o[:-1]+x
print(o)

Pero personalmente me gusta más esta versión más prolija:

H=input().split("^H")
print(eval("("*~-len(H)+")[:-1]+".join(map(repr,H))))

Lo interesante es que

'B''a''c''k''h''a''n''d''e''d'[:-1][:-1][:-1][:-1][:-1][:-1]

en realidad funciona y da 'Back', así que intenté mapear ^H -> [:-1]y cualquier otro carácter en c -> 'c'ese momento eval, pero desafortunadamente no puedes tener ninguna secuencia después sin un +, así que esto falla:

'B''a''c''k''h''a''n''d''e''d'[:-1][:-1][:-1][:-1][:-1][:-1]'s''p''a''c''e''s'

Heyy ... eso es bastante bueno.
Alex Van Liew

+=funciona en el bucle
CalculatorFeline

Es @CatsAreFluffy o=o[:-1]+x, noo=o+x
SP3000

Vaya, me perdí eso. ¿Algo como el o[:-2]=xtrabajo?
CalculatorFeline

@CatsAreFluffy No puede asignar astr
Sp3000

7

Haskell, 52 47 bytes

import Data.Lists
foldl1((++).init).splitOn"^H"

Ejemplo de uso:

> map (foldl1((++).init).splitOn"^H") ["Horse^H^H^H^H^HCow", "123^H45^H^H^H78^H", "Digital Trauma^H^H^H^H^H^H^H^H^H^H^H^H^H^HMaria Tidal Tug^H^H^H^H^H^H^H^H^H^H^H^H^H^H^HDigital Trauma"]
["Cow","17","Digital Trauma"]

Cómo funciona:

                  splitOn"^H"     -- split on substring "^H", e.g "Horse^H^H^H^H^HCow" -> ["Horse","","","","","Cow"]
                 .                -- then
foldl1(         )                 -- fold from left by
            init                  --   first dropping the last char from the left argument
       (++).                      --   second concatenating left and right argument

6

Rubí, 27 24 20 bytes

(Código de 19 caracteres + opción de línea de comando de 1 carácter).

$_=$`+$'while/.\^H/

Gracias a:

  • Ventero por sugerir utilizar las variables globales (-4 caracteres)

Ejecución de muestra:

bash-4.3$ ruby -pe '$_=$`+$'"'"'while/.\^H/' <<< "Be nice to this fool^H^H^H^Hgentleman, he's visiting from corporate HQ."
Be nice to this gentleman, he's visiting from corporate HQ.

+1 Pensé que haría una respuesta de Ruby hasta que vi esto. Estoy bastante seguro de que es tan pequeño como pueda ser. Gran uso de []!
daniero

Había otra versión al principio: loop{$_[/.\^H/]=""}rescue""esta es mejor, ya que demuestra la frialdad de manejo de excepciones de Ruby.
manatwork

Jaja, esa es genial :)
daniero

1
Más vale tarde que nunca: $_=$`+$'while~/.\^H/por 20 (incluso puedes soltar la tilde si no te importa la regexp literal in conditionadvertencia).
Ventero

1
@manatwork: Técnicamente aparece en todas las versiones de ruby> = 1.9 (los literales regex y string en condiciones quedaron en desuso después de 1.8), supongo que rubysimplemente sigue siendo predeterminado 1.8, mientras que irbusa ruby ​​2.1.5.
Ventero

4

Pitón 2, 50

Es un poco extraño tener un segundo lambdaallí, pero parece ser el mejor Python hasta ahora.

lambda s:reduce(lambda a,b:a[:-1]+b,s.split('^H'))

3

Pyth - 19 bytes

Reducir funciona muy, muy bien con esto, pero solo tiene un carácter a la vez, por lo que tuve que gastar casi tantos caracteres como el algoritmo real para reemplazar un ^Hsalto de línea. Buscando una mejor manera de hacerlo.

u?+GHnHbPGjbcz"^H"k

Pruébelo en línea aquí .


3

TeaScript , 7 bytes [No compite]

No compitió ya que TeaScript se creó después de publicar este desafío. Esto está aquí como referencia.

xW/.\^H

Utiliza el nuevo TeaScript 3, y reemplaza recursivamente para eliminar los caracteres.


1
Por alguna razón, esto cuenta como 8859 bytes en la tabla de clasificación debido al enlace ISO 8859 ...
ev3commander

regerence? xD
gato

2

K5, 64 bytes

K no está realmente diseñado para este tipo de trabajo ...

{[s]$[2>#s;s;`=t:*&{"^H"~2#x_s}'1+!-2+#s;s;,/2#2!|(0,t,3+t)_s]}/

2

golflua, 36 bytes

\f(s)@o!=s o=s;s=s:g(".^H","",1)$~s$

Ejecución de muestra:

Lua 5.2.2  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> \f(s)@o!=s o=s;s=s:g(".^H","",1)$~s$
> w(f("Be nice to this fool^H^H^H^Hgentleman, he's visiting from corporate HQ."))
Be nice to this gentleman, he's visiting from corporate HQ.

2

Javascript, 62 bytes

No es el más corto, pero funciona bien.

t=prompt();while(t.match(R=/.\^H/))t=t.replace(R,'');alert(t);

¡Esto probablemente se puede acortar mucho!


1
No es el más corto y tampoco funciona (pruebe cualquiera de los casos de prueba). La
expresión regular

@ edc65 Gracias por el consejo. Intenté algunas cosas y funcionaron. Es por eso que publiqué así
Ismael Miguel

2

R, 54 52 bytes

f=function(s)ifelse(s==(r=sub(".\\^H","",s)),r,f(r))

La misma idea básica que mi respuesta de Julia . Esto crea una función recursiva que acepta una cadena y devuelve una cadena. Si la entrada es igual a sí misma con una sola ocurrencia de ^Heliminación, devuélvala, de lo contrario, llame a la función nuevamente.

¡Puedes probarlo en línea !


2

ECMAScript 6, 57 bytes

s=>{while(~s.indexOf`^H`)s=s.replace(/.\^H/,'');return s}

Esto es probablemente golfable, solo tengo que pensar en una forma que probablemente no


2
¿Qué tal s=>{while(s!=(s=s.replace(/.\^H/,""));return s}?
lrn

O, si whiley returnson demasiado largos, podría ser recursivo:var f=s=>s==(s=s.replace(/.\^H/))?s:f(s)
LRN

@lm debe agregar el segundo parámetro "" para reemplazar. Entonces tienes mi respuesta :)
edc65

Cierto. Y el argumento de cadena vacía debe estar allí, debo haber copiado la versión incorrecta :(
lrn

~s.indexOf`^H`puede convertirse/\^H/.test(s)
No es que Charles

2

Java, 78 77 bytes

String f(String a){while(!a.equals(a=a.replaceFirst(".\\^H","")));return a;}

1
Puede eliminar el espacio después de la coma para guardar un carácter.
ProgramFOX

2

(Visual) FoxPro cualquier versión 80 bytes

PARA t
DO WHILE AT('^H',t)>0
t = STRT(t,SUBS(t,AT('^H',t)-1,3))
ENDDO
RETU t

Repetir la traducción de la cadena al vacío al encontrar ^ H y hacer una copia de seguridad de un carácter.


2

Julia, 41 39 bytes

s->foldl((t,v)->chop(t)v,split(s,"^H"))

Lo que está haciendo es usar ^ H como delimitador, y luego eliminar el último carácter de cada cadena y luego concatenar la siguiente cadena antes de eliminar nuevamente el último carácter. A diferencia de la otra respuesta de Julia, esta no es una función recursiva.

Nota: he eliminado el nombre de la función de la definición. Originalmente, decía f(s)=más que s->, y lo usaste como f("AAA^HB^H^H")... pero estoy ahorrando dos bytes al dejar que sea "anónimo", y usarlo como su nombre. Lo usas así:

(s->foldl((t,v)->chop(t)v,split(s,"^H")))("AAA^HB^H^H")

(también puede asignarle una variable como f=s->foldl((t,v)->chop(t)v,split(s,"^H")), entonces f("AAA^HB^H^H")funcionará)


2

rs, 8 bytes

Técnicamente, esto no cuenta, ya que depende de una característica que agregué después de que se publicó esta pregunta. Sin embargo, creo que es bastante bueno.

+?1.\^H/

Demostración en vivo y casos de prueba .


¿La nueva característica es un reemplazo de límite?
xnor

@xnor Sí: el ?1.
kirbyfan64sos

@Optimizer ¿Por qué? Estás perdiendo con Gema de todos modos. : O
kirbyfan64sos

Sí :(. Vi a Gema después de publicar un comentario
Optimizer

1

Python 2, 74 + 2 = 76 bytes

He intentado algunos enfoques hasta ahora, este es el mejor que he podido encontrar hasta ahora.

n=input();o='';c=0
for l in n:d=l=='^';o=[o+l*(1-c),o[:-1]][d];c=d
print o

44
¿De dónde vienen esos 2 bytes adicionales?
xnor

La entrada @xnor tiene que estar entre comillas para que esto funcione. Olvidé poner eso en la publicación.
Kade

1
Creo que la convención habitual ha sido permitir que los argumentos de cadena se tomen entre comillas de forma gratuita, pero no estoy totalmente seguro.
xnor

1

Paperas, 84 bytes

R Z S T="",Y=$L(Z,"^H") F I=1:1:Y{S T=T_$P(Z,"^H",I) S:I<Y T=$E(T,1,$L(T)-1)} W !,T

Esto probablemente podría acortarse como una función (1 byte que pude guardar en pruebas rápidas) pero me gusta el aspecto de una línea ... :-)

Las llaves provienen del sabor Intersystems Cache de Paperas, que es lo que más conozco.


1

Java - 123 bytes

Personalmente, me gusta la g---1parte que mejor.

String f(char[] a){String b="";for(int g=-1;++g<a.length;b=(a[g++]=='^'?b.substring(0,b.length()-1):b+a[g---1]));return b;}

expandido (ligeramente):

  String f(char[] a) {
      String b = "";
      for (int g = -1;
           ++g < a.length;
           b = (a[g++]=='^' 
                ? b.substring(0, b.length() - 1) 
                : b + a[g---1])
      );
      return b;
  }

1

Lote - 138 bytes

@!! 2>nul||cmd/q/v/c%0 %1&&exit/b
set s=%1&for /F %%a in ('"prompt $H&echo on&for %%b in (1)do rem"')do set D=%%a
echo %s:^H=!D! !D!%

La primera línea es una forma de guardar unos pocos bytes a lo largo @echo off&setLocal enableDelayedExpansion(lo que desactiva el eco y permite la expansión retardada de las variables, en caso de que se lo pregunte). Lo expliqué en Tips for Golfing in Batch .

La segunda línea es un pequeño truco para guardar el carácter de control de retroceso en una variable. Es bastante hacky, y no puedo pretender tomar el crédito por ello. Se explica más o menos aquí . Básicamente usa el comando prompt para generar un carácter de retroceso y lo captura en una variable, en este caso !D!.

La línea final realiza la simple manipulación de cadenas de - reemplazar ^Hcon !D!<SPACE>!D!.

C:\>bsp.bat "testing^H^H^H test"
"test test"

Desafortunadamente, rompe con casos como "AAA^HB^H^H": donde debería producir "A", en su lugar produce "A"B. Lo cual es algo confuso. Tendré que analizar cómo funciona la manipulación de cadenas de Batch con más profundidad.

C:\>bsp.bat "AAA^HB^H^H"
"A"B

Gracias a algunas personas útiles por aquí , ahora me doy cuenta de que solo estaba guardando el carácter de retroceso (0x08), por lo que solo estaba sobrescribiendo los caracteres. Ahora funciona con ejemplos como los siguientes:

C:\>bsp.bat "AAA^HB^H^H"
"A"
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.