Missy Elliot, XKCD and ASCII Bytes

9

2

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!

WallyWest

Posted 2014-01-08T00:15:03.030

Reputation: 6 949

3Do we care that this is not a reversible process? When the bit shift is performed the least-significant bit is essentially thrown away. – Sammitch – 2014-01-08T00:35:32.520

For the purpose of this exercise we are not after reversibility... We don't give a crap about it, essentially ;) I just want the code to do as I have requested... – WallyWest – 2014-01-08T00:39:22.117

1I get 0 1 1 0 1 1 0 1 and 0 1 1 0 1 0 0 1 for mi – marinus – 2014-01-08T00:46:00.967

@marinus, by golly you're right... Editing... Okay, that's been fixed and the result modified accordingly... – WallyWest – 2014-01-08T00:48:30.593

2I always did wonder what that song was about... – boothby – 2014-01-08T02:09:56.490

By my calcs, there are eight input ASCII chars (A,P,Q,a,p,q,@,```) that output ASCII codes > 126. i.e. "unprintable" -meh- – Darren Stone – 2014-01-08T09:08:24.397

@DarrenStone That's why I put in the wrap around rules so that it stays within the confines of characters 32-126... – WallyWest – 2014-01-08T09:18:09.613

2The 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? – Darren Stone – 2014-01-08T09:23:11.837

Shoot, good point... I will have to alter the rule slightly...

Good point... I'll give you +1 for spotting the flaw... – WallyWest – 2014-01-08T10:37:59.450

2Be careful altering the rules. You have a lot of submitted answers which conform to your current definition. – Darren Stone – 2014-01-08T23:13:08.303

Answers

5

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

marinus

Posted 2014-01-08T00:15:03.030

Reputation: 30 224

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 – Tobia – 2014-01-08T21:49:46.393

4

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.

Ben Reich

Posted 2014-01-08T00:15:03.030

Reputation: 1 577

Clever, and so far you're in the lead! – WallyWest – 2014-01-08T05:51:03.450

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&). – Peter Taylor – 2014-01-08T08:37:28.570

Thanks @PeterTaylor - the 512 trick is perfect! In the spirit of the question, though, I think we should bit shift before negating. – Ben Reich – 2014-01-08T14:42:30.713

If you count 2/ as a bit shift then you can still bit shift, then ~, then base convert... – Peter Taylor – 2014-01-08T15:18:03.587

@PeterTaylor I like it! Thanks for the help. – Ben Reich – 2014-01-08T16:16:36.187

3

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"

tmartin

Posted 2014-01-08T00:15:03.030

Reputation: 3 917

2

J - 61

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

swish

Posted 2014-01-08T00:15:03.030

Reputation: 7 484

2

J, 55 54 characters

u:+/(*126&>*.32&<)_95 0 95+/#.|."1#:255-<.-:a.i.1!:1[1

Gareth

Posted 2014-01-08T00:15:03.030

Reputation: 11 678

Muy impressivo! – WallyWest – 2014-01-08T06:01:53.103

1

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

Darren Stone

Posted 2014-01-08T00:15:03.030

Reputation: 5 072

1

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

Sinkingpoint

Posted 2014-01-08T00:15:03.030

Reputation: 141

You can drop the space after a:. – Darren Stone – 2014-01-08T09:53:58.120

You can replace your final chr expression with this for another 1-char savings: chr(x-(95,(-95,0)[x>32])[x<126]). – Darren Stone – 2014-01-08T09:56:25.100

A bit shorter: print'\b%c'%(x+95*((x<32)-(x>126))), – grc – 2014-01-08T13:37:49.933

1

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

user8777

Posted 2014-01-08T00:15:03.030

Reputation: