HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Brainfuck Printer Generator

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
brainfuckprintergenerator

Problem

Given a text, this program will output a Brainfuck program, that when executed will print the text back.


Writing Brainfuck in this style to print a sentence is pretty straightforward. Iterate over the sentence and do the following per character:



  • Calculate the difference between the current character and the previous



  • Write either as many + or - as the difference between characters. + if current character is higher than previous character, - if lower than previous character



  • Write . to print current character




Hello, World!

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.
+++++++++++++++++++++++++++++.
+++++++.
.
+++.
-------------------------------------------------------------------.
------------.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++.
++++++++++++++++++++++++.
+++.
------.
--------.
-------------------------------------------------------------------.


The code

def brainturing_printer_generator(text)
  ords = text.chars.map(&:ord)
  ("+" * ords.first + ".\n") + ords
    .zip(ords[1..-1])
    .take(ords.size - 1)
    .map {|prev, curr| (curr > prev ? "+" : "-") * (curr - prev).abs}
    .join(".\n") + ".\n"
end

print brainturing_printer_generator("Hello, World!")

Solution

It's neat, though I feel like there's a bit too much array manipulation going on.

Your friend for this, I'd argue, is the each_cons method, short for "each consecutive". Then you don't need the zip, though you do need to pad the beginning of the array.

Here's my take:

def brainturing_printer_generator(text)
  ords = [0] + text.chars.map(&:ord)
  ords.each_cons(2).map do |previous, current|
    delta = current - previous
    line = (delta < 0 ? "-" : "+") * delta.abs
    "#{line}."
  end.join("\n")
end

Code Snippets

def brainturing_printer_generator(text)
  ords = [0] + text.chars.map(&:ord)
  ords.each_cons(2).map do |previous, current|
    delta = current - previous
    line = (delta < 0 ? "-" : "+") * delta.abs
    "#{line}."
  end.join("\n")
end

Context

StackExchange Code Review Q#103912, answer score: 6

Revisions (0)

No revisions yet.