The Wayback Machine - https://web.archive.org/web/20161011083534/http://codegolf.stackexchange.com/questions/57204/programming-with-bits-and-bytes
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In this challenge you are going to write an interpreter for a simple language I've made up. The language is based on a single accumulator A, which is exactly one byte in length. At the start of a program, A = 0. These are the languages instructions:

!: Inversion

This instruction simply inverts every bit of the accumulator. Every zero becomes a one and every one becomes a zero. Simple!

>: Shift Right

This instruction shifts every bit in A one place to the right. The leftmost bit becomes a zero and the rightmost bit is discarded.

<: Shift Left

This instruction shifts every bit in A one place to the left. The rightmost bit becomes a zero and the leftmost bit is discarded.

@: Swap Nybbles

This instruction swaps the top four bits of A with the bottom four bits. For example, If A is 01101010 and you execute @, A will be 10100110:

 ____________________ | | 0110 1010 1010 0110 |_______| 

That's all the instructions! Simple, right?

Rules

  • Your program must accept input once at the beginning. This will be a line of code. This is not an interactive interpreter! You can only accept input once and do not have to loop back to the start once that line has been executed.
  • Your program must evaluate said input. Every character that is not mentioned above is ignored.
  • Your program should then print out the final value of the accumulator, in decimal.
  • Usual rules for valid programming languages apply.
  • Standard loopholes are disallowed.
  • This is , smallest byte count wins.

Here are some small programs to test out your submissions. Before the arrow is the code, after it is the expected result:

  • ! -> 255
  • !>> -> 63
  • !<@ -> 239
  • !nop!&6*! -> 255

Enjoy!

share|improve this question
    
I'm presuming from ! -> 255 that we're to use 8 bits per byte here? The question isn't explicit. – Toby SpeightSep 9 '15 at 12:10
1  
@TobySpeight A byte, by definition, is 8 bits. – Alex L.Feb 15 at 0:30

27 Answers 27

Pyth, 36 35 bytes

u%@[t_G/G2yGi_jGJ16JG)x"!><@"H256z0 

<@"H256z0&test_suite=1&test_suite_input=! !>> !<@ !<&&debug=0">Test harness

The internal representation of the accumulator is an integer. This integer is mod-ed by 256 on each iteration, as desired. The operations performed are -G-1, G/2, G*2 and G converted to base 16, reversed, and converted back to base 10, where G is the accumulator.

I missed the line about ignoring everything else. This has been remedied. Thanks, @Dennis.

share|improve this answer

C, 96

Assuming ASCII (or compatible) input:

a;main(c){while(c=getchar()+1)a=(c^34?c^61?c^63?c^65?a:a*257/16:a/2:a*2:~a)&255;printf("%u",a);} 

Tidier:

a; main(c){ while(c=getchar()+1) a=(c^34? c^61? c^63? c^65? a : a*257/16 : a/2 :a*2:~a )&255; printf("%u",a); } 

Basically it's just a collection of nested ternary expressions. I'm incrementing the value obtained from getchar() so that an EOF (-1) results in a value of zero and the program exits.

(ideone link)

share|improve this answer
1  
I tried the challenge myself and I wrote almost exactly the same code. Btw. your program doesn't drop the bit when shifting upwards (input: !<> should result in 127 and not 255). Either define your a as char, or use the line a&=255 (and use %u) to get the correct effect. Also you can shorten your negation a^255 to ~a. a>>4&15 is also shorter than your (a&240)/16. – MarcDefiantSep 8 '15 at 12:53
    
Ah, good point. Turns out it was more efficient to mask out the lower 8 bits at each iteration. – squeamish ossifrageSep 8 '15 at 13:10
1  
In this case you can even use the format string %u instead of %hhu – MarcDefiantSep 8 '15 at 13:19
1  
I just saw it now, but you can also use a/16|a*16 instead of a/16|(a&15)*16. The few bits on top get removed by the &255. – MarcDefiantSep 8 '15 at 13:27
1  
A tiny improvement: a*257/16 is one byte shorter than a/16|a*16. – Toby SpeightSep 9 '15 at 12:37

