The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Ruby Brainfuck golf [Update]

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Jan Lelis

Posts: 136
Nickname: rbjl
Registered: Aug, 2009

Jan Lelis is an IT student from Dresden/Germany
Ruby Brainfuck golf [Update] Posted: Oct 7, 2009 10:06 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Jan Lelis.
Original Post: Ruby Brainfuck golf [Update]
Feed Title: rbJ*_*L.net
Feed URL: http://feeds.feedburner.com/rbJL
Feed Description: Hi, I am a fan of Ruby and like to explore it and the world around ;). So I started this blog, where I am publishing code snippets, tutorials for beginners as well as general thoughts about Ruby, the web or programming in general.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Jan Lelis
Latest Posts From rbJ*_*L.net

Advertisement

Some days ago, I discovered a website – which is the most addicting one I know :) – codegolf.com. The goal is, to solve programming problems with as short code as possible.

As I said, it is addicting. You do not write better ruby code by golfing. But you can really improve the knowledge of the language. And it is fun :)

Brainfuck

After doing some of the other challenges I tried the brainfuck challenge.
Brainfuck is a Turing-complete esoteric programming language consisting only of 8 letters, operating on a 30000 cells-array. This is the hello world program:

>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]
<.>+++++++++++[<++++++++>-]<-.--------.+++.------.--------.[-]>++++++++[<++++>-
]<+.[-]++++++++++.

The goal is to build a interpreter.\nh3. A basic brainfuck interpreter

This is my first one. It is not that fast, but works fine.

f,e=$<.read.split'!'
e&&e=e.split('')
b=[a=i=n=0]*s=30000
while i<f.size
  case f[i]
  when ?>
    a+=1
  when ?<
    a-=1
  when ?+
    b[a]+=1
  when ?-
    b[a]-=1
  when ?.
    putc b[a]
  when ?,
    e==[]?i=s:b[a]=e.shift[0]
  when ?[
    n=d=1 if b[a]==0
  when ?]
  n,d=1,-1 if b[a]!=0
  end
  
  while n>0
    i+=d
    f[i]==?[&&n+=d
    f[i]==?]&&n-=d
  end
  i+=1
end
  • About 300 Byte without the whitespaces.
  • Cannot calculate all square numbers till 1000 within 4 seconds..

There are some possibilities to shorten the code.. but not, to get down to 107 Bytes (that is the size of the brainfuck interpreter by the Ruby golfing god flagitious)! I had recognized, that I needed another approach.

Playing code golf

To understand the following solution better, here are the specifications about the brainfuck interpreter for the challenge:

  • The Ruby version is 1.8.5
  • The input for the brainfuck program is directly appended, split by an exclamation mark
  • There is no cell overflow (255 + 1 = 256, not 0)
  • The result of the tests (see the golfcode challenge page) has to be calculated within 4 seconds
  • You don’t need 30000 cells, just enough to pass the tests
  • The input is well formed brainfuck (…no “comments” are in it [except new lines])
  • Exiting with an error is fine, as long the output is right :)

The ansatz is:

eval

Every letter of the brainfuck program is translated into ruby and then executed via eval. Then, some golfing tricks are applied. For example the global variable

$$
holds a (big) process number, which are enough cells. There are some more nice golfing tips at the codegolf-board (Thanks).

After lots of hours and hours (days!) of thinking, trying, depression, but also with senses of achievement, this is my result:

Ruby Brainfuck interpreter in 158 Bytes

gets'!'
%w(! [ ] + - > < . ,).zip(%w{9 ( )while(0!=b[a]) b[a]+=1 b[a]-=1 a+=1 a-=1 putc(b[a]) (b[a]=getc)<11&&1/0}).map{|a,b|gsub a,b+$/}
eval"b=[a=0]*$$
"+$_

It’s so crazy… I don’t know (yet) how it’s possible to shrink it another 51 Bytes °_°

Update

I wanted to get into the top ten! So I thought and thought… and discovered that It actually is possible to get it shorter ;).

To get down to 149 Bytes I used the gsub mechanism of the 158 Byte solution, that was already there, to substitute some often used fragments of the code words. I also got some Bytes by putting the initialization out the eval.

Ruby Brainfuck interpreter in 149 Bytes

gets'!'
%w(! + - > < [ ] . , j k).zip(%w{9 j+k j-k a+k a-k ( )until(j==0); putc(j); (j=getc)<11&&1/0; b[a] =1;}).map{|a,b|gsub a,b}
b=[a=0]*$$
eval$_

Won some Bytes!

Then I had been puzzled again.. and searched the internet. After reading some code of some top golfers (ruby but also perl), I realized the big trick: Instead of using the direct brainfuck commands to get the right eval code fragment, you can us their ASCII values by mapping them to low numbers. These can be used for (very short) Array access!

So how to find these mappings? I did it by writing a little bruteforce C programm (in C because I mistakenly thought, it will take some time to find a formula, but it got lots in seconds)

Now, I had to iterate over each sourcecode character instead of using gsub, so I could not use the “compression” substitution anymore. But nevertheless it is far shorter.

Ruby Brainfuck interpreter in 137 Bytes

b=[a=0]*$$
gets'!'
eval split('').map{|z|%w{b[a]+=1 (b[a]=getc)<11&&1/0 b[a]-=1 putc(b[a]) 9 ( a-=1 )while(b[a]!=0) a+=1}[z[0]%32%11]}*$/

Yeah! Got into the top ten!

Ruby Brainfuck interpreter in 125 Bytes

I did it. It is possible. I could not believe it myself. Now it is up to you, to find out how ;)

Ruby Brainfuck interpreter in 107 Bytes

…is the one by flagitious. Magic.

(He has not to obey the Ruby interpreter, the Ruby interpreter obeys him!)

CC-BY-SA (DE)

Read: Ruby Brainfuck golf [Update]

Topic: Felipe Elias Philipp Winner RPCFN #1 Previous Topic   Next Topic Topic: JavaScript Module pattern – overused, dangerous and bloody annoying

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use