LoginSignup
2
2

More than 5 years have passed since last update.

Brainf*ck | RubyでBrainf*ckのコードを生成する

Posted at

Brainf*ck | RubyでBrainf*ckのコードを生成する

概要

RubyでBrainf*ckのコードを生成します。
必要に駆られたので作りました。
=>必要になった要因(https://codeiq.jp/ace/tbpgr/q943)

備考

使い捨てのコードなので美しくしようとか、汎用的にしようとか思って作ってません

愚直版生成器

brainf__k_foolish.rb
class BrainF__k
  class << self
    def increment(count = 1)
      '+' * count
    end

    def decrement(count = 1)
      '-' * count
    end

    def next_pointer(count = 1)
      '>' * count
    end

    def previous_pointer(count = 1)
      '<' * count
    end

    def output(count = 1)
      '.' * count
    end

    def comment(message)
      "; #{message}"
    end
  end
end

text = ARGV.first
codes = text.split('').map(&:ord).reduce('') do |codes, char|
  codes += BrainF__k.increment(char)
  codes += BrainF__k.output(1)
  codes += BrainF__k.next_pointer(1)
  codes += BrainF__k.comment("output #{char.chr}\n")
  codes
end

print codes

呼び出しサンプル

$ ruby brainf__k_foolish.rb 'brainf__k now'
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output b
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output r
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output a
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output i
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output n
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output f
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output _
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output _
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output k
++++++++++++++++++++++++++++++++.>; output
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output n
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output o
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>; output w

差分版生成器

brainf__k.rb
class BrainF__k
  attr_reader :tables, :init_codes, :pointer
  TEN_INCREMENT = '+' * 10

  def initialize(char, comment = '')
    comment = ";#{comment}" if comment
    char_code = char.ord
    repeat = char_code / 10
    rest = char_code % 10
    @tables = []
    @pointer = 0
    @init_codes = "#{TEN_INCREMENT}[>#{increment(repeat)}<-]>\n#{increment(rest)}#{comment}\n"
    @tables[@pointer] = char_code
  end

  def increment(count = 1)
    @tables[@pointer] = 0 unless @tables[@pointer]
    @tables[@pointer] += count
    '+' * count
  end

  def decrement(count = 1)
    @tables[@pointer] -= count
    '-' * count
  end

  def diff(char_code)
    diff_of_code = char_code - @tables[@pointer]
    return '' if diff_of_code.zero?
    @tables[@pointer] += diff_of_code
    diff_of_code > 0 ? ('+' * diff_of_code) : ('-' * diff_of_code.abs)
  end

  def next_pointer(count = 1)
    @pointer += count
    '>' * count
  end

  def previous_pointer(count = 1)
    @pointer -= count
    '<' * count
  end

  def output(count = 1)
    '.' * count
  end

  def comment(message)
    "; #{message}"
  end
end

text = ARGV.first
first_word = text[0]
bf = BrainF__k.new(first_word, "init by #{first_word}")
codes = text.split('').map(&:ord).reduce(bf.init_codes) do |codes, char|
  codes += bf.diff(char)
  codes += bf.output(1)
  codes += bf.comment("output #{char.chr}\n")
  codes
end

print codes

呼び出しサンプル

$ ruby brainf__k.rb 'hello brainf__k'
++++++++++[>++++++++++<-]>
++++;init by h
.; output h
---.; output e
+++++++.; output l
.; output l
+++.; output o
-------------------------------------------------------------------------------.; output
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.; output b
++++++++++++++++.; output r
-----------------.; output a
++++++++.; output i
+++++.; output n
--------.; output f
-------.; output _
.; output _
++++++++++++.; output k

参照

GitHubに置きました

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2