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

47

2

On some terminals, pressing backspace generates the control code ^H to delete the previous character. This gave rise to a snarky idiom where edits are feigned for comedic effect:

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

Given a string with one or more ^H's, output the result of backspacing on each ^H. The input will use only printable characters (ASCII 32-126), and ^ will only appear as ^H. Backspaces will never happen on empty text.

You may not assume that the output environment supports control codes, in particular the backspace code \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

Leaderboard

Here's a by-language leaderboard, courtesy of Martin Büttner.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

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

function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/52946/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function getAnswers(){$.ajax({url:answersUrl(page++),method:"get",dataType:"jsonp",crossDomain:true,success:function(e){answers.push.apply(answers,e.items);if(e.has_more)getAnswers();else process()}})}function shouldHaveHeading(e){var t=false;var n=e.body_markdown.split("\n");try{t|=/^#/.test(e.body_markdown);t|=["-","="].indexOf(n[1][0])>-1;t&=LANGUAGE_REG.test(e.body_markdown)}catch(r){}return t}function shouldHaveScore(e){var t=false;try{t|=SIZE_REG.test(e.body_markdown.split("\n")[0])}catch(n){}return t}function getAuthorName(e){return e.owner.display_name}function process(){answers=answers.filter(shouldHaveScore).filter(shouldHaveHeading);answers.sort(function(e,t){var n=+(e.body_markdown.split("\n")[0].match(SIZE_REG)||[Infinity])[0],r=+(t.body_markdown.split("\n")[0].match(SIZE_REG)||[Infinity])[0];return n-r});var e={};var t=1;answers.forEach(function(n){var r=n.body_markdown.split("\n")[0];var i=$("#answer-template").html();var s=r.match(NUMBER_REG)[0];var o=(r.match(SIZE_REG)||[0])[0];var u=r.match(LANGUAGE_REG)[1];var a=getAuthorName(n);i=i.replace("{{PLACE}}",t++ +".").replace("{{NAME}}",a).replace("{{LANGUAGE}}",u).replace("{{SIZE}}",o).replace("{{LINK}}",n.share_link);i=$(i);$("#answers").append(i);e[u]=e[u]||{lang:u,user:a,size:o,link:n.share_link}});var n=[];for(var r in e)if(e.hasOwnProperty(r))n.push(e[r]);n.sort(function(e,t){if(e.lang>t.lang)return 1;if(e.lang<t.lang)return-1;return 0});for(var i=0;i<n.length;++i){var s=$("#language-template").html();var r=n[i];s=s.replace("{{LANGUAGE}}",r.lang).replace("{{NAME}}",r.user).replace("{{SIZE}}",r.size).replace("{{LINK}}",r.link);s=$(s);$("#languages").append(s)}}var QUESTION_ID=45497;var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";var answers=[],page=1;getAnswers();var SIZE_REG=/\d+(?=[^\d&]*(?:&lt;(?:s&gt;[^&]*&lt;\/s&gt;|[^&]+&gt;)[^\d&]*)*$)/;var NUMBER_REG=/\d+/;var LANGUAGE_REG=/^#*\s*((?:[^,\s]|\s+[^-,\s])*)/
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src=https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js></script><link rel=stylesheet type=text/css href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><div id=answer-list><h2>Leaderboard</h2><table class=answer-list><thead><tr><td></td><td>Author<td>Language<td>Size<tbody id=answers></table></div><div id=language-list><h2>Winners by Language</h2><table class=language-list><thead><tr><td>Language<td>User<td>Score<tbody id=languages></table></div><table style=display:none><tbody id=answer-template><tr><td>{{PLACE}}</td><td>{{NAME}}<td>{{LANGUAGE}}<td>{{SIZE}}<td><a href={{LINK}}>Link</a></table><table style=display:none><tbody id=language-template><tr><td>{{LANGUAGE}}<td>{{NAME}}<td>{{SIZE}}<td><a href={{LINK}}>Link</a></table>

xnor

Posted 2015-07-10T21:43:20.737

Reputation: 115 687

4Is AAA^HB^H^H valid? – Nathan Merrill – 2015-07-10T21:47:41.753

@NathanMerrill Yes, and it results in A. – xnor – 2015-07-10T21:54:16.743

3

I suspect retina would do well here.

– Claudiu – 2015-07-10T21:55:33.110

is ^HAvalid? More generally, can strings start with a useless backspace? – Fatalize – 2015-07-10T22:05:55.580

1@Fatalize: "Backspaces will never happen on empty text." – Maltysen – 2015-07-10T22:06:25.233

16@Maria Tidal Tug comes back to haunt me – Digital Trauma – 2015-07-10T23:18:38.447

The URL in the leaderboard snippet should be https://, since the snippet doesn't work in newer versions of Chrome that don't load insecure resources on pages loaded over HTTPS. – Frxstrem – 2015-07-11T22:12:18.293

@Frxstrem Changed it to https. – xnor – 2015-07-13T07:19:54.927

I tried to implement this in the correct language for such a problem, chicken, but I'm new to chicken and gave up eventually... I'd love to see if any senior chicken developers could post a solution. – Mark K Cowan – 2015-07-13T10:03:35.620

@Frxstrem Or // – user253751 – 2015-07-14T04:16:57.107

May we take input with actual backspaces? – Adám – 2017-04-24T14:51:47.110

@Adám No, use ^H's. – xnor – 2017-04-24T20:42:47.117

Suggested test case from ~3 years into the future: H^Hello H^HLarry! – Erik the Outgolfer – 2018-06-03T18:17:24.893

Answers

69

GNU sed, 11 bytes

:;s/.^H//;t

Test output:

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

Digital Trauma

Posted 2015-07-10T21:43:20.737

Reputation: 64 644

5Look who showed up! It's Maria Tidal Tug^H^H^H^H^H^H^H^H^H^H^H^H^H^H^HDigital Trauma! – Alex A. – 2015-07-13T18:43:05.693

@AlexA. Am I missing an in-joke? – user253751 – 2015-07-14T01:59:54.223

@immibis: See Digital Trauma's comment on the question.

– Alex A. – 2015-07-14T02:01:00.013

sed -r ':;s/(^|.)\^H//;t' - this works at expense of extra 6 bytes – aragaer – 2015-07-15T10:40:11.607

@aragaer Why is that necessary? The OP says "Backspaces will never happen on empty text". I think a ^H the beginning of the string is a backspace on empty text. – Digital Trauma – 2015-07-15T15:05:16.167

I thought it was valid to press backspace more times than there are characters in front of it.... I do it all the time myself! – aragaer – 2015-07-15T16:27:55.483

19

Pyth, 11 bytes

.U+PbZcz"^H

Demonstration.

.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

Posted 2015-07-10T21:43:20.737

Reputation: 39 268

17

Gema, 6 bytes

?#\^H=

Sample run:

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

CW, because the fool vs. gentleman example takes far too long. (Killed after a day. Maybe a glitch in the interpreter? All other examples here are processed in fractions of seconds.) Gema's recursive pattern not seems to be affected by the recursion level, but the amount of non-matching text increases processing time exponentially.

manatwork

Posted 2015-07-10T21:43:20.737

Reputation: 17 865

Is there a link to the language? A quick search on Github turned up quite a few – Sp3000 – 2015-07-11T10:29:17.197

Sure. http://gema.sourceforge.net/ (BTW, the Gema project was registered 2003-10-27, while GitHub was launched 2008-04-10. That may be a reason to not find it there.)

– manatwork – 2015-07-11T10:32:50.833

I believe the recursion depth is equally to the length of the non-matching string, because it will recurse again and again until the \^H maches, matching one character at a time to the ?. – isaacg – 2015-07-11T22:11:54.953

15

C, 52 bytes

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

We define a function f that takes a pointer to the string as input. After the function call, that pointer will contain a modified string.

A simple test:

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

The above prints:

Digital Trauma

BrainSteel

Posted 2015-07-10T21:43:20.737

Reputation: 5 132

1This was really clever. A couple things I noticed: globals are already initialized to zero, so no need to init j in your for loop (of course then it's single use, but I don't see anything about that in the rules :) ). You can also combine the assignment with the decrement: j;f(char*s){for(;s[j]==94?*s--=s[j],j+=3:s++);} (47 bytes) – Cole Cameron – 2015-07-11T03:46:12.247

@ColeCameron you missed this

– undergroundmonorail – 2015-07-11T03:56:27.730

@undergroundmonorail dang, I was just double checking to see if I missed that. I'm still new to code golf but I'll remember that for the future :). Thanks for the info! – Cole Cameron – 2015-07-11T04:02:05.373

