4
\$\begingroup\$

I wrote this interpreter for a code challenge. Can this be written any cleaner/smaller? Could I reduce the amount of nested conditional/loops?

def brain_luck(code, input)
 output = ''
 cp = 0 # code pointer
 dp = 0 # data pointer
 ip = 0 # input pointer
 data = Array.new(10, 0)
 while cp < code.length
 case code[cp]
 when '>'
 dp += 1
 if dp == data.length
 data.push(0)
 end
 when '<'
 dp -= 1
 if dp == -1
 dp = 0
 data.unshift(0)
 end
 when '+'
 data[dp] = (data[dp].ord+1)%256
 when '-'
 data[dp] = (data[dp].ord-1)%256
 when '.'
 output += data[dp].chr
 when ','
 data[dp] = input[ip].ord
 ip += 1
 when '['
 if data[dp] == 0
 nest_count = 1
 while nest_count > 0
 case code[cp += 1]
 when '[' then nest_count += 1
 when ']' then nest_count -= 1
 end
 end
 end
 when ']' 
 if data[dp] != 0
 nest_count = 1
 while nest_count > 0
 case code[cp -= 1]
 when ']' then nest_count += 1
 when '[' then nest_count -= 1
 end
 end
 end
 end
 cp += 1
 end
 output
end
asked Dec 19, 2016 at 23:14
\$\endgroup\$
5
  • \$\begingroup\$ I know you don't want to swear, but brain_luck is not the way to go. It's confusing since it doesn't make sense why there is a function like that. You could just do something like eval_program. \$\endgroup\$ Commented Dec 20, 2016 at 0:20
  • \$\begingroup\$ brain_luck was how the code challenge presented it (same with the double * in brainf**k) \$\endgroup\$ Commented Dec 20, 2016 at 0:33
  • \$\begingroup\$ Ok, if you need to submit it that way for the challenge, but outside of the challenge, I would highly recommend changing it. :) \$\endgroup\$ Commented Dec 20, 2016 at 0:35
  • 1
    \$\begingroup\$ Does it work for this BF-program now? ,>+>>>>++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++<<<<<<[>[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<[>++++++++++[-<-[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]]>[<<[>>>+<<<-]>>[-]]<<]>>>[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]]>[<<+>>[-]]<<<<<<<]>>>>>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]++++++++++<[->-<]>++++++++++++++++++++++++++++++++++++++++++++++++.[-]<<<<<<<<<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<-[>>.>.<<<[-]]<<[>>+>+<<<-]>>>[<<<+>>>-]<<[<+>-]>[<+>-]<<<-] \$\endgroup\$ Commented Dec 20, 2016 at 9:41
  • \$\begingroup\$ @SimonForsberg sure does ;) \$\endgroup\$ Commented Dec 20, 2016 at 21:08

1 Answer 1

1
\$\begingroup\$

Sure it can!

Steps I see to make it clean:

  1. Create a class, define state attrs:

    private
    attr_reader :output, :code_pointer, :data_pointer, :input_pointer
    
  2. define initialize method

    def initialize(args = {})
     @code = args[:code]
     @input = args[:input]
     @output = ''
     @code_pointer, @data_pointer, @input_pointer = 0, 0, 0
    end
    
  3. define whens as a methods and give it right names: next_cell, prev_cell, increment, decrement, write_byte, read_byte and so on

  4. define constant for configuration:

    OPERATORS = {
     '>' => :next_cell,
     '<' => :prev_cell,
     '+' => :increment,
     ...
    }
    
  5. define method to evaluate code:

    def evaluate_code
     code.each { |operator| public_send OPERATORS[operator] }
    end
    
  6. Finally instantiate object of your class and call evaluate_code

    BrainLuck.new(code: code, input: input).evaluate_code
    

I think you'll love your object oriented result.

answered Dec 27, 2016 at 13:52
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.