27
\$\begingroup\$

Reverse and Invert a String

Challenge

In this challenge. You'll be writing a program which will output or return the input, reversed and inverted.

First, each character should be converted to its character code. Then, that should be converted to base-2. Following, that string should be reversed. After, the string should be inverted (1 -> 0 and 0 -> 1). Finally, that should be converted back to base 2 and then converted back to a character. If an character results to be an unprintable, you may optionally output it but they do not have to be removed.

H -> 72  -> 1001000 -> 0001001 -> 1110110 -> 118 -> v
e -> 101 -> 1100101 -> 1010011 -> 0101100 -> 44  -> ,
l -> 108 -> 1101100 -> 0011011 -> 1100100 -> 100 -> d
l -> 108 -> 1101100 -> 0011011 -> 1100100 -> 100 -> d
o -> 111 -> 1101111 -> 1111011 -> 0000100 -> 4   -> (unprintable)
, -> 44  -> 101100  -> 001101  -> 110010  -> 50  -> 2
  -> 32  -> 100000  -> 000001  -> 111110  -> 62  -> >
W -> 87  -> 1010111 -> 1110101 -> 0001010 -> 10  -> (newline)
o -> 111 -> 1101111 -> 1111011 -> 0000100 -> 4   -> (unprintable)
r -> 114 -> 1110010 -> 0100111 -> 1011000 -> 88  -> X
l -> 108 -> 1101100 -> 0011011 -> 1100100 -> 100 -> d
d -> 100 -> 1100100 -> 0010011 -> 1101100 -> 108 -> l
! -> 33  -> 100001  -> 100001  -> 011110  -> 30  -> (unprintable)

Scoring

Shortest code in bytes wins.

-15% Bonus: if your program removes un-printables from the output. This must be at least all characters below 32 except newlines (char 10)

\$\endgroup\$
  • \$\begingroup\$ I need to get my Simplex interpreter working again XD GBktnkZs \$\endgroup\$ – Conor O'Brien Nov 6 '15 at 1:13
  • \$\begingroup\$ So the characters in the string aren't reversed, but the bits in each character are? \$\endgroup\$ – xnor Nov 6 '15 at 1:36
  • \$\begingroup\$ Just to be sure: for 0010000 is the bit reverse 0000100 or 00001? \$\endgroup\$ – Digital Trauma Nov 6 '15 at 2:37
  • \$\begingroup\$ @DigitalTrauma If the binary code is 0010000, it should be treated as 10000 so the reverse would be 00001 \$\endgroup\$ – Downgoat Nov 6 '15 at 3:06
  • 2
    \$\begingroup\$ Can we assume just ASCII (as your examples), or should this work for whatever is a character in my language? (Also, if a language uses a different character code, should I use this instead of ASCII/Unicode)? \$\endgroup\$ – Paŭlo Ebermann Nov 6 '15 at 17:30

25 Answers 25

4
\$\begingroup\$

CJam, 14

q{i2bW%:!2bc}%

Try it online

Explanation:

Pretty straightforward:

q       read input
{…}%    convert each character
  i     convert to number
  2b    convert to base 2 (digit array)
  W%    reverse
  :!    invert each digit
  2b    convert from base 2
  c     convert to character

"Printable" version, 20 - 15% = 17