@ColeCameron No problem, it's easy to miss stuff (and it's good that you checked at all :P) – undergroundmonorail – 2015-07-11T04:07:16.253

1@ColeCameron That has an unsequenced modification and access (UB), and causes an immediate EXC_BAD_ACCESS on my compiler/machine, unfortunately. – BrainSteel – 2015-07-11T14:51:05.060

You can replace == with ^ if you swap the last operands of ?: :) – Quentin – 2015-07-12T20:06:54.667

1@Quentin I tried that, but because of the comma in s--, j+=3 and operator precedence, it doesn't work right. – BrainSteel – 2015-07-12T20:36:00.203

@BrainSteel oh, right. – Quentin – 2015-07-12T20:37:36.223

14

Haskell, 47 bytes

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

Defines a function f :: String -> String. How it works:

    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

Posted 2015-07-10T21:43:20.737

Reputation: 55 648

1I think you can save a byte by swapping the two cases of h and doing h(x,_)=x for the empty string case. – Zgarb – 2015-07-13T07:17:46.813

12

CJam, 14 13 bytes

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

How it works

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

UPDATE: 1 byte saved thanks to jimmy23013

Try it online here

Optimizer

Posted 2015-07-10T21:43:20.737

Reputation: 25 836

21 byte shorter: W\ts. – jimmy23013 – 2015-07-10T22:43:40.320

