Backhanded ^ H ^ H ^ H ^ H ^ H ^ Hspaces

47

Em alguns terminais, pressionar backspace gera o código de controle ^Hpara excluir o caractere anterior. Isso deu origem a um idioma sarcástico, onde as edições são simuladas para efeito cômico :

Seja gentil com esse tolo ... H ^ H ^ H ^ Hgentleman, ele está visitando do QG corporativo.

Dada uma string com um ou mais ^H, produza o resultado do backspacing em cada um ^H. A entrada usará apenas caracteres imprimíveis (ASCII 32-126) e ^aparecerá apenas como ^H. Backspaces nunca acontecerão em texto vazio.

Você não pode assumir que o ambiente de saída suporta códigos de controle, em particular o código de backspace \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

Entre os melhores

Aqui está uma tabela de classificação por idioma, cortesia de Martin Büttner .

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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

xnor
fonte
4
É AAA^HB^H^Hválido?
22415 Nathan Merrill
@NathanMerrill Sim, e isso resulta em A.
Xnor
3
Eu suspeito que a retina faria bem aqui.
Claudiu
1
@Fatalize: "Backspaces nunca acontecerão em texto vazio."
Maltysen
16
@Maria Tidal Tug volta para me assombrar
Digital Trauma

Respostas:

69

GNU sed, 11 bytes

:;s/.^H//;t

Saída de teste:

$ 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
$ 
Trauma Digital
fonte
5
Olha quem apareceu! É Maria Tidal Tug ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H Trauma digital!
18780 Alex A.
@AlexA. Estou sentindo falta de uma piada?
user253751
@immibis: Veja o comentário do Digital Trauma sobre a questão.
Alex A.
sed -r ':;s/(^|.)\^H//;t'- Esta opção funciona à custa de extra de 6 bytes
aragaer
@aragaer Por que isso é necessário? O OP diz " Backspaces nunca acontecerá em texto vazio ". Eu acho que ^Ho início da string é um backspace no texto vazio.
Digital Trauma
19

Pitão, 11 bytes

.U+PbZcz"^H

Demonstração.

.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.
isaacg
fonte
17

Gema, 6 bytes

?#\^H=

Exemplo de execução:

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

CW, porque o exemplo de tolo vs. cavalheiro leva muito tempo. (Morto após um dia. Talvez uma falha no intérprete? Todos os outros exemplos aqui são processados ​​em frações de segundos.) O padrão recursivo do Gema não parece ser afetado pelo nível de recursão, mas a quantidade de texto não correspondente aumenta exponencialmente o tempo de processamento .

manatwork
fonte
Existe um link para o idioma? Uma rápida pesquisa no Github apareceu bastante
Sp3000 11/11/2015
Certo. gema.sourceforge.net (.. BTW, o projeto Gema foi registrado 2003-10-27, enquanto GitHub foi lançado 2008-04-10 Isso pode ser uma razão para não encontrá-lo lá)
manatwork
Eu acredito que a profundidade da recursão é igual ao comprimento da string não correspondente, porque ela se \^Hrepetirá repetidamente até os maches, correspondendo um caractere de cada vez ao ?.
Isaacg
15

C, 52 bytes

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

Definimos uma função fque leva um ponteiro para a string como entrada. Após a chamada da função, esse ponteiro conterá uma string modificada.

Um teste simples:

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

As impressões acima:

Digital Trauma
BrainSteel
fonte
1
Isso foi realmente inteligente. Notei algumas coisas: os globais já estão inicializados em zero, então não há necessidade de iniciar jno seu forloop (é claro que é de uso único, mas não vejo nada sobre isso nas regras :)). Você também pode combinar a atribuição com o decréscimo: j;f(char*s){for(;s[j]==94?*s--=s[j],j+=3:s++);}(47 bytes)
Cole Cameron
@ColeCameron você perdeu isso
undergroundmonorail
@undergroundmonorail dang, eu estava apenas checando duas vezes para ver se eu perdi isso. Ainda sou novo em codificar golfe, mas lembrarei disso para o futuro :). Obrigado pela informação!
Cole Cameron
1
@ColeCameron Isso tem uma modificação e acesso sem seqüência (UB), e causa um EXC_BAD_ACCESS imediato no meu compilador / máquina, infelizmente.
BrainSteel
1
@ Quentin Eu tentei isso, mas por causa da vírgula s--, j+=3e da precedência do operador, ele não funciona direito.
BrainSteel
14

