6
2

More than 1 year has passed since last update.

この記事誰得? 私しか得しないニッチな技術で記事投稿!

自作Brainf*ckインタプリタを使ってAtCoderをBrainf*ckで解く

Last updated at Posted at 2023-07-21

この記事は この記事誰得? 私しか得しないニッチな技術で記事投稿! - Qiita の参加記事です。

はじめに

記事のネタに困っており、ネタ探しをしていたら

の記事を見つけ、

自作のBrainf*ckインタプリタを使ってAtcoderの問題をBrainf*ckで解こう!

と思ってしまいました。

ここまできたらやるしかない(?)と思い、実際にやってみたので紹介します。

作戦

AtCoderでは、

  • Bashで問題を解くことができる
  • 環境にRubyがインストールされている様

なので、

  1. RubyでBrainf*ckインタプリタをつくる
  2. Bashスクリプト内でRubyでつくったBrainf*ckインタプリタを実行させる
  3. Brainf*ckのソースコード、問題で渡される標準入力をRubyの標準入力に渡す

でやることにしました。

Brainf*ckインタプリタをつくる

実際につくったものは以下のGistにあげてます。
この記事では詳細は省きます。

brainfuck.rb | GitHub Gist

AtCoder解答用のBashスクリプトをつくる

作戦の通りにつくったBashスクリプトは以下です。

AtCoderの問題を解くためのBrainf*ckのソースコードは

のものを使わせていただきました :pray:

cat <<EOS > main.rb
class Brainfuck
  MEMORY_SIZE = 100

  def initialize
    @pc = 0
    @pointer = 0
    @memory = Array.new(MEMORY_SIZE, 0)
  end

  # @param program [String]
  def run(program)
    while @pc < program.length
      op = program[@pc]

      case op
      when '>'
        @pointer += 1
      when '<'
        @pointer -= 1
      when '+'
        @memory[@pointer] += 1
      when '-'
        @memory[@pointer] -= 1
      when '.'
        print(@memory[@pointer].chr)
      when ','
        @memory[@pointer] = \$stdin.getc.ord
      when '['
        if @memory[@pointer] == 0
          depth = 0
          while @pc < program.length
            @pc += 1

            break if depth == 0 && program[@pc] == ']'

            case program[@pc]
            when '['
              depth += 1
            when ']'
              depth -= 1
            end
          end
        end
      when ']'
        if @memory[@pointer] != 0
          depth = 0
          while @pc >= 0
            @pc -= 1

            break if depth == 0 && program[@pc] == '['

            case program[@pc]
            when ']'
              depth += 1
            when '['
              depth -= 1
            end
          end
        end
      end

      @pc += 1
    end
  end
end

brainfuck = Brainfuck.new

line = gets
brainfuck.run(line)
EOS

source=",>++++++++++++++++++++++++++++++++++++++++++++++++++++++++<>[<[->>+>+<<<]>>>[-<<<+>>>]<<>[[-]<<->>]<-]<>>>>>>>>+<<<<<<<<[[-]>+++++++++[>++++++++++<-]>-.<+++[>++++<-]>.<+++++++[>++<-]>.>>>>>>-<<<<<<<<]>>>>>>>>[[-]>,>++++++++++++++++++++++++++++++++++++++++++++++++++++++++<>[<[->>+>+<<<]>>>[-<<<+>>>]<<>[[-]<<->>]<-]<>>>>>>>>+<<<<<<<<[[-]>+++++++++[>++++++++++<-]>-.<+++[>++++<-]>.<+++++++[>++<-]>.>>>>>>-<<<<<<<<]>>>>>>>>[[-]>+++++++++++[>+++++++<-]>+.<+++[>+++++++++++<-]>.<<]<<]"

read line1

ruby main.rb <<EOS
${source}
${line1}
EOS

いざ提出

結果は...

ACです!最高ですね!!

提出 #43807447 - AtCoder Beginner Contest 073

image.png

最後に

無事、自作Brainf*ckインタプリタを使ってAtCoderをBrainf*ckで解くことができました!
自分は何をしているのだろうと思ってはいけません。楽しければよかろうなのです。

みんなでBrainf*ck Lifeを楽しみましょう(?)

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