11

Retina, 13 bytes

Retina

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

The two lines should go to their own files but you can run the code as one file with the -s flag.

At each step we delete the first match for .\^H in the string. We repeat this (with the + modifier) until no deletion happens.

randomra

Posted 2015-07-10T21:43:20.737

Reputation: 19 909

Just a curiosity: why the capturing of (.*), as it seems to be just put back unchanged? – manatwork – 2015-07-11T11:21:58.227

1@manatwork This way we only capture the first .\^H in one step. Otherwise abc^H^H^H would result in ab^ after the first step. – randomra – 2015-07-11T11:55:31.487

4Apologies for not implementing a replacement limit yet (which would probably allow something like +1\.^H`). ;) – Martin Ender – 2015-07-11T12:19:58.560

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

Posted 2015-07-10T21:43:20.737

Reputation: 31 086

10

Perl, 20 16 15 bytes

(14 characters code + 1 character command line option.)

s/.\^H//&&redo

Sample run:

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.

manatwork

Posted 2015-07-10T21:43:20.737

Reputation: 17 865

1Save 4 characters: 1while s/.\^H// – Kevin Reid – 2015-07-11T14:48:52.967

Wow! That's great @KevinReid. Thank you. – manatwork – 2015-07-11T15:00:22.933

1One more: s/.\^H//&&redo – Dennis – 2015-07-11T19:12:09.407

Thank you, @Dennis. redo somehow not made its way into my skill set. Will have to change that. – manatwork – 2015-07-12T09:33:15.587

2Note that @Dennis's version will only work (as intended) if it's the only statement inside a loop or a { } block. (The reason why it works with perl -p is that the -p switch automatically wraps your code inside a while loop.) Kevin's version works in any setting. – Ilmari Karonen – 2015-07-12T10:29:06.907

9

Julia, 58 42 41 bytes

Saved 16 bytes thanks to manatwork and 1 thanks to Glen O!

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

This creates a recursive function that accepts a string and returns a string.

This replaces one occurrence of ^H at a time with an empty string while the input contains ^.

Examples:

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.

Posted 2015-07-10T21:43:20.737

Reputation: 23 761

This is the first time I've seen Julia in the wild. Nice! – Ogaday – 2016-02-09T16:27:01.580

8

REGXY, 10 bytes

Uses REGXY, a regex substitution based language. Replaces any character followed by ^H with nothing. The second line then executes which is just a pointer to the previous line, repeating the substitution until it fails to match.

/.\^H//
//

This compiles and executes correctly with the sample interpreter in the link above, but the solution is perhaps a bit cheeky as it relies on an assumption in the vagueness of the language specification. The spec states that the first token on each line (before the /) acts as a label, but the assumption is that a null label-pointer will point back to the first command in the file with a null label (or in other words, that 'null' is a valid label). A less cheeky solution would be:

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

Which amounts to 13 bytes.

Jarmex

Posted 2015-07-10T21:43:20.737

Reputation: 2 045

7

Python 3, 53 bytes

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

But personally I like this wordier version better:

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

The interesting thing is that

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

actually works and gives 'Back', so I tried to map ^H -> [:-1] and any other char c -> 'c' then eval, but unfortunately you can't have any strings afterwards without a +, so this fails:

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

Sp3000

Posted 2015-07-10T21:43:20.737

Reputation: 58 729

Heyy... that's pretty neat. – Alex Van Liew – 2015-11-17T21:53:25.073

+=works in the loop – CalculatorFeline – 2016-04-11T05:30:49.573

@CatsAreFluffy It's o=o[:-1]+x, not o=o+x – Sp3000 – 2016-04-11T05:36:54.537

Oops, missed that. Does something like o[:-2]=x work? – CalculatorFeline – 2016-04-11T16:50:12.070

@CatsAreFluffy You can't assign to str – Sp3000 – 2016-04-11T16:53:04.297

7

Haskell, 52 47 bytes

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

Usage example:

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

How it works:

                  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

Posted 2015-07-10T21:43:20.737

Reputation: 34 639

6

Ruby, 27 24 20 bytes

(19 characters code + 1 character command line option.)

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

Thanks to:

  • Ventero for suggesting to use the global variables (-4 characters)

Sample run:

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.

manatwork

Posted 2015-07-10T21:43:20.737

Reputation: 17 865

+1 I thought I'd do a Ruby answer until I saw this -- I'm pretty sure this is as small as it's gonna get. Great usage of []! – daniero – 2015-07-11T14:21:44.640

There was another version in the beginning: loop{$_[/.\^H/]=""}rescue"" This one is nicer as it demonstrates Ruby's exception handling coolness. – manatwork – 2015-07-11T14:30:44.567

Haha, that's a great one :) – daniero – 2015-07-11T14:45:24.820

1Better late than never: $_=$`+$'while~/.\^H/ for 20 (you can even drop the tilde if you don't care about the regexp literal in condition warning). – Ventero – 2016-04-10T21:44:12.600