Python 3, 133 bytes

Uses a dictionary to make up for a lack of switch-case syntax in Python. See more here.

a="0"*8 for i in input():a={"!":''.join(str(1-int(b))for b in a),"<":a[1:]+"0",">":"0"+a[:-1],"@":a[4:]+a[:4]}.get(i,a) print(int(a,2)) 

The accumulator is a string which is converted into a base 10 number at the end.

Example I/O:

$ python3 bitsnbytes.py ! 255 $ python3 bitsnbytes.py !>> 63 $ python3 bitsnbytes.py !<@ 239 $ python3 bitsnbytes.py !nop!&6*! 255 
share|improve this answer
    
If it was a real, interactive interpreter, it would be for i in sys.stdin: :) – Zizouz212Sep 7 '15 at 16:15
4  
@Zizouz212 I believe you mean if it was interactive; it looks like a real interpreter to me. ;) – Alex A.Sep 7 '15 at 16:25

Javascript (ES6), 8091 90 bytes

a=>[...a].reduce((p,c)=>c=='!'?p^255:c=='<'?p*2%256:c=='>'?p>>1:c=='@'?p/16|0+p%16*16:p,0) 

Pretty much as short as it can get. Defines an anonymous function which takes the program as input.

  • For !, takes x XOR 255, as JS's ~ would consider x a 32-bit number.
  • For <, multiplies x by 2 and takes the result mod 256.
  • For >, truly shifts the bits of x 1 bit to the right.
  • For @, floors x/16 and adds it to x%16*16.

Thanks to @vihan for suggesting the use of reduce to save a byte.

share|improve this answer
    
You can use < to save around 4 bytes. Using reduce might also save some bytes – DowngoatSep 7 '15 at 16:52
1  
@vihan Do you mean < in place of ==? If so, that wouldn't work, as no-op characters would incorrectly perform an operation. I used that in my previous, 80-byte solution. – ETHproductionsSep 8 '15 at 1:26
    
Isn't ES6 fat arrow standard on PPCG that you have to define it? – MayorMontySep 9 '15 at 0:09
    
@SpeedyNinja I don't know of any such standard, but if you could point me to a post about one, I'll modify my answer. – ETHproductionsSep 9 '15 at 3:05

CJam, 37 bytes