Haskell, 47 bytes

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

Define uma função f :: String -> String. Como 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)
Lynn
fonte
1
Eu acho que você pode salvar um byte trocando os dois casos de he fazendo h(x,_)=xpelo caso de string vazio.
Zgarb 13/07/2015
12

CJam, 14 13 bytes

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

Como 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

ATUALIZAÇÃO: 1 byte salvo graças a jimmy23013

Experimente online aqui

Optimizer
fonte
2
1 byte mais curto: W\ts.
jimmy23013
11

Retina, 13 bytes

Retina

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

As duas linhas devem ir para seus próprios arquivos, mas você pode executar o código como um arquivo com o -ssinalizador.

Em cada etapa, excluímos a primeira correspondência .\^Hna string. Repetimos isso (com o +modificador) até que nenhuma exclusão ocorra.

randomra
fonte
Apenas uma curiosidade: por que a captura de (.*), como parece ser adiada, permanece inalterada?
11389 manatwork
1
@manatwork Desta forma, capturamos apenas o primeiro .\^Hem uma etapa. Caso contrário abc^H^H^H, resultaria ab^após o primeiro passo.
Aleatório
4
Desculpas por não implementar um limite de substituição ainda (o que provavelmente permitiria algo parecido +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>

edc65
fonte
10

Perl, 20 16 15 bytes

(Código de 14 caracteres + opção de linha de comando de 1 caractere.)

s/.\^H//&&redo

Exemplo de execução:

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.
homem a trabalhar
fonte
1
Salvar 4 caracteres:1while s/.\^H//
Kevin Reid
Uau! Isso é ótimo @KevinReid. Obrigado.
manatwork
1
Mais um:s/.\^H//&&redo
Dennis
Obrigado, @Dennis. redode alguma forma, não entrou no meu conjunto de habilidades. Terá que mudar isso.
manatwork
2
Observe que a versão do @ Dennis só funcionará (como pretendido) se for a única instrução dentro de um loop ou { }bloco. (A razão pela qual ele funciona perl -pé que o -pcomutador agrupa automaticamente seu código dentro de um whileloop.) A versão de Kevin funciona em qualquer configuração.
Ilmari Karonen
9

Julia, 58 42 41 bytes

Economizou 16 bytes graças ao manatwork e 1 graças ao Glen O!

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

Isso cria uma função recursiva que aceita uma string e retorna uma string.

Isso substitui uma ocorrência de ^Hcada vez por uma sequência vazia enquanto a entrada contém ^.

Exemplos:

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

julia> f("pizza is alright^H^H^H^H^H^Hwesome")
"pizza is awesome"
Alex A.
fonte
É a primeira vez que vejo Julia na natureza. Agradável!
Ogaday
8

REGXY, 10 bytes

Usa REGXY , um idioma baseado em substituição de regex. Substitui qualquer caractere seguido por ^ H por nada. A segunda linha então executa o que é apenas um ponteiro para a linha anterior, repetindo a substituição até que ela não corresponda.

/.\^H//
//

Isso compila e executa corretamente com o intérprete de amostra no link acima, mas a solução talvez seja um pouco atrevida, pois se baseia em uma suposição de imprecisão na especificação da linguagem. A especificação especifica que o primeiro token em cada linha (antes de /) atua como um rótulo, mas a suposição é que um ponteiro de rótulo nulo apontará de volta para o primeiro comando no arquivo com um rótulo nulo (ou seja, que 'null' é um rótulo válido). Uma solução menos atrevida seria:

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

O que equivale a 13 bytes.

Jarmex
fonte
7

Python 3, 53 bytes

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

Mas, pessoalmente, eu gosto mais desta versão mais wordier:

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

O interessante é que

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

realmente funciona e dá 'Back', então tentei mapear ^H -> [:-1]e qualquer outro caractere c -> 'c'então eval, mas infelizmente você não pode ter nenhuma sequência posteriormente sem um +, então isso falha:

'B''a''c''k''h''a''n''d''e''d'[:-1][:-1][:-1][:-1][:-1][:-1]'s''p''a''c''e''s'
Sp3000
fonte
Ei, isso é muito legal.
Alex Van Liew
+=funciona no loop
CalculatorFeline
@CatsAreFluffy É o=o[:-1]+x, nãoo=o+x
SP3000
Opa, senti falta disso. Algo como o[:-2]=xfunciona?
CalculatorFeline
@CatsAreFluffy Você não pode atribuir astr
Sp3000 11/11
7

Haskell, 52 47 bytes

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

Exemplo 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"]

Como 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
nimi
fonte
6

Ruby, 27 24 20 bytes

(Código de 19 caracteres + opção de linha de comando de 1 caractere.)

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

Graças a:

  • Ventero por sugerir o uso de variáveis ​​globais (-4 caracteres)

Exemplo de execução:

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.
homem a trabalhar
fonte
+1 Pensei em fazer uma resposta Ruby até ver isso - tenho certeza de que isso é o menor possível. Ótimo uso de []!
Daniero 11/07/2015
Havia outra versão no começo: loop{$_[/.\^H/]=""}rescue""Essa é melhor, pois demonstra a exceção de Ruby ao lidar com a frieza.
manatwork
Haha, isso é um grande :)
daniero
1
Antes tarde do que nunca: $_=$`+$'while~/.\^H/por 20 (você pode até soltar o til se não se importar com o regexp literal in conditionaviso).
Ventero
1
@manatwork: Tecnicamente, ele aparece em todas as versões do ruby> = 1.9 (literais regex e string em condições foram descontinuadas após 1.8), acho que o seu rubyainda é o padrão 1.8, enquanto irbusa o ruby ​​2.1.5.
Ventero
4

Python 2, 50

É um pouco estranho ter um segundo lambdalá, mas parece ser o melhor Python até agora.

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

Pitão - 19 bytes

Reduzir funciona muito, muito bem com isso, mas apenas um caractere de cada vez, então tive que gastar quase tantos caracteres quanto o algo real para substituir o ^Hquebra de linha. Procurando uma maneira melhor de fazer isso.

u?+GHnHbPGjbcz"^H"k

Experimente online aqui .

Maltysen
fonte
3

TeaScript , 7 bytes [Não competindo]

Não competir, pois o TeaScript foi feito após o lançamento deste desafio. Isto é aqui como referência.

xW/.\^H

Isso usa o novo TeaScript 3 e substituições recursivas para remover os caracteres

Downgoat
fonte
1
Por alguma razão, isso conta como 8859 bytes no ranking devido à ligação ISO 8859 ...
ev3commander
regerence? xD
cat
2

K5, 64 bytes

K não é realmente projetado para esse tipo de trabalho ...

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

golflua, 36 bytes

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

Exemplo de execução:

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.
homem a trabalhar
fonte
2

Javascript, 62 bytes

Não é o mais curto, mas funciona bem.

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

Provavelmente isso pode ser muito reduzido!

Ismael Miguel
fonte
1
Não é o menor e não funciona (tente qualquer um dos casos de teste). A expressão regular não deve ser global (remove / g)
edc65
@ edc65 Obrigado pela dica. Eu tentei algumas coisas e eles funcionaram. É por isso que eu postei assim
Ismael Miguel
2

R, 54 52 bytes

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

A mesma idéia básica da minha resposta de Julia . Isso cria uma função recursiva que aceita uma string e retorna uma string. Se a entrada for igual a si mesma com uma única ocorrência de ^Hremoção, retorne-a, caso contrário, chame a função novamente.

Você pode experimentá-lo online !

Alex A.
fonte
2

ECMAScript 6, 57 bytes

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

Isso provavelmente é jogável, só preciso pensar em uma maneira que provavelmente não

Downgoat
fonte
2
Que tal s=>{while(s!=(s=s.replace(/.\^H/,""));return s}?
LRN
Ou, se whilee returnforem muito longos, pode ser recursivo: #var f=s=>s==(s=s.replace(/.\^H/))?s:f(s)
1144
@lm você deve adicionar o segundo parâmetro "" para substituir. Então você tem a minha resposta :)
edc65
Verdadeiro. E o argumento de cadeia vazia precisa estar lá, eu devo ter copiado a versão errada :( #
1144
~s.indexOf`^H`pode se tornar/\^H/.test(s)
Não que Charles
2

Java, 78 77 bytes

String f(String a){while(!a.equals(a=a.replaceFirst(".\\^H","")));return a;}
Olivia Trewin
fonte
1
Você pode remover o espaço após a vírgula para salvar um caractere.
ProgramFOX
2

(Visual) FoxPro qualquer versão 80 bytes

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

Repetindo a tradução de string para vazia, localizando ^ H e fazendo backup de um caractere.

Chris
fonte
2

Julia, 41 39 bytes

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

O que está fazendo é usar ^ H como um delimitador e, em seguida, remover o último caractere de cada sequência e concatenar a próxima sequência antes de remover o último caractere novamente. Diferentemente da outra resposta de Julia, essa não é uma função recursiva.

Nota: removi o nome da função da definição. Originalmente, dizia em f(s)=vez de s->, e você o usou como f("AAA^HB^H^H")... mas estou economizando dois bytes deixando "anônimo" e use-se como seu nome. Você o usa assim:

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

(você também pode atribuir uma variável a ela como f=s->foldl((t,v)->chop(t)v,split(s,"^H")), então f("AAA^HB^H^H")funcionará)

Glen O
fonte
2

rs, 8 bytes

Tecnicamente, isso não conta, pois depende de um recurso que eu adicionei após a postagem desta pergunta. No entanto, acho bem legal.

+?1.\^H/

Demonstração ao vivo e casos de teste .

kirbyfan64sos
fonte
O novo recurso é uma substituição de limite?
Xnor
@ xnor Sim: o ?1.
Kirbyfan64sos
@Optimizer Por quê? Você está perdendo para Gema de qualquer maneira. : O
kirbyfan64sos
Sim :(. Vi o gema após postar o comentário
Otimizador
1

Python 2, 74 + 2 = 76 bytes

Eu tentei algumas abordagens até agora, este é o melhor que pude apresentar até agora.

n=input();o='';c=0
for l in n:d=l=='^';o=[o+l*(1-c),o[:-1]][d];c=d
print o
Kade
fonte
4
De onde vêm esses 2 bytes extras?
Xnor
A entrada @xnor deve estar entre aspas para que isso funcione. Eu esqueci de colocar isso no post.
Kade
1
Penso que a convenção habitual tem sido permitir que argumentos de cadeia sejam usados ​​entre aspas gratuitamente, mas não tenho muita certeza.
Xnor
1

Caxumba, 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

Provavelmente isso poderia ser reduzido em função (1 byte que eu consegui salvar em testes rápidos), mas eu meio que gosto do aspecto de uma linha ... :-)

Os aparelhos vêm do sabor de caxumba do Intersystems, que é o que eu mais gosto.

zmerch
fonte
1

Java - 123 bytes

Eu pessoalmente gosto da g---1parte da melhor.

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

  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;
  }
Stretch Maniac
fonte
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!%

A primeira linha é uma maneira de salvar alguns bytes ao longo do tempo @echo off&setLocal enableDelayedExpansion(que desativa o eco e permite a expansão atrasada das variáveis, caso você esteja se perguntando). Expliquei isso em Dicas para jogar golfe no lote .

A segunda linha é um pequeno truque para salvar o caractere de controle de backspace em uma variável. É muito hacky, e não posso fingir ter crédito por isso. É meio que explicado aqui . Basicamente, usa o comando prompt para gerar um caractere de backspace e captura-o em uma variável - nesse caso !D!.

A linha final executa a manipulação simples de cadeia de - substitua ^Hpor !D!<SPACE>!D!.

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

Infelizmente, ele rompe com casos como "AAA^HB^H^H"- onde deveria produzir "A", em vez disso produz "A"B. O que é um pouco confuso. Vou ter que analisar como a manipulação de strings em lote funciona com mais profundidade.

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

Graças a algumas pessoas úteis por aqui - agora percebo que estava apenas salvando o caractere de backspace (0x08) e, portanto, apenas substituindo os caracteres. Agora ele funciona com exemplos como o seguinte:

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