Thank you, @Ventero. The warning appears only in irb (at least in 2.1.5), so I don't care about it, as I run the code from command line. :) – manatwork – 2016-04-11T17:53:13.020

1@manatwork: Technically it appears in all ruby versions >= 1.9 (regex and string literals in conditions were deprecated after 1.8), I guess your ruby simply still defaults 1.8, whereas irb uses ruby 2.1.5. – Ventero – 2016-04-11T20:03:36.677

Thank you for the information on the deprecation, @Ventero. Sorry, for the confusing wording, that version 2.1.5 actually applies to both ruby and irb: http://pastebin.com/eZaWtirp My first guess was different verbose mode, but both are on medium.

– manatwork – 2016-04-12T07:58:59.200

4

Python 2, 50

It's a bit odd having a second lambda in there, but seems to be the best Python so far.

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

feersum

Posted 2015-07-10T21:43:20.737

Reputation: 29 566

3

Pyth - 19 bytes

Reduce works really, really well with this but it only does one char at a time so I had to spend almost as many chars as the actual algo to do a replace ^H with linebreak. Looking for a better way to do that.

u?+GHnHbPGjbcz"^H"k

Try it online here.

Maltysen

Posted 2015-07-10T21:43:20.737

Reputation: 25 023

3

TeaScript, 7 bytes [Not competing]

Not competing as TeaScript was made after this challenge was posted. This is here as reference.

xW/.\^H

This uses the new TeaScript 3, and recursive replaces to remove the characters

Downgoat

Posted 2015-07-10T21:43:20.737

Reputation: 27 116

1For some reason this counts as 8859 bytes on the leaderboard because of the ISO 8859 link... – ev3commander – 2015-12-16T22:54:48.577

regerence? xD – cat – 2016-04-10T20:41:47.357

2

ECMAScript 6, 57 bytes

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

