Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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

20 Answers 20

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 bitnbytes.py
!
255
$ python3 bitnbytes.py
!>>
63
$ python3 bitnbytes.py
!<@
239
$ python3 bitnbytes.py
!nop!&6*!
255
share|improve this answer
    
If it was a real, interactive interpreter, it would be for i in sys.stdin: :) –  Zizouz212 19 hours ago
3  
@Zizouz212 I believe you mean if it was interactive; it looks like a real interpreter to me. ;) –  Alex A. 19 hours ago

Pyth, 36 35 bytes

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

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

Javascript (ES6), 80 91 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 –  vihan 18 hours ago
    
@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. –  ETHproductions 10 hours ago

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. –  Mauris 15 hours ago

CJam, 37 bytes

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

Try it online in the 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

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. –  uno20001 17 hours ago
    
Note that this doesn't discard the leftmost bit when left shifting, so !< gives 510 while it should be 254 –  Anachor 16 hours ago
    
I hope now it does. Sorry for my mistakes, this is my first "golf" challenge. –  uno20001 16 hours ago

Python 3, 124 94 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
    
I don't know that much Python, but can you replace each == with a <? –  Ypnypn 8 hours ago
    
@Ypnypn The problem requires that unnecessary characters be ignored. That's why < won't work here. –  Anachor 3 hours ago

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

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

Julia, 117 bytes

p=readline();a=0x0;for c=p c=='!'?(a=~a):c=='<'?(a=a<<1):c=='>'?(a=a>>1):c=='@'?(a=16(a%16)+a÷16):0end;print(int(a))

Ungolfed:

# Read the program as a string from STDIN
p = readline();

# Initialize the accumulator to 0 as an 8-bit unsigned integer
a = 0x0

# Loop over the characters in the input
for c in p
    if c == '!'
        a = ~a
    elseif c == '<'
        a = a << 1
    elseif c == '>'
        a = a >> 1
    elseif c == '@'
        a = 16(a%16) + a÷16
    else
        0 # no-op
    end
end

# Print the value of the accumulator to STDOUT
print(int(a))
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. –  user4867444 17 hours ago

C, 107

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

Tidier:

a;
main(c) {
  while(c=getchar()+1)
    a=c^34?
      c^61?
        c^63?
          c^65?
            a
          :(a&240)/16|(a&15)*16
        :a/2:a*2
      :a^255;
    printf("%hhu",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

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

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

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. 19 hours ago
    
Also it seems to me that you shouldn't have to cast to byte for each operation but I could be wrong. –  Alex A. 18 hours ago

Java, 514 483 411 366 characters

public class T{static int a;public static void main(String[]g)throws Exception{int i;while((i=System.in.read())!='\n'){switch(i){case'!':a=Integer.parseInt(String.format("%8s",Integer.toString(a,2)).replaceAll("[1 ]","0").replaceAll("0","_").replaceAll("_","1"),2);break;case'>':a>>=1;break;case'<':a<<=1;break;case'@':a (a&240)>>4|(a&15)<<4;}}System.out.print(a);}}

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

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

Golfed 45 (!!) bytes 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!

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. –  bmarks 8 hours ago

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

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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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