0q{"!><@"#"~ 2/ 2* GmdG*+ "S/=~255&}/ 

Try it online in the <@"#"~ 2/ 2* GmdG*+ "S/=~255&}/&input=!<@" rel="nofollow">CJam interpreter.

How it works

0 e# Push 0 (accumulator). q e# Read from STDIN. { e# For each character in the input: "!><@"# e# Find its index in "!><@" (-1 if not found). "~ 2/ 2* GmdG*+ " e# Push that string. S/ e# Split at spaces to push ["~" "2/" "2*" "GmdG*+" ""]. e# "~" : signed 64-bit bitwise NOT e# "2/" : divide by 2 e# "2*" : multiply by 2 e# "GmdG*+" : (x) -> (x/16) (x%16) -> (16(x%16) + (x/16)) e# "" : NOOP =~ e# Select the corresponding string and evaluate it. 255& e# Zero all but the 8 least significant bits. }/ e# 
share|improve this answer

Rust, 121 115 bytes

fn r(s:&str)->u8{let mut n=0u8;for t in s.chars(){match t{'!'=>n=!n,'>'=>n/=2,'<'=>n<<=1,'@'=>n=n>>4|n<<4,_=>()}}n} 

Sample run:

fn main() { println!("{}", r("!")); //=> 255 println!("{}", r("!>>")); //=> 63 println!("{}", r("!<@")); //=> 239 } 

Ungolfed:

fn run_ungolfed(s: &str) -> u8 { let mut n = 0u8; for t in s.chars() { match t { '!' => n = !n, '>' => n >>= 1, '<' => n <<= 1, '@' => n = (n >> 4) | (n & 15) << 4, _ => () } } n } 

Surprisingly short for Rust. Nothing else really interesting other than the fact that I learned more precedence rules today—who knew (a>>b)|c is the same as a>>b|c?

Shaved off a byte by changing n>>=1 to n/=2; however, the same cannot be done with multiplication, because arithmetic overflow is a panic (i.e. crash) in Rust.

share|improve this answer
2  
The precedence thing makes sense when you convince yourself that >> is sort of like division and | is sort of like addition. – LynnSep 7 '15 at 20:23

HP 41C/CV/CX (? bytes, 42 steps)

Purely for giggles, here it is for the HP 41C/CV/CX calculator. (Requires either the Extended Functions module, or a 41CX for the ATOX function.) The calculator doesn't report program sizes in bytes, unfortunately.

Put your program into the Alpha register, which is a little tricky, as there's no way to enter ! or @ directly from the keyboard (use XTOA with the ASCII codes 33 and 64 respectively to append them).

Steps 08 and 10 allow for ignoring invalid opcodes; remove them to save 2 steps, but the program will crash on invalid input.

01 LBL"BB 02 0 03 LBL A 04 ATOX 05 X=0? 06 GTO E 07 X<>Y 08 SF 25 09 XEQ IND Y 10 CF 25 11 GTO A 12 LBL 33 13 255 14 X<>Y 15 - 16 RTN 17 LBL 60 18 2 19 * 20 256 21 MOD 22 RTN 23 LBL 62 24 2 25 / 26 INT 27 RTN 28 LBL 64 29 RCL X 30 16 31 / 32 INT 33 X<>Y 34 16 35 * 36 256 37 MOD 38 + 39 RTN 40 LBL E 41 RDN 42 RTN 
share|improve this answer

Python 2, 79 bytes

I realized that I have done something very similar to this in Python earlier. This is just a port of my Ruby answer, but it is incidentally the shortest Python answer as of now :D

a=0 for i in raw_input():a=[~a,a/2,a*2,a*16+a/16,a]["!><@".find(i)]&255 print a 

The difference from the Ruby version is that this one doesn't ignore invalid instructions while iterating over the input. Instead I take advantage of the fact that Python tends to return -1 instead of nil when there is no match -- The current value of a is appended to the back of the result array, so that all invalid instructions maps to the same, unchanged value.

share|improve this answer

Java (8), 514483411366359239224229198194187186184182181180 177 characters

Wow, this has been golfed down a LOT! Thanks to everyone who gave me suggestions! I greatly appreciate it!

interface T{static void main(String[]g)throws Exception{int i,a=0;while((i=System.in.read())!=10)a=(i==33?255-a:i==62?a/2:i==60?a*2:i==64?a>>4|a<<4:a)%256;System.out.print(a);}} 

Golfed 31 (!) bytes by optimizing the nibble swap with bitwise operations as opposed to lengthy Integer.??? methods.

Golfed 72 (!!!!) chars by removing the unnecessary string created to swap nibbles. Much better than before!?

Golfed 45 (!!) chars by removing use of java.util.Scanner and reading from System.in directly. Note that now that the lambda expression is gone, Java 8 is no longer required! Just merely Java 1 would do!

Golfed 7 chars by making class (default) (removed public keyword), thanks to @bmarks

Golfed 120 (!!!!!!!) chars by turning all those lengthy Integer class operations in the bit flipping to 255 - a. Now that's much shorter!

Golfed 15 (!) chars by converting shifts to multiplication and division, removing the braces from the while statement, and making a local within the main method.

Ungolfed 9 =( chars because of a problem with the left shift not discarding the leftmost byte. Therefore, I now do mod (256). The right shift will make the resulting number one bit shorter than before, so there is no need to use mod on right shift. My nibble-swap thing will swap the last 4 bits and the second-last nibble, and the and (&) truncates all other bits. My inversion program doesn't cause any problems if the original number is less than 256.

Golfed 31 35 chars thanks to @Geobits by converting switch statement to a lot of ternary statements, and also converting chars to ints, shortening the literals.

Golfed 7 chars by removing unnecessary &240 in the nibble swap ((a&240)>>4 to a>>4 and converting (a&15)<<4 to a<<4&240. The last change only golfed one character though.

Golfed 1 char by removing unnecessary = in a /= 2, because a = a /= 2 is equivalent to a = a / 2.

Golfed 2 chars by turning println to print.

Golfed 2 chars by removing accidental a= in a=255-a (a=a=255-a is equivalent to a=255-a)

Golfed 1 char by turning a<<4&240 into a%16<<4.

Golfed 1 char by adding brackets to the outside of the ternary statement and doing %256. That way, the %16 is unnecessary in the left-shift part of the nibble swap. The brackets add 2 chars and the %16 saves 3 chars.

Golfed 3 chars by changing class to interface and removing public using Java 8's static interface method feature. Thanks to @TheNumberOne (no comment, but find his answer on "Tips for golfing in Java"

share|improve this answer
    
I don't think the class has to be public. Also, I think if you make a an Integer instead of an int, you could do a.parseInt, a.toString, etc. instead of Integer.parseInt,Integer.toString, etc. – bmarksSep 8 '15 at 3:02
    
Thanks for the first suggestion; I'm going to remove all Integer class methods though. – Alex L.Sep 8 '15 at 23:18
    
Perhaps you can do while((i=System.in.read())>10) instead of !=10 to save a byte? – bmarksSep 9 '15 at 0:29
    
Good idea, but then anything below 10 will cause the program to terminate, and I'm supposed to ignore other characters, not make then the end of the world (or at least my program:)) I'll consider it though; perhaps there are no valid ascii characters below 10. – Alex L.Sep 9 '15 at 0:33
3  
It's almost never worth it to use a switch while golfing. The case/break are just too long. You should be able to save a bunch by making the whole thing a ternary; something like a=i=='!'?255-a:i==62?a/2:i=='<'?a*2%256:i=='@'?(a&240)>>4|(a‌​&15)<<4:a; – GeobitsSep 9 '15 at 13:51

Python 3, 12494 93 bytes

a=0 for i in input(): if i in"!><@":a=(i=='!')*(255-a)+(i==">")*a//2+(i=="<")*(a+a)%256+(i=="@")*(16*(a%16)+a//16) print(a) 

"!" is same as subtracting from 255.
"<" is same as multiplying by 2. But 8 bit register means mod 256.
">" is same as integer division by 2.
"@" means shifting last 4 bits (a%16) by 4 bits(*16) and adding the first four bits(a/16).

EDIT (read shameless copying)
Saw the other answer in python (by Beta decay). It uses a really effective way to simulate switch cases using dictionary. Using that we can write

a=0 for i in input():a={"!":255-a,"<":a<<1&255,">":a//2,"@":(a%16)<<4+a>>4}.get(i,a) print(a) 

Thanks, Beta Decay.

share|improve this answer
    
No matter what operation you do, you have to reduce mod 256 right? So why not do that at the end: a={"!":255-a,"<":a*2,">":a//2,"@":(a%16)<<4+a>>4}.get(i,a)%2‌​56. This immediately saves you a byte (because you'll do a*2 instead of a<<1)...but @daniero's answer also shows that if you do it this way then (a%16)<<4 can be shortened to just a<<4, because any bit 16 or larger will be eliminated once you multiply it by 16 and reduce it mod 256. Nice! Also, you can now replace 255-a by -1-a...or better, by just ~a. Altogether, these suggestions should save you 9 bytes. – mathmandanSep 9 '15 at 6:06

Haskell, 89 bytes

a#'!'=255-a a#'>'=div a 2 a#'<'=mod(a*2)256 a#'@'=mod(a*16)256+div a 16 a#_=a f=foldl(#)0 

Usage example: f "!>>" -> 63

share|improve this answer

Python 3, 127 bytes

Edit: shorting, thanks @Jakube

Edit2: fix, thanks @Anachor

a=0 for i in input():a=(a^255if i=="!"else a>>1if i==">"else a<<1if i=="<"else(a&15)<<4|(a&240)>>4if i=="@"else a)&255 print(a) 
share|improve this answer
    
Maybe this is because windows' new line. That's plus two bytes. I'll use that byte counter next time. :-) Thanks. – uno20001Sep 7 '15 at 18:32
    
Note that this doesn't discard the leftmost bit when left shifting, so !< gives 510 while it should be 254 – AnachorSep 7 '15 at 18:48
    
I hope now it does. Sorry for my mistakes, this is my first "golf" challenge. – uno20001Sep 7 '15 at 19:05

Ceylon, 297 290

shared void y(){value t=process.readLine()else"";variable Byte a=0.byte;for(c in t){switch(c)case('!'){a=a.not;}case('>'){a=a.rightLogicalShift(1);}case('<'){a=a.leftLogicalShift(1);}case('@'){a=a.and(#f0.byte).rightLogicalShift(4).xor(a.and(#f.byte).leftLogicalShift(4));}else{}}print(a);} 

Formatted:

shared void y() { value t = process.readLine() else ""; variable Byte a = 0.byte; for (c in t) { switch (c) case ('!') { a = a.not; } case ('>') { a = a.rightLogicalShift(1); } case ('<') { a = a.leftLogicalShift(1); } case ('@') { a = a.and(#f0.byte).rightLogicalShift(4).xor(a.and(#f.byte).leftLogicalShift(4)); } else {} } print(a); } 

#f and #f0 are hexadecimal numbers for the nibbles, .byte converts an integer into a byte. I'm lucky that Byte's .string attribute already uses the unsigned representation of a byte. Ceylon also features a switch statement without fall-through, and a string is a list of characters, which can be iterated.

I also tried to cut those long shift method names down by using an aliasing import, but this actually becomes 7 bytes longer:

import ceylon.language{Byte{r=rightLogicalShift,l=leftLogicalShift}}shared void x(){value t=process.readLine()else"";variable Byte a=0.byte;for(c in t){switch(c)case('!'){a=a.not;}case('>'){a=a.r(1);}case('<'){a=a.l(1);}case('@'){a=a.and(#f0.byte).r(4).xor(a.and(#f.byte).l(4));}else{}}print(a);} 

Formatted:

import ceylon.language { Byte { r=rightLogicalShift, l=leftLogicalShift } } shared void x() { value t = process.readLine() else ""; variable Byte a = 0.byte; for (c in t) { switch (c) case ('!') { a = a.not; } case ('>') { a = a.r(1); } case ('<') { a = a.l(1); } case ('@') { a = a.and(#f0.byte).r(4).xor(a.and(#f.byte).l(4)); } else {} } print(a); } 

This might be useful if we need those methods a bit more often.

share|improve this answer

Ruby, 81 73 bytes

So much simpler -- no eval! For each valid character in the input, it evaluates each instruction, and finds the appropriate instruction through the index of $& (the current character in the input).

a=0 gets.scan(/[!><@]/){a=[~a,a/2,a*2,a*16+a/16]["!><@".index$&]&255} p a 
share|improve this answer
    
That's genius. Much shorter that any other way. 2 upvotes by me! – edc65Sep 9 '15 at 6:44
    
How can you double upvote...? – Alex L.Sep 12 '15 at 15:40
    
@JamesSmith He's probably referring to this and my python answer :) – danieroSep 12 '15 at 17:46
    
@danerio I see. – Alex L.Sep 12 '15 at 17:54

STATA, 197 bytes

di _r(a) gl b=0 forv x=1/`=length("$a")'{ gl c=substr("$a",`x',1) if"$c"=="!" gl b=255-$b if"$c"==">" gl b=int($b/2) if"$c"=="<" gl b=mod($b*2,256) if"$c"=="@" gl b=mod($b,16)*16+int($b/16) } di $b 

Ungolfed

display _request(a) //get the input via prompt and put in var a global b=0 //initialise A to be 0 forv x=1/`=length("$a")'{ //for loop from 1 to last char in a global c=substr("$a",`x',1) //get the char at index x in a if "$c"=="!" global b=255-$b //invert is the same as 255-A if "$c"==">" global b=int($b/2) //right shift is the same as A/2 (with integer division) if "$c"=="<" global b=mod($b*2,256) //left shift is the same as A*2%256 if "$c"=="@" global b=mod($b,16)*16+int($b/16) //nibble swap is the same as A%16*16+A/16 } display $b //display the result of A 

Does not work with the online interpreter and requires the non-free default interpreter. This would be somewhat easier with actual bitwise operations, but I don't think they're too useful for most of the common uses of STATA.

share|improve this answer

Rust, 111 bytes

More of a comment on @Doorknob's answer, but I don't have any rep for comments as I just created an account.

One can shave 10 bytes off his Rust solution with the following:

fn r(s:&str)->u8{let mut n=0u8;for t in s.chars(){n=match t{'!'=>!n,'>'=>n>>1,'<'=>n<<1,'@'=>n>>4|n<<4,_=>n}}n} 
share|improve this answer
    
I thought we could get even shorter using fold (doc.rust-lang.org/std/iter/trait.Iterator.html#method.fold) but surprisingly makes it a tad longer. – user4867444Sep 7 '15 at 18:41

JavaScript, 104

[].reduce.call(prompt(),function(a,i){return(i=='!'?~a:i=='>'?a/2:i=='<'?a*2:i=='@'?a>>4|a<<4:a)&255},0) 

Nested ternary operators map to instructions.

BITWISE AND is used to constrain our Number type to a single byte.

share|improve this answer

JavaScript (ES6), 81

As an unnamed function returning the accumulator value (in the line of the other ES6 answer - but my logic is quite different).

Bonus: you can pass an initial value of the accumulator. If not passed, starting value is 0 as by specific.

(p,a)=>(p.replace(/[!<>@]/g,i=>a=(i<'<'?~a:i<'>'?a*2:i<'@'?a/2:a<<4|a>>4)&255),a) 

Test running the snippet below in any EcmaScript 6 browser (I tested in Firefox)

f=(p,a)=>(p.replace(/[!<>@]/g,i=>a=(i<'<'?~a:i<'>'?a*2:i<'@'?a/2:a<<4|a>>4)&255),a) // TEST out=x=>O.innerHTML+=x+'\n' function go(x) { out(x+' -> '+f(x)) } go('!'),go('!>>'),go('!<@'),go('!nop!&6*!') // LESS GOLFED f=(p,a)=>( // a as a parameter // if not passed its value starts as undefined, then becomes NaN, but the operators '&' and '~' treat it as 0 p.replace(/[!<>@]/g, // execute following function for each character in ! < > @, ignore other chars i=>a=( i < '<'? ~a // tilde == binary not (can give a result wider than a byte) : i < '>'? a*2 // < shift left is *2 (can give a result wider than a byte) : i < '@'? a/2 // > shift right is /2 (can give a non integer result) : a<<4 | a>>4 // move nibbles around (can give a result wider than a byte) ) & 255 // any intermediate result is truncate to a byte ) ,a // return accumulator )
Test program:<input id=I><button onclick='go(I.value)'>go</button> <pre id=O></pre>

share|improve this answer

Julia, 1179486 73 bytes

p->(a=0x0;[a=c==33?~a:c==60?a<<1:c==62?a>>1:c!=64?a:a<<4|a>>4for c=p];1a) 

This is an anonymous function that accepts a string and returns an integer. To call it, assign it to a variable.

Ungolfed:

function f(p) # Initialize the accumulator to 0 as an 8-bit unsigned integer a = 0x0 # Loop over the characters in the input for c in p a = c == 33 ? ~ a : # '!' c == 60 ? a << 1 : # '<' c == 62 ? a >> 1 : # '>' c != 64 ? a : # no-op a << 4 | a >> 4 # '@' end # Convert the accumulator to a regular integer and return return Int(a) end 

Saved 8 bytes thanks to Sp3000 and 13 thanks to Dennis!

share|improve this answer

Crystal, 139 bytes

def f x b=0_u8 x.chars.each do|c| b=case c when'!' ~b when'>' b>>1 when'<' b<<1 when'@' b<<4|b>>4 else raise "" end end puts b end 
share|improve this answer

C# 193

void Main(){byte a=0;foreach(var c in Console.ReadLine()){if(c=='!')a=(byte)~a;if(c=='>')a=(byte)(a>>1);if(c=='<')a=(byte)(a<<1);if(c=='@')a=(byte)(((a&240)>>4)|((a&15)<<4));}Console.Write(a);} 
share|improve this answer
2  
Don't you need using System; or something like that to access Console.ReadLine and Console.Write without the System. prefix? – Alex A.Sep 7 '15 at 16:30
    
Also it seems to me that you shouldn't have to cast to byte for each operation but I could be wrong. – Alex A.Sep 7 '15 at 17:22

R, 194 bytes

b<-readline();A<-rep(0,8);s<-strsplit(b,"")[[1]];for(r in s){if(r=="!")A<-(A+1)%%2;if(r==">")A<-c(0,A)[1:length(A)];if(r=="<")A<-c(A,0)[-1];if(r=="@")A<-c(A[5:8],A[1:4])};print(sum(A*(2^(7:0)))) 

ungolfed

b <- readline() A <- rep(0, 8) s <- strsplit(b, "")[[1]] for (r in s) { if (r == "!") A <- (A + 1) %% 2 if (r == ">") A <- c(0, A)[1:length(A)] if (r == "<") A <- c(A, 0)[-1] if (r == "@") A <- c(A[5:8], A[1:4]) } print(sum(A*(2^(7:0)))) 
share|improve this answer
    
All the <- can be replaced by = here, thus reducing the code by 7 bytes. Additionally you might be able to replace the series of if statements by one call to switch (as in A=switch(r,"!"=(A+1)%%2, ...)) – plannapusApr 20 at 7:08
    
The resulting b=readline();A=rep(0,8);s=strsplit(b,"")[[1]];for(r in s)A=switch(r,"!"=(A+1)%%2,">"=c(0,A)[1:length(A)],"<"=c(A,0)‌​[-1],"@"=c(A[5:8],A[‌​1:4]),A);print(sum(A‌​*(2^(7:0)))) is 167 bytes. – plannapusApr 20 at 7:17

Lua, 344 char

a=string.rep("0",8) t=io.read() f={["!"]=function()local s="";for j=1,8 do s=s..(a:sub(j,j)=="0"and"1"or"0") end;return s end,[">"]=function() return "0"..a:sub(1,7) end,["<"]=function()return a:sub(2,8).."0"end,["@"]=function()return a:sub(5,8)..a:sub(1,4)end} for i=1,#t do a=(f[t:sub(i,i)]or function()return a end)()end print(tonumber(a,2)) 

Inspired by @Beta Decay's use of a string accumulator, seeing as lua has no byte type. Could probably be golfed more by using fewer functions.

share|improve this answer

RPL, 170.5 bytes

The input should be entered as a string on level 1.

\<< DEC 8 STWS \-> S \<< #0d 1 S SIZE FOR I "!><@" S I DUP SUB POS 1 + { \<< \>> NOT SR SL \<< DUP #16d / SWAP #16d * + \>> } SWAP GET EVAL NEXT \>> \>> 
share|improve this answer

K, 57 bytes

It's a start:

0{y+2*x}/(8#0){((~:;{-1_0,x};{1_ x,0};4!;{x})"!><@"?y)x}/ 

tested using Kona:

 f:0{y+2*x}/(8#0){((~:;{-1_0,x};{1_ x,0};4!;{x})"!><@"?y)x}/ ... f'("!";"!>>";"!<@";"!nop!&6*!") 255 63 239 255 

I might be able to do better in k5, but it's a complex series of tradeoffs- for example, converting binary to decimal is as easy as 2/, but the behavior of ? makes it harder to handle a default case for instruction lookup.

share|improve this answer

PHP, 189 bytes

<? $c='00000000';foreach(str_split($argv[1])as$a){$a=='!'&&$c=strtr($c,'01','10');$a=='<'&&$c=substr($c.'0',1);$a=='>'&&$c=substr('0'.$c,0,8);$a=='@'&&$c=substr($c.$c,4,8);}echo bindec($c); 

It's not that it gonna beat many answers, it's only for practice

share|improve this answer

HPPPL, 302 294 bytes

#pragma mode(separator(.,;)integer(d8))EXPORT b()BEGIN print();local p,j,a;a:=#0d;INPUT({{p,[2]}});for j from 1 to dim(p)do c:=p(j);case if c==33 then a:=BITNOT(a)end if c==62 then a:=BITSR(a,1)end if c==60 then a:=BITSL(a,1)end if c==64 then a:=BITSL(a,4)+BITSR(a,4)end end;end;print(a*1);END; 

Ungolfed:

// make sure integers are unsigned 8 bit decimal numbers #pragma mode( separator(.,;) integer(d8) ) EXPORT b() BEGIN print(); local p,j,a; a:=#0d; // set a to integer value 0 INPUT({{p,[2]}}); // open input dialog treating input as string ( type [2]) for j from 1 to dim(p) do c:=p(j); case if c==33 then a:=BITNOT(a) end // ! if c==62 then a:=BITSR(a,1) end // > if c==60 then a:=BITSL(a,1) end // < if c==64 then a:=BITSL(a,4)+BITSR(a,4) end // @ end; end; print(a*1); // converts to proper output by promoting to non integer format // print(a) would result in // #239:8d for 239 if the default bit size is not set to 8 bits decimal // indicating an 8 bit unsigned decimal integer, or // #239d if the default bit size is already set to 8 bits decimal END; 

HPPPL Input command

HPPPL Output to Terminal

This answer ensures that the HP Prime uses unsigned 8 bit integers even if the mode is set to e.g. 64 bits by the user. If the calculator is set up manually to using unsigned 8 bit decimal integers, then the pragma command can be omitted. If the output does not need to follow the format strictly then the a*1 at the end can simply be a. Multiplying the result by 1 just ensures the output does not follow the internal output for integer values. The print command in line 4 can also be omitted if the terminal does not need to be cleared before printing out the result. If passing the program as a string argument is allowed, then the INPUT command can be omitted as well.

This is the shortest version with input and proper output, without the pragma argument (if the calculator is set to Uint8 by default:

243 bytes:

EXPORT b()BEGIN local p,j,a;a:=#0d;INPUT({{p,[2]}});for j from 1 to dim(p)do c:=p(j);case if c=33 then a:=BITNOT(a)end if c=62 then a:=BITSR(a,1)end if c=60 then a:=BITSL(a,1)end if c=64 then a:=BITSL(a,4)+BITSR(a,4)end end;end;print(a*1);END; 
share|improve this answer

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

close