This is probably golfable, just gotta think of a way probably not

Downgoat

Posted 2015-07-10T21:43:20.737

Reputation: 27 116

2How about s=>{while(s!=(s=s.replace(/.\^H/,""));return s}? – lrn – 2015-07-11T12:41:00.950

Or, if while and return are too long, it could be recursive: var f=s=>s==(s=s.replace(/.\^H/))?s:f(s) – lrn – 2015-07-11T14:31:00.893

@lm you should add the second parameter "" for replace. Then you have my answer :) – edc65 – 2015-07-11T17:24:13.730

True. And the empty string argument needs to be there, I must have copied the wrong version :( – lrn – 2015-07-11T23:14:23.237

~s.indexOf\^H`` can become /\^H/.test(s) – Not that Charles – 2015-11-18T04:53:12.100

Generally for doesn't increase bytes overwhile – ev3commander – 2015-12-16T22:52:46.443

Try using eval: s=>eval("while(~s.indexOf`^H`)s=s.replace(/.^H/,'');s"). Untested, but it might work. – Mama Fun Roll – 2015-12-26T15:52:29.217

2

R, 54 52 bytes

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

Same basic idea as my Julia answer. This creates a recursive function that accepts a string and returns a string. If the input is equal to itself with a single occurrence of ^H removed, return it, otherwise call the function again.

You can try it online!

Alex A.

Posted 2015-07-10T21:43:20.737

Reputation: 23 761

2

K5, 64 bytes

K isn't really designed for this kind of work...

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

kirbyfan64sos

Posted 2015-07-10T21:43:20.737

Reputation: 8 730

2

golflua, 36 bytes

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

Sample run:

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.

manatwork

Posted 2015-07-10T21:43:20.737

Reputation: 17 865

2

Javascript, 62 bytes

Not the shortest one, but works fine.

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

This probably can be shortened a lot!

Ismael Miguel

Posted 2015-07-10T21:43:20.737

Reputation: 6 797

1Not the shortest one and does not work eiither (try any of the test cases). The regexp should not be global (remove /g) – edc65 – 2015-07-11T17:29:23.143

@edc65 Thanks for the tip. I tried some things and they worked. That's why I posted like that – Ismael Miguel – 2015-07-11T21:29:21.090

2

Java, 78 77 bytes

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

Olivia Trewin

Posted 2015-07-10T21:43:20.737

Reputation: 351

1You can remove the space after the comma to save one char. – ProgramFOX – 2015-07-13T06:51:19.000

2

Julia, 41 39 bytes

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

What it's doing is using ^H as a delimiter, and then removing the last character on each string then concatenating the next string before removing the last character again. Unlike the other Julia answer, this is not a recursive function.

Note: I've removed the function name from the definition. Originally, it said f(s)= rather than s->, and you used it as f("AAA^HB^H^H")... but I'm saving two bytes by letting it be "anonymous", and use itself as its name. You use it like this:

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

(you can also assign a variable to it as f=s->foldl((t,v)->chop(t)v,split(s,"^H")), then f("AAA^HB^H^H") will work)

Glen O

Posted 2015-07-10T21:43:20.737

Reputation: 2 548

2

(Visual)FoxPro any version 80 bytes

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

Repeating string translation to empty by finding ^H and backing up one character.

Chris

Posted 2015-07-10T21:43:20.737

Reputation: 21

2

rs, 8 bytes

Technically, this doesn't count, as it depends on a feature I added after this question was posted. However, I think it's pretty neat.

+?1.\^H/

Live demo and test cases.

kirbyfan64sos

Posted 2015-07-10T21:43:20.737

Reputation: 8 730

Is the new feature a limit replacement? – xnor – 2015-07-23T04:55:57.480

@xnor Yes: the ?1. – kirbyfan64sos – 2015-07-23T12:54:50.083

@Optimizer Why? You're losing to Gema anyway. :O – kirbyfan64sos – 2015-07-23T13:00:32.450

Yeah :( . Saw gema after posting comment – Optimizer – 2015-07-23T13:03:46.977

1

Java - 123 bytes

I personally like the g---1 part the best.

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

expanded (slightly):

  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

Posted 2015-07-10T21:43:20.737

Reputation: 3 971

1

Python 2, 74 + 2 = 76 Bytes

I've tried a few approaches so far, this is the best I've been able to come up with so far.

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

Kade

Posted 2015-07-10T21:43:20.737

Reputation: 7 463

4Where are those 2 extra bytes coming from? – xnor – 2015-07-11T09:17:05.983

@xnor input has to be surrounded by quotes for this to work. I forgot to put that in the post. – Kade – 2015-07-11T13:42:37.727

1I think the usual convention has been to allow string arguments to be taken in quotes for free, but I'm not totally sure. – xnor – 2015-07-13T07:19:13.927

1

Batch - 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!%

The first line is a way of saving a few bytes over the lengthy @echo off&setLocal enableDelayedExpansion (which turns echo off and enables the delayed expansion of variables, in case you were wondering). I explained it in Tips for Golfing in Batch.

The second line is a neat little trick to save the a backspace control character into a variable. It's pretty hacky, and I can't pretend to take credit for it. It's sort of explained here. Basically uses the prompt command to generate a backspace character and captures it in a variable - in this case !D!.

The final line then performs the simple string manipulation of - replace ^H with !D!<SPACE>!D!.

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

Unfortunately it breaks with cases like "AAA^HB^H^H" - where it should produce "A", it instead produces "A"B. Which is somewhat confusing. I'll have to look into how Batch string manipulation works in some more depth.

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

Thanks to to some helpful people over here - I now realize that I was only saving the backspace character (0x08), and so was only overwriting the characters. It now works with examples like the following:

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

unclemeat

Posted 2015-07-10T21:43:20.737

Reputation: 2 302

1

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

This could probably be made shorter as a function (1 byte I was able to save in quick testing) but I kinda like the one-liner aspect... :-)

The braces come from the Intersystems Cache flavour of Mumps which is what I'm most versed in.

zmerch

Posted 2015-07-10T21:43:20.737

Reputation: 541

1

><>, 39 38 36 bytes

There was no ><> answer so I thought I'd add one.

i:0(?v:'^'=?\
     ~   ~~i/
;!?lr<ro

Aaron

Posted 2015-07-10T21:43:20.737

Reputation: 3 689

1

JavaScript, 60 bytes

b=n=>(v=n.search('^H'))>0?b(n.replace(n.slice(v-1,v+2),'')):n

Not as good as edc65's answer, but I wanted to try something that didn't use Regex.

Amechra

Posted 2015-07-10T21:43:20.737

Reputation: 111

1

bash, 50 bytes

while [ "$a" != "${a/?^H/}" ];do a=${a/?^H/};done

Sample:

a=$'Horse^H^H^H^H^HCow'
while [ "$a" != "${a/?^H/}" ];do a=${a/?^H/};done
echo $a
Cow

a="Be nice to this fool^H^H^H^Hgentleman, he's visiting from corporate HQ."
while [ "$a" != "${a/?^H/}" ];do a=${a/?^H/};done
echo $a
Be nice to this gentleman, he's visiting from corporate HQ.

This could work with real (binaries) backspaces as well:

a=$'Be nice to this fool\b\b\b\bgentleman, he'\'$'s visiting from corporate HQ.'
echo $a.. but:
Be nice to this gentleman, he's visiting from corporate HQ... but:
printf %q\\n "$a"
$'Be nice to this fool\b\b\b\bgentleman, he\'s visiting from corporate HQ.'

while [ "$a" != "${a/?$'\b'/}" ];do a=${a/?$'\b'/};done
printf %q\\n "$a"
Be\ nice\ to\ this\ gentleman\,\ he\'s\ visiting\ from\ corporate\ HQ.

F. Hauri

Posted 2015-07-10T21:43:20.737

Reputation: 2 654

1

JavaScript, 60 Bytes

I know there is already a JS answer here, but wanted to do it without regexes, because regex is really almost a language by itself. I'm sorry if you feel I shouldn't post this, this is my first post.

X is the string to be operated upon.

while((z=x.indexOf('^D'))>0){x=x.slice(0,z-1)+x.slice(z+2);}

Test

Put this into your browser's address bar.

javascript:x=prompt('Enter the sentence to be erased');while((z=x.indexOf('^D'))>0){x=x.slice(0,z-1)+x.slice(z+2);}alert(x);

I love JS because it will let you do things like saying (z=x.indexOf('^D))>0, and it will both assign z.indexOf('^D'); to x and evaluate z.indexOf('^D') in the condition, which saves me precious bytes in this problem. It's not very useful otherwise, but it's fun!

alexcat3

Posted 2015-07-10T21:43:20.737

Reputation: 11

3

No problem posting another answer in a language that was already used. But please note that unless the task specifies otherwise, by default a program or a function is expected. Your is just a snippet. And please post your code in code block markup, so scripts like Code Golf UserScript Enhancement Pack can insert the code size beside the code.

– manatwork – 2015-12-17T11:31:56.753

1

Emacs Lisp, 45 73 bytes

(lambda(s)(while(string-match".^H"s)(set's(replace-match"" nil nil s)))s)

Searches for the first occurence of anything else and ^H as long as it exists and replaces it with an empty string.

Old, incorrect version

(lambda(s)(replace-regexp-in-string".^H"""s))

Lord Yuuma

Posted 2015-07-10T21:43:20.737

Reputation: 587

Sorry, but I'm afraid this is not enough – you have to do the replacing in multiple steps so “one^Hff^H^H^Huch” gets transformed into “ouch”. – manatwork – 2015-12-25T17:03:39.273

1

Japt, 8 bytes (non-competing)

This answer is non-competing because Japt is newer than this challenge.

Ue/.\^H/

Try it online!

How it works

U        // Take the input,
e/.\^H/  // and recursively replace any char followed by "^H" with
         // (nothing, defaults to an empty string).
         // Implicit: output last expression

ETHproductions

Posted 2015-07-10T21:43:20.737

Reputation: 47 880

1

Oracle SQL 11.2, 172 bytes

WITH v(s,i)AS(SELECT:1,INSTR(:1,'^')FROM DUAL UNION ALL SELECT LPAD(s,i-2)||SUBSTR(s,i+2),INSTR(s,'^',1,2)-3 FROM v WHERE i>0AND'^'<>s)SELECT s FROM v WHERE INSTR(s,'^')=0;

Un-golfed

WITH v(s,i) AS                        -- Recursive view, s-> string, i->pos of first ^
(
  SELECT :1,INSTR(:1,'^')             -- Initialisation view 
  FROM   DUAL
  UNION ALL
  SELECT LPAD(s,i-2)||SUBSTR(s,i+2),  -- Remove the ^ at pos i and the characters before and after 
         INSTR(s,'^',1,2)-3           -- Compute the pos of the next ^ (the 2nd of s as before the remove just above)
  FROM   v 
  WHERE  i>0                          -- Exit clause : no more ^
    AND  s<>'^'                       -- Needed to circumvent oracle's cycle detection, without it 123^H45^H^H^H78^H will fail
)
SELECT s FROM v WHERE INSTR(s,'^')=0; -- Keep only the row without any ^

Jeto

Posted 2015-07-10T21:43:20.737

Reputation: 1 601

0

APL (Dyalog Unicode), 18 bytes

'.\^H'⎕R''⍠'ML'1⍣≡

Try it online!

Erik the Outgolfer

Posted 2015-07-10T21:43:20.737

Reputation: 38 134

0

jq 1.5, 41 37 bytes

(34 characters code + 3 characters command line option.)

reduce(./"^H")[]as$t("";.[:-1]+$t)

Sample run:

bash-4.3$ bin/jq -R -r 'reduce(./"^H")[]as$t("";.[:-1]+$t)' <<< "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.

On-line test (Passing -R through URL is not supported – so input passed as JSON string literal. Passing -r through URL is not supported – check Raw Output yourself.)

manatwork

Posted 2015-07-10T21:43:20.737

Reputation: 17 865

0

Javascript ES6, 41 39 bytes

f=s=>s==(s=s.replace(/.\^H/,""))?s:f(s)

Qwertiy

Posted 2015-07-10T21:43:20.737

Reputation: 2 697

0

, 8 chars / 10 bytes (noncompetitive)

ïė/.\^H/

Try it here (Firefox only).

Works like all of the other JSGL's.

Mama Fun Roll

Posted 2015-07-10T21:43:20.737

Reputation: 7 234