8
\$\begingroup\$

Inspired by the following XKCD comic:

enter image description here

In Missy Elliot's "Work It", part of the chorus goes as follows:

Is it worth it, let me work it

I put my thing down, flip it and reverse it

Bearing that in mind, I propose the following code golf challenge:

Create code that does, in order:

  1. Takes 8-bit ASCII input from STDIN; e.g n (Hex 6E, or Bin 01101110)
  2. Shifts each byte's 8 bits down 1 bit level (I believe it's called a bitwise shift down), e.g 01101110 becomes 00110111 ("put my thing down");
  3. Inverts each byte's bits, e.g 00110111 becomes 11001000 ("flip it");
  4. Reverses the bits for each byte, e.g 11001000 becomes 00010011 ("reverse it");
  5. If a byte's value is less than 32, then perform (95 + [byte value]), or in other words, (126-(31-[byte value])), on the byte before converting back to ASCII... If the byte value is still less than 32, repeat step 5
  6. If a byte's value is greater than 126, then perform ([byte value] - 95), or in other words, (32+([byte value]-127)), on the byte before converting back to ASCII... IF the value is still greater than 126, repeat step 6.
  7. Display the newly converted string as ASCII.

An example of this code in action:

(The input, is it worth it?)

workit missy ("missy" being the input, "workit" is the function)

Now behind the scenes...

(let me work it... Into binary)

01101101 01101001 01110011 01110011 01111001

(Put my thing down... Bitwise)

00110110 00110100 00111001 00111001 00111100

(...Flip it...)

11001001 11001011 11000110 11000110 11000011

(... And reverse it!)

10010011 11010011 01100011 01100011 11000011

(Converted back to Decimal)

147 211 99 99 195

(Perform the necessary math)

147-95 211-95 99 99 195-95 => 52 116 99 99 100

(Convert back to ASCII and display, the output)

4tccd

Rules

  1. Shortest code wins... simple as that...
  2. Input can be via function, by prompt or whatever works for you, so long as you can make Rule 1 "work it" for you... ;)
  3. I am not after reversibility, so long as you can make the code do what I have asked it to do, I'll be happy...

Best of luck!

\$\endgroup\$
10
  • 3
    \$\begingroup\$ Do we care that this is not a reversible process? When the bit shift is performed the least-significant bit is essentially thrown away. \$\endgroup\$
    – Sammitch
    Jan 8, 2014 at 0:35
  • 1
    \$\begingroup\$ I get 0 1 1 0 1 1 0 1 and 0 1 1 0 1 0 0 1 for mi \$\endgroup\$
    – marinus
    Jan 8, 2014 at 0:46
  • 3
    \$\begingroup\$ I always did wonder what that song was about... \$\endgroup\$
    – boothby
    Jan 8, 2014 at 2:09
  • 2
    \$\begingroup\$ The rules do not do that, do they? For example: P turns into the byte value 235 and subtracting 95 leaves you with 140. Still unprintable. Or do I misunderstand? \$\endgroup\$ Jan 8, 2014 at 9:23
  • 2
    \$\begingroup\$ Be careful altering the rules. You have a lot of submitted answers which conform to your current definition. \$\endgroup\$ Jan 8, 2014 at 23:13

8 Answers 8

5
\$\begingroup\$

APL  50  45

⎕UCS n+95ׯ1++⌿126 31∘.≥n←2⊥⊖~(8/2)⊤⌊.5×⎕UCS⍞

Takes input on the keyboard, e.g.:

      ⎕UCS n+95ׯ1++⌿126 31∘.≥n←2⊥⊖~(8/2)⊤⌊.5×⎕UCS⍞
missy
4tccd
\$\endgroup\$
1
  • \$\begingroup\$ I took the liberty of improving your answer down to 45 (pending edit approval.) It took too much from yours to post it as my own \$\endgroup\$
    – Tobia
    Jan 8, 2014 at 21:49
4
\$\begingroup\$

GolfScript 43 38 35

{2/~512+2base(;-1%2base-32+95%32+}%

Explanation: For each character in the string, we will do the following:

2/ # "Put your thing down": do integer division (accomplishing a bit shift).
~ # "Flip it": negate the bits of the integer.
512+ #make sure the binary form will have sufficient initial 0s (the extra initial 1 will be removed).
2base #convert string to value in base 2 (as an array)
(; #remove the initial 1 added by the 512 addition
-1% # "Reverse it": reverse the array
2base #convert back to base 10
-32+95%32+ #this does the equivalent of the subtraction/addition logic

Usage:

echo 'missy' | ruby golfscript.rb workit.gs
> 4tccd

Thanks to help from PeterTaylor.

\$\endgroup\$
5
  • \$\begingroup\$ Clever, and so far you're in the lead! \$\endgroup\$ Jan 8, 2014 at 5:51
  • \$\begingroup\$ I usually find that the best way to get a guaranteed number of digits when I do a base conversion is to add a suitable value beforehand. I.e. instead of 2base{0\+.,9<}do it would be 512+2base(;. Also note that if the intention is only to get the correct output you can reorder the operations, so rather than {!}% you just need to ~ the input before base conversion (and then replace the 512+ with 511&). \$\endgroup\$ Jan 8, 2014 at 8:37
  • \$\begingroup\$ Thanks @PeterTaylor - the 512 trick is perfect! In the spirit of the question, though, I think we should bit shift before negating. \$\endgroup\$
    – Ben Reich
    Jan 8, 2014 at 14:42
  • \$\begingroup\$ If you count 2/ as a bit shift then you can still bit shift, then ~, then base convert... \$\endgroup\$ Jan 8, 2014 at 15:18
  • \$\begingroup\$ @PeterTaylor I like it! Thanks for the help. \$\endgroup\$
    – Ben Reich
    Jan 8, 2014 at 16:16
3
\$\begingroup\$

K, 68 58

{"c"${$[a<32;95;a>126;-95;0]+a:6h$0b/:|~8#0b,0b\:x}'4h$'x}

.

k){"c"${$[a<32;95;a>126;-95;0]+a:6h$0b/:|~8#0b,0b\:x}'4h$'x}"missy"
"4tccd"
\$\endgroup\$
2
\$\begingroup\$

J - 61

u:-&95^:(>&126)"0+&95^:(<&32)"0#.|."1(1-0,0,}:)"1#:3&u:1!:1[1
missy
4tccd
\$\endgroup\$
2
\$\begingroup\$

J, 55 54 characters

u:+/(*126&>*.32&<)_95 0 95+/#.|."1#:255-<.-:a.i.1!:1[1
\$\endgroup\$
1
  • \$\begingroup\$ Muy impressivo! \$\endgroup\$ Jan 8, 2014 at 6:01
1
\$\begingroup\$

Ruby, 115

This entry is uncompetitively long. So I'll go with, "but you can read it!" :-P

$><<gets.chars.map{|c|c=(c.ord.to_s(2)[0..-2].tr('01','10').reverse+'11').to_i(2)
(c+(c<32?95:c>126?-95:0)).chr}*''

Reads from stdin:

missy
4tccd
\$\endgroup\$
1
\$\begingroup\$

Python 2.7, 106

Another rather long answer, but hey it's my first try:

for c in raw_input():x=sum(1<<7-i for i in range(8)if~ord(c)>>1+i&1);print'\b%c'%(x+95*((x<32)-(x>126))),

Modified based off of Darren Stone and grc's comments below...

\$\endgroup\$
3
  • \$\begingroup\$ You can drop the space after a:. \$\endgroup\$ Jan 8, 2014 at 9:53
  • \$\begingroup\$ You can replace your final chr expression with this for another 1-char savings: chr(x-(95,(-95,0)[x>32])[x<126]). \$\endgroup\$ Jan 8, 2014 at 9:56
  • \$\begingroup\$ A bit shorter: print'\b%c'%(x+95*((x<32)-(x>126))), \$\endgroup\$
    – grc
    Jan 8, 2014 at 13:37
1
\$\begingroup\$

Python 2.7 - 73 86

Thanks to the change in rules I found a much simpler way to do this all using binary and integer manipulation. This saves space over Quirlioms by not needing a temporary variable:

for i in input():print chr((int(bin(ord(i)>>1^255)[:1:-1],2)-32)%95+32),

> python workit.py
"missy"
4 t c c d
> python workit.py
"P Diddy"
- 9 \ t T T d

And in explanation form:

for i in input():  # Take an input, better quote it
                   # Is it worth it? Let me work it
  print chr(
    int(bin(
        ord(i)>>1  # Put my thing down by bitshifting it
             ^255  # XOR it with 255 to flip the bits and pad to 8 bits
        )[:1:-1]   # Then reverse it (but don't take the cruft
                   # python puts at the start of binary strings)
    ,2) 
    )-32)%95+32    # This pulls everything into the 32-126 range
  ),
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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