q{i2bW%:!2bc' ,N--}%
\$\endgroup\$
  • \$\begingroup\$ Dangit, you. I was just about to post a CJam answer D: \$\endgroup\$ – anOKsquirrel Nov 6 '15 at 1:20
  • \$\begingroup\$ @anOKsquirrel sorry ^^ was it similar? \$\endgroup\$ – aditsu Nov 6 '15 at 1:21
  • \$\begingroup\$ It would have been if I had finished it. \$\endgroup\$ – anOKsquirrel Nov 6 '15 at 1:23
  • \$\begingroup\$ How does W% work? W is -1, so... \$\endgroup\$ – anOKsquirrel Nov 6 '15 at 1:25
  • 1
    \$\begingroup\$ @anOKsquirrel see the documentation here \$\endgroup\$ – aditsu Nov 6 '15 at 1:26
9
\$\begingroup\$

Pyth, 14 bytes

smCi!M_jCd2 2z

Try it online.

How it works

 m           z  Map over the input with lambda d:
        Cd        Cast d to character.
       j  2       Convert to base 2.
      _           Reverse the resulting array.
    !M            Mapped logical NOT.
   i        2     Convert back to integer.
  C               Cast to character.
s               Concatenate the resulting characters.
\$\endgroup\$
  • 2
    \$\begingroup\$ Alternative solutions (all 14 bytes): smCi!MvM_.Bd2z smCi.r_.Bd`T2z smCiqR\0_.Bd2z \$\endgroup\$ – Dennis Nov 6 '15 at 2:38
  • \$\begingroup\$ How about a version which removes unprintables, just out of interest/for comparison? Probably as a separate answer. \$\endgroup\$ – hyde Nov 6 '15 at 6:51
8
\$\begingroup\$

Perl, 57 51 characters

(50 characters code + 1 character command-line option.)

s/./$_=unpack b8,$&;s|0+$||;"chr 0b".y|10|01|r/gee

Sample run:

bash-4.3$ perl -pe 's/./$_=unpack b8,$&;s|0+$||;"chr 0b".y|10|01|r/gee' <<< 'Hello, World!'
v,dd2>
Xdl

bash-4.3$ perl -pe 's/./$_=unpack b8,$&;s|0+$||;"chr 0b".y|10|01|r/gee' <<< 'Hello, World!' | od -tad1
0000000    v    ,    d    d  eot    2    >   nl  eot    X    d    l   rs   nl
         118   44  100  100    4   50   62   10    4   88  100  108   30   10
0000016
\$\endgroup\$
  • 1
    \$\begingroup\$ 51 bytes: -p s/./$_=unpack b8,$&;s|0+$||;"chr 0b".y|10|01|r/gee. unpack b8,$& is shorter than sprintf'%b',ord$&, and additionally decodes in reverse order. Unfortunately it also produces trailing 0s, which need to be removed. \$\endgroup\$ – primo Nov 7 '15 at 11:08
  • \$\begingroup\$ Thank you @primo. unpack is still unexplored terrain for me. \$\endgroup\$ – manatwork Nov 7 '15 at 17:28
  • \$\begingroup\$ 42 bytes: -p s/./"chr 0b".unpack(b8,~$&)=~s|1+$||r/gee. Invert the character, no need to transliterate ;) \$\endgroup\$ – primo Nov 9 '15 at 11:48
7
\$\begingroup\$

JavaScript (ES6 ES7), 119 114 108 bytes

This turned out way longer than expected :(

Thanks to @vihan for 5 bytes saved! Thanks to @ETHProductions for another 6 bytes saved!

To test:  Run the snippet below, enter input like "Hello, World!", and click Test!

x=>String.fromCharCode(...[for(y of x)+('0b'+[...y.charCodeAt().toString(2)].reverse().map(z=>z^1).join``)])
<!--                               Try the test suite below!                              --><strong id="bytecount" style="display:inline; font-size:32px; font-family:Helvetica"></strong><strong id="bytediff" style="display:inline; margin-left:10px; font-size:32px; font-family:Helvetica; color:lightgray"></strong><br><br><pre style="margin:0">Code:</pre><textarea id="textbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><pre style="margin:0">Input:</pre><textarea id="inputbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><button id="testbtn">Test!</button><button id="resetbtn">Reset</button><br><p><strong id="origheader" style="font-family:Helvetica; display:none">Original Code Output:</strong><p><div id="origoutput" style="margin-left:15px"></div><p><strong id="newheader" style="font-family:Helvetica; display:none">New Code Output:</strong><p><div id="newoutput" style="margin-left:15px"></div><script type="text/javascript" id="golfsnippet">var bytecount=document.getElementById("bytecount");var bytediff=document.getElementById("bytediff");var textbox=document.getElementById("textbox");var inputbox=document.getElementById("inputbox");var testbtn=document.getElementById("testbtn");var resetbtn=document.getElementById("resetbtn");var origheader=document.getElementById("origheader");var newheader=document.getElementById("newheader");var origoutput=document.getElementById("origoutput");var newoutput=document.getElementById("newoutput");textbox.style.width=inputbox.style.width=window.innerWidth-50+"px";var _originalCode=null;function getOriginalCode(){if(_originalCode!=null)return _originalCode;var allScripts=document.getElementsByTagName("script");for(var i=0;i<allScripts.length;i++){var script=allScripts[i];if(script.id!="golfsnippet"){originalCode=script.textContent.trim();return originalCode}}}function getNewCode(){return textbox.value.trim()}function getInput(){try{var inputText=inputbox.value.trim();var input=eval("["+inputText+"]");return input}catch(e){return null}}function setTextbox(s){textbox.value=s;onTextboxChange()}function setOutput(output,s){output.innerHTML=s}function addOutput(output,data){output.innerHTML+='<pre style="background-color:'+(data.type=="err"?"lightcoral":"lightgray")+'">'+escape(data.content)+"</pre>"}function getByteCount(s){return(new Blob([s],{encoding:"UTF-8",type:"text/plain;charset=UTF-8"})).size}function onTextboxChange(){var newLength=getByteCount(getNewCode());var oldLength=getByteCount(getOriginalCode());bytecount.innerHTML=newLength+" bytes";var diff=newLength-oldLength;if(diff>0){bytediff.innerHTML="(+"+diff+")";bytediff.style.color="lightcoral"}else if(diff<0){bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgreen"}else{bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgray"}}function onTestBtn(evt){origheader.style.display="inline";newheader.style.display="inline";setOutput(newoutput,"");setOutput(origoutput,"");var input=getInput();if(input===null){addOutput(origoutput,{type:"err",content:"Input is malformed. Using no input."});addOutput(newoutput,{type:"err",content:"Input is malformed. Using no input."});input=[]}doInterpret(getNewCode(),input,function(data){addOutput(newoutput,data)});doInterpret(getOriginalCode(),input,function(data){addOutput(origoutput,data)});evt.stopPropagation();return false}function onResetBtn(evt){setTextbox(getOriginalCode());origheader.style.display="none";newheader.style.display="none";setOutput(origoutput,"");setOutput(newoutput,"")}function escape(s){return s.toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}window.alert=function(){};window.prompt=function(){};function doInterpret(code,input,cb){var workerCode=interpret.toString()+";function stdout(s){ self.postMessage( {'type': 'out', 'content': s} ); }"+" function stderr(s){ self.postMessage( {'type': 'err', 'content': s} ); }"+" function kill(){ self.close(); }"+" self.addEventListener('message', function(msg){ interpret(msg.data.code, msg.data.input); });";var interpreter=new Worker(URL.createObjectURL(new Blob([workerCode])));interpreter.addEventListener("message",function(msg){cb(msg.data)});interpreter.postMessage({"code":code,"input":input});setTimeout(function(){interpreter.terminate()},1E4)}setTimeout(function(){getOriginalCode();textbox.addEventListener("input",onTextboxChange);testbtn.addEventListener("click",onTestBtn);resetbtn.addEventListener("click",onResetBtn);setTextbox(getOriginalCode())},100);function interpret(code,input){window={};alert=function(s){stdout(s)};window.alert=alert;console.log=alert;prompt=function(s){if(input.length<1)stderr("not enough input");else{var nextInput=input[0];input=input.slice(1);return nextInput.toString()}};window.prompt=prompt;(function(){try{var evalResult=eval(code);if(typeof evalResult=="function"){var callResult=evalResult.apply(this,input);if(typeof callResult!="undefined")stdout(callResult)}}catch(e){stderr(e.message)}})()};</script>

\$\endgroup\$
  • \$\begingroup\$ I think you could save a 4 bytes replacing the parseInt with +('0b'+<code>) as described here and another one by using w^1 instead of +!+w \$\endgroup\$ – Downgoat Nov 6 '15 at 2:12
  • 2
    \$\begingroup\$ I never would have thought this possible, but I just golfed off .05 bytes: x=>String.fromCharCode(...[for(y of x)if((c=+('0b'+[...y.charCodeAt().toString(2)].reverse().map(z=>z^1).join``)) >31||c==10)c]) (127 - 15% = 107.95) Maybe this isn't legal, though; it only handles 10 == \n, not 13 == \r. @Vɪʜᴀɴ what is your opinion? \$\endgroup\$ – ETHproductions Nov 6 '15 at 4:14
  • 1
    \$\begingroup\$ I get Unexpected token '>' when I try to run the snippet. \$\endgroup\$ – Paul R Nov 6 '15 at 11:46
  • 1
    \$\begingroup\$ @ETHproductions: thanks - I only have Safari and Chrome to hand and I guess neither of these is "ES6-compliant". \$\endgroup\$ – Paul R Nov 6 '15 at 14:07
  • 1
    \$\begingroup\$ @PaulR ES6, or ECMAScript 6, is one of the latest sets of new features for JavaScript. See this site for more info. There's also a compatability table that shows which features are supported by which browsers (and other programs). This answer in particular requires "arrow functions", the "spread operator", and ES7's "array comprehensions". \$\endgroup\$ – ETHproductions Nov 6 '15 at 15:26
5
\$\begingroup\$

JavaScript (ES7), 126 bytes - 15% = 107.1

I was playing around with this answer to see if the bonus was worth it. Apparently, it is. The test suite was stolen from the same answer, but I added my own twist: full support of the 15% bonus! :)

x=>String.fromCharCode(...[for(y of x)if((c=+('0b'+[...y.charCodeAt().toString(2)].reverse().map(z=>z^1).join``))>31|c==10)c])
<!--                               Try the test suite below!                              --><strong id="bytecount" style="display:inline; font-size:32px; font-family:Helvetica"></strong><strong id="bytediff" style="display:inline; margin-left:10px; font-size:32px; font-family:Helvetica; color:lightgray"></strong><br><strong id="score" style="display:inline; font-size:32px; font-family:Helvetica">Score:</strong><strong id="scorediff" style="display:inline; margin-left:10px; font-size:32px; font-family:Helvetica; color:lightgray"></strong><br><br><pre style="margin:0">Code:</pre><textarea id="textbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><pre style="margin:0">Input:</pre><textarea id="inputbox" style="margin-top:5px; margin-bottom:5px">"Hello, World!"</textarea><br><button id="testbtn">Test!</button><button id="resetbtn">Reset</button><br><p><strong id="origheader" style="font-family:Helvetica; display:none">Original Code Output:</strong><p><div id="origoutput" style="margin-left:15px"></div><p><strong id="newheader" style="font-family:Helvetica; display:none">New Code Output:</strong><p><div id="newoutput" style="margin-left:15px"></div><script type="text/javascript" id="golfsnippet">var bytecount=document.getElementById("bytecount");var bytediff=document.getElementById("bytediff");var score=document.getElementById("score");var scorediff=document.getElementById("scorediff");var textbox=document.getElementById("textbox");var inputbox=document.getElementById("inputbox");var testbtn=document.getElementById("testbtn");var resetbtn=document.getElementById("resetbtn");var origheader=document.getElementById("origheader");var newheader=document.getElementById("newheader");var origoutput=document.getElementById("origoutput");var newoutput=document.getElementById("newoutput");textbox.style.width=inputbox.style.width=window.innerWidth-50+"px";var _originalCode=null;function getOriginalCode(){if(_originalCode!=null)return _originalCode;var allScripts=document.getElementsByTagName("script");for(var i=0;i<allScripts.length;i++){var script=allScripts[i];if(script.id!="golfsnippet"){originalCode=script.textContent.trim();return originalCode}}}function getNewCode(){return textbox.value.trim()}function getInput(){try{var inputText=inputbox.value.trim();var input=eval("["+inputText+"]");return input}catch(e){return null}}function setTextbox(s){textbox.value=s;onTextboxChange()}function setOutput(output,s){output.innerHTML=s}function addOutput(output,data){output.innerHTML+='<pre style="background-color:'+(data.type=="err"?"lightcoral":"lightgray")+'">'+escape(data.content)+"</pre>"}function getByteCount(s){return(new Blob([s],{encoding:"UTF-8",type:"text/plain;charset=UTF-8"})).size}function getScore(s){var a=1;try{b=eval('('+s+')("Hello, World!")');if(b=="v,dd2>\nXdl")a=.85}catch(e){};return getByteCount(s)*a}function onTextboxChange(){var newLength=getByteCount(getNewCode());var oldLength=getByteCount(getOriginalCode());bytecount.innerHTML=newLength+" bytes";var diff=newLength-oldLength;if(diff>0){bytediff.innerHTML="(+"+diff+")";bytediff.style.color="lightcoral"}else if(diff<0){bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgreen"}else{bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgray"}newLength=getScore(getNewCode());var oldLength=getScore(getOriginalCode());score.innerHTML="Score: "+newLength;var diff=Math.round((newLength-oldLength)*100)/100;if(diff>0){scorediff.innerHTML="(+"+diff+")";scorediff.style.color="lightcoral"}else if(diff<0){scorediff.innerHTML="("+diff+")";scorediff.style.color="lightgreen"}else{scorediff.innerHTML="("+diff+")";scorediff.style.color="lightgray"}}function onTestBtn(evt){origheader.style.display="inline";newheader.style.display="inline";setOutput(newoutput,"");setOutput(origoutput,"");var input=getInput();if(input===null){addOutput(origoutput,{type:"err",content:"Input is malformed. Using no input."});addOutput(newoutput,{type:"err",content:"Input is malformed. Using no input."});input=[]}doInterpret(getNewCode(),input,function(data){addOutput(newoutput,data)});doInterpret(getOriginalCode(),input,function(data){addOutput(origoutput,data)});evt.stopPropagation();return false}function onResetBtn(evt){setTextbox(getOriginalCode());origheader.style.display="none";newheader.style.display="none";setOutput(origoutput,"");setOutput(newoutput,"")}function escape(s){return s.toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}window.alert=function(){};window.prompt=function(){};function doInterpret(code,input,cb){var workerCode=interpret.toString()+";function stdout(s){ self.postMessage( {'type': 'out', 'content': s} ); }"+" function stderr(s){ self.postMessage( {'type': 'err', 'content': s} ); }"+" function kill(){ self.close(); }"+" self.addEventListener('message', function(msg){ interpret(msg.data.code, msg.data.input); });";var interpreter=new Worker(URL.createObjectURL(new Blob([workerCode])));interpreter.addEventListener("message",function(msg){cb(msg.data)});interpreter.postMessage({"code":code,"input":input});setTimeout(function(){interpreter.terminate()},1E4)}setTimeout(function(){getOriginalCode();textbox.addEventListener("input",onTextboxChange);testbtn.addEventListener("click",onTestBtn);resetbtn.addEventListener("click",onResetBtn);setTextbox(getOriginalCode())},100);function interpret(code,input){window={};alert=function(s){stdout(s)};window.alert=alert;console.log=alert;prompt=function(s){if(input.length<1)stderr("not enough input");else{var nextInput=input[0];input=input.slice(1);return nextInput.toString()}};window.prompt=prompt;(function(){try{var evalResult=eval(code);if(typeof evalResult=="function"){var callResult=evalResult.apply(this,input);if(typeof callResult!="undefined")stdout(callResult)}}catch(e){stderr(e.message)}})()};</script>

\$\endgroup\$
  • \$\begingroup\$ Awesome modification of the test snippet! It seems the snippet now automatically checks for the bonus, may I ask how you did that? (p.s. if you want the original (not on one line) source, feel free to ask, might be easier to modify that way) \$\endgroup\$ – jrich Nov 8 '15 at 23:09
  • \$\begingroup\$ @UndefinedFunction Oh, sorry for not replying right away! I added a getScore() function which checks the test-case Hello, World! for compliance (it conveniently contains both a newline and unprintable chars), and returns the score multiplied by .85 or 1, depending on the result. And yes, access to the un-minified snippet would be great. :) \$\endgroup\$ – ETHproductions Nov 14 '15 at 23:27
  • \$\begingroup\$ I've made the original snippet code available here. Have fun! \$\endgroup\$ – jrich Nov 15 '15 at 22:02
4
\$\begingroup\$

PHP - 187 182 163 bytes

<?php $s=$_GET["s"];$m="array_map";echo join($m("chr",$m("bindec",$m(function($v){return strtr($v,[1,0]);},$m("strrev",$m("decbin",$m("ord",str_split($s))))))));?>

Pass the value as GET["s"].

array_map returns an array with all the elements of the second parameter (an array) after applying the callback function (first parameter) to all of them.

Not sure if I should take the 15% off, since echo doesn't output unprintable characters, but I didn't remove them.

Just glad I finished, since this is the first challenge I take part.

\$\endgroup\$
  • 1
    \$\begingroup\$ Is shorter if you not declare those functions: $m='array_map';echo join($m("chr",$m("bindec",$m(function($v){return strtr($v,[1,0]);},$m("strrev",$m("decbin",$m("ord",str_split($s))))))));. \$\endgroup\$ – manatwork Nov 6 '15 at 16:24
  • \$\begingroup\$ @manatwork completely forgot about that. Thanks. \$\endgroup\$ – undefined Nov 6 '15 at 16:27
  • \$\begingroup\$ You can't just put the input in a variable. You should create a function or read the input from STDIN. By the way, you don't need to use quotes around string ("chr", "bindec", …) since we don't care about warnings. That should save you 12 bytes. \$\endgroup\$ – Blackhole Nov 7 '15 at 11:50
  • \$\begingroup\$ @Blackhole thanks for the infos, I'll be aware of that next time. \$\endgroup\$ – undefined Nov 7 '15 at 13:40
  • \$\begingroup\$ You'd better do the modification on this answer, which is otherwise invalid :) . It will cost you almost no bytes, just replace str_split($s) with str_split(fgets(STDIN)) for instance. \$\endgroup\$ – Blackhole Nov 7 '15 at 17:57
3
\$\begingroup\$

K5, 28 bytes

`c${b/~|{x@&|\x}@(b:8#2)\x}'

This is a bit inconvenient because K5's decode operator performs a fixed-width base conversion, so to comply with the problem statement I have to trim leading zeroes. The lambda {x@&|\x} accomplishes this step.

Smear:

  |\0 0 1 0 1 1 0 1
0 0 1 1 1 1 1 1

Gather:

  &|\0 0 1 0 1 1 0 1
2 3 4 5 6 7

Select:

  {x@&|\x}0 0 1 0 1 1 0 1
1 0 1 1 0 1

The whole program in action:

  `c${b/~|{x@&|\x}@(b:8#2)\x}'"Hello, World"
"v,dd2>\nXdl"

I believe oK's natural behavior with unprintables makes this eligible for -15%, giving this a score of 28*0.85 = 23.8.

\$\endgroup\$
  • \$\begingroup\$ +1 because I tried but couldn't figure out a short way to get rid of the leading zeros! \$\endgroup\$ – kirbyfan64sos Nov 8 '15 at 3:20
  • \$\begingroup\$ A few related constructions can be found here. \$\endgroup\$ – JohnE Nov 8 '15 at 4:39
3
\$\begingroup\$

Julia, 77 bytes - 15% = 65.45

s->join(filter(isprint,[Char(parse(Int,join(1-digits(Int(c),2)),2))for c=s]))

This creates an unnamed functon that accepts a string and returns a string. Unprintable characters are removed, which qualifies this for the bonus.

Ungolfed:

function f(s::AbstractString)
    # digits() returns the digits in reverse order, so no explicit
    # reverse() is needed
    x = [Char(parse(Int, join(1 - digits(Int(c), 2)), 2)) for c = s]

    # Remove unprintables, join into a string
    return join(filter(isprint, x))
end
\$\endgroup\$
  • \$\begingroup\$ While it certainly qualifies it for the bonus, it also costs more than the bonus saves. 16 bytes to filter(isprint,) and only 11.55 bytes saved through the bonus. \$\endgroup\$ – Glen O Nov 6 '15 at 15:03
  • \$\begingroup\$ And if you give up the filter step, you can avoid the comprehension and join by using map directly on the string. s->map(c->Char(parse(Int,join(1-digits(Int(c),2)),2)),s) (for 56 bytes) \$\endgroup\$ – Glen O Nov 6 '15 at 15:06
  • \$\begingroup\$ @GlenO Thanks for the suggestions, but that approach leaves in unprintables as hex codes, which the OP said is not allowed. Using filter(isprint,) both qualifies it for the bonus and makes it compliant with the rules. \$\endgroup\$ – Alex A. Nov 6 '15 at 21:03
  • \$\begingroup\$ "If an character results to be an unprintable, you may optionally output it but they do not have to be removed." \$\endgroup\$ – Glen O Nov 7 '15 at 3:50
  • \$\begingroup\$ And if the concern is on the other side of it (that it displays as \x04 and the like), then print() costs seven, which would bring 56 up to 63. \$\endgroup\$ – Glen O Nov 7 '15 at 3:53
3
\$\begingroup\$

PowerShell, 199 175 (171 - 15%)=145.35

param([char[]]$a)($a|%{$b=[convert]::ToString(+$_,2);$c=[convert]::ToInt32("$((-join$b[$b.Length..0])-split0-replace1,0-join1)",2);if($c-gt31-or$c-eq10){[char]$c}})-join''

Uses an unfortunate amount of some .NET calls/built-ins, which significantly bloats the code.

Explained:

Takes the input param(..) and casts it as a char[] so we can work through it appropriately.

The next bit (..)-join'' collects and joins our output together.

Inside those parens, we iterate with $a|%{..} as a foreach loop.

Inside the loop:

  • We create a new string $b, which is our input letter cast as an int +$_ and [convert]ed to base 2
  • This next bit, setting $c, is tricky, so let's start inside and work our way out
  • We reverse the string $b with (-join$b[$b.length..0])
  • We leverage my previous code for inverting a binary string and recast the result as a string with "$(..)"
  • We feed that string into a different .NET call that [convert]s ToInt32 from base 2, which is finally stored that into $c
  • If $c is greater than 31, or equal to 10, we cast it as a char and that value is left on the pipeline for output (which is what gets collected and -join''ed together, above), else nothing gets left on this particular iteration

Phew.

Qualifies for the -15% bonus, as well.

Example

PS C:\Tools\Scripts\golfing> .\reverse-and-invert-a-string.ps1 "Hello, World!"
v,dd2>
Xdl
\$\endgroup\$
3
\$\begingroup\$

C function, 63

o;f(o,char *s){for(;*s;*s=o,s++)for(o=0;*s;*s/=2)o+=o+!(*s%2);}
\$\endgroup\$
2
\$\begingroup\$

𝔼𝕊𝕄𝕚𝕟, 39 chars / 73 bytes

ô⟦ï]ć⇝ϚĎ(+“0b`+⟦a.ü⬮ߧ2]ù⬮ć⇀$^1)ø`”⸩ø⬯⦆

Try it here (Firefox only).

\$\endgroup\$
1
\$\begingroup\$

Minkolang 0.11, 26 bytes

od?.(d2%,$r2:d)xrI1-[2*+]O

Try it here.

Explanation

od?.            Takes input as character, halting if empty
(d2%,$r2:d)x    Converts to binary, inverting digits on the way
r               Reverses stack
I1-[2*+]        Converts to decimal
O               Outputs as character (if printable)
\$\endgroup\$
1
\$\begingroup\$

MATLAB, 60 bytes

@(y)[arrayfun(@(x)bin2dec([97-fliplr(dec2bin(x)) '']),y) '']

Basically each character in turn is converted into a binary string (with no leading zeros). The array is flipped and is subtracted from 97 ('0'+'1') which inverts the character. This is converted back to decimal. After all characters have been processed, the whole array is then converted back to characters before being returned.

\$\endgroup\$
1
\$\begingroup\$

Python 3, 95 91

Straightforward implementation.

print(''.join(chr(int(''.join('10'[j>'0']for j in bin(ord(i))[:1:-1]),2))for i in input()))

Ungolfed:

inp = input()
ints = (ord(i) for i in inp)
bins = (bin(i) for i in ints)
revs = (i[2:][::-1] for i in bins) #without leading '0b'
invs = (''.join('0' if j == '1' else '1' for j in i) for i in revs)
newInts = (int(i, 2) for i in invs)
newChars = (chr(i) for i in newInts)
newStr = ''.join(newChars)
print(newStr)
\$\endgroup\$
1
\$\begingroup\$

Ruby, 62 characters

gets.bytes{|b|$><<b.to_s(2).reverse.tr("01","10").to_i(2).chr}

Samply run:

bash-4.3$ ruby -e 'gets.bytes{|b|$><<b.to_s(2).reverse.tr("01","10").to_i(2).chr}' <<< 'Hello, World!'
v,dd2>
Xdl

bash-4.3$ ruby -e 'gets.bytes{|b|$><<b.to_s(2).reverse.tr("01","10").to_i(2).chr}' <<< 'Hello, World!' | od -tad1
0000000    v    ,    d    d  eot    2    >   nl  eot    X    d    l   rs   nl
         118   44  100  100    4   50   62   10    4   88  100  108   30   10
0000016
\$\endgroup\$
1
\$\begingroup\$

C#, 156 bytes - 15% = 132.6

class P{static void Main(string[]a){try{for(int i=0,b,c;;){for(b=a[0][i++],c=0;b>0;b/=2)c=c<<1|1-b%2;if(c==10|c>31)System.Console.Write((char)c);}}catch{}}}

Indentation and new lines for clarity:

class P{
    static void Main(string[]a){
        try{
            for(int i=0,b,c;;){
                for(b=a[0][i++],c=0;b>0;b/=2)
                    c=c<<1|1-b%2;
                if(c==10|c>31)
                    System.Console.Write((char)c);
            }
        }
        catch{}
    }
}
\$\endgroup\$
1
\$\begingroup\$

Javascript 123 bytes

s=>[].map.call(s,s=>String.fromCharCode("0b"+s.charCodeAt().toString(2).split('').reverse().map(s=>s^1).join(''))).join('')
\$\endgroup\$
1
\$\begingroup\$

Retina, 1107 629 bytes - 15% = 534.65 (non-competing)

Uses features added after challenge date. (Implicit behavior of $*, , Sorting)

Retina doesn't have a built-in to convert a character to its ASCII ordinal or back... so behold its lustrous length. This handles printable ASCII, and removes unprintables as well as newlines. Byte count assumes ISO 8859-1 encoding.

The code contains unprintable characters.


¶
±
S_`
%(S`±
{2`
$`
}T01`-`_o
)Ms`.
\d+
$*
+`(1+)\1
${1}0
01
1
%O$^`.

T`01`10
1
01
+`10
011
0

m`^1{1,31}$

M%`1
m`^0¶?

126
~
125
}
124
|
123
{
122
z
121
y
120
x
119
w
118
v
117
u
116
t
115
s
114
r
113
q
112
p
111
o
110
n
109
m
108
l
107
k
106
j
105
i
104
h
103
g
102
f
101
e
100
d
99
c
98
b
97
a
96
`
95
_
94
^
93
]
92
\
91
[
90
Z
89
Y
88
X
87
W
86
V
85
U
84
T
83
S
82
R
81
Q
80
P
79
O
78
N
77
M
76
L
75
K
74
J
73
I
72
H
71
G
70
F
69
E
68
D
67
C
66
B
65
A
64
@
63
?
62
>
61
=
60
<
59
;
58
:
57
9
56
8
55
7
54
6
32

33
!
34
"
35
#
36
$
37
%
38
&
39
'
40
(
41
)
42
*
43
+
44
,
45
-
46
.
47
/
48
0
49
1
50
2
51
3
52
4
53
5
¶

Try it online

If you check out the Retina tutorial for unary arithmetic, you'll recognize several different pieces of my code as coming from there.

Thanks to Martin for golfing off hundred of bytes

\$\endgroup\$
1
\$\begingroup\$

Java, 205 - 15% = 174.2

interface F{static void main(String[]a){for(int i=0,c,s;i<a[0].length();++i){c=a[0].charAt(i);s=Integer.numberOfLeadingZeros(c);c=~(Integer.reverse(c)>>s)&-1>>>s;if(c==10|c>31)System.out.print((char)c);}}}

Ungolfed:

interface F {
    static void main(String[] a) {
        for (int i = 0, c, s; i < a[0].length(); ++i) {
            c = a[0].charAt(i);
            s = Integer.numberOfLeadingZeros(c);
            c = ~(Integer.reverse(c) >> s) & -1 >>> s;
            if (c == 10 | c > 31) System.out.print((char)c);
        }
    }
}

I think this solution is a bit interesting in its use of the Integer methods Integer.reverse and Integer.numberOfLeadingZeros which do what they sound like, and the shift of -1 >>> s where s is the number of leading zeroes, to get the mask to mask off high bits that we don't want. I just regret that the name of the latter method is so damn verbose, but that's what I get for golfing in Java.

Output:

v,dd2>
Xdl
\$\endgroup\$
1
\$\begingroup\$

Japt, 25 bytes

Want to create a golfy JavaScript program, but the shortest method involves lots of long function names? That's what Japt was made for. :)

UmX=>Xc s2 w mY=>Y^1 n2 d

Try it in the online interpreter!

How it works

         // Implicit: U = first item in input
UmX=>    // for each character X in U:
Xc s2 w  //  take the char-code of X, convert to binary, and reverse
mY=>     //  for each character Y in this:
Y^1      //   take Y XOR 1 (converts 1 to 0 and 0 to 1)
n2 d     //  convert the result back to decimal, then to a character
         // Implicit: output last expression

Using the current version of Japt (as of v1.4.4), the byte count can be cut to 14:

®c ¤w m^1 n2 d

Test it online!

\$\endgroup\$
0
\$\begingroup\$

Haskell, 167 bytes

import Data.Char
import Numeric
r '0'='1'
r '1'='0'
s=map (chr.fst.head.(readInt 2 (`elem` "01") digitToInt).(map r).reverse.flip (showIntAtBase 2 intToDigit . ord)"")

Unfortunately Haskell gets quite verbose when needing to read/print in another base…

\$\endgroup\$
0
\$\begingroup\$

Perl 6,  66 bytes

Going all-out by removing the non-printing control characters gets me to (83+1)-15% = 71.4

perl6 -ne 'print grep /<-:C+[\n]>/,.ords».base(2)».flip.map({chr :2([~] $_.comb.map(+!+*))})'

If I remove the code that strips out the control characters I save quite a bit 65+1 = 66

perl6 -ne 'print .ords».base(2)».flip.map({chr :2([~] $_.comb.map(+!+*))})'

( I used » instead of >> for clarity )

\$\endgroup\$
0
\$\begingroup\$

Jelly, 6 bytes (non-competing)

OBU¬ḄỌ

Try it online!

Explanation:

OBU¬ḄỌ Main link: z
O      Convert z to a list of character codes.
 B     Convert the codes to bit lists.
  U    Reverse the bits (not the lists).
   ¬   Invert the bits.
    Ḅ  Convert back to decimal.
     Ọ Convert back to string.
\$\endgroup\$
0
\$\begingroup\$

Racket 250 15% bonus = 212 bytes

(λ(s)(list->string(map integer->char(filter(λ(x)(or(> x 31)(= x 10)))(for/list((i(string->list s)))(string->number(string-append
"#b"(list->string(map(λ(i)(if(equal? #\0 i)#\1 #\0))(reverse(string->list(number->string(char->integer i)2))))))))))))

Ungolfed:

(define (f s)
    (list->string 
     (map 
      integer->char
      (filter
       (λ(x)(or(> x 31)(= x 10)))

       (for/list ((i (string->list s)))
         (string->number
          (string-append
           "#b"
           (list->string
            (map
             (λ(i)(if(equal? #\0 i) #\1 #\0))
             (reverse
              (string->list
               (number->string
                (char->integer i) 2)
               )))))))))))

Testing:

(f "Hello, World!")

Output:

"v,dd2>\nXdl"
\$\endgroup\$
0
\$\begingroup\$

PHP, 80 bytes

while(a&$c=$argn[$i++])echo chr(bindec(strtr(strrev(decbin(ord($c))),10,"01")));

takes input from STDIN; run with -R.

bonus version, 97 110 bytes -> 93.5 score

while(a&$c=$argn[$i++])ctype_print($c=chr(bindec(strtr(strrev(decbin(ord($c))),10,"01"))))||"
"==$c?print$c:0;

prints ASCII 10 and 32 to 126 (newline and printables)


breakdown, TiO and if possible some golfing will follow; I´m tired right now.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.