概要
paiza.ioでelixirやってみた。
練習問題やってみた。
練習問題
Forthインタープリタを書け。
forthで数9を4個つかって1から15までの数を表す式を実行せよ。
Enumを使え。
サンプルコード
defmodule Forth do
def start_link do
Agent.start_link(fn ->
[]
end, name: __MODULE__)
end
def add do
Agent.update(__MODULE__, fn stack ->
po = Enum.count(stack) - 1
top = Enum.at(stack, po)
tmp = Enum.with_index(stack)
po = po - 1
stack = Enum.map(tmp, fn {val, ind} ->
cond do
ind == po ->
val + top
true ->
val
end
end)
stack = Enum.drop(stack, -1)
end)
end
def sub do
Agent.update(__MODULE__, fn stack ->
po = Enum.count(stack) - 1
top = Enum.at(stack, po)
tmp = Enum.with_index(stack)
po = po - 1
stack = Enum.map(tmp, fn {val, ind} ->
cond do
ind == po ->
val - top
true ->
val
end
end)
stack = Enum.drop(stack, -1)
end)
end
def mul do
Agent.update(__MODULE__, fn stack ->
po = Enum.count(stack) - 1
top = Enum.at(stack, po)
tmp = Enum.with_index(stack)
po = po - 1
stack = Enum.map(tmp, fn {val, ind} ->
cond do
ind == po ->
val * top
true ->
val
end
end)
stack = Enum.drop(stack, -1)
end)
end
def div do
Agent.update(__MODULE__, fn stack ->
po = Enum.count(stack) - 1
top = Enum.at(stack, po)
tmp = Enum.with_index(stack)
po = po - 1
stack = Enum.map(tmp, fn {val, ind} ->
cond do
ind == po ->
val / top
true ->
val
end
end)
stack = Enum.drop(stack, -1)
end)
end
def dup do
Agent.update(__MODULE__, fn stack ->
po = Enum.count(stack) - 1
top = Enum.at(stack, po)
stack = Enum.concat(stack, [top])
end)
end
def drop do
Agent.update(__MODULE__, fn stack ->
stack = Enum.drop(stack, -1)
end)
end
def get do
Agent.get(__MODULE__, fn stack ->
po = Enum.count(stack) - 1
Enum.at(stack, po)
end)
end
def push(n) do
Agent.update(__MODULE__, fn stack ->
{v, _} = Integer.parse(n)
stack = Enum.concat(stack, [v])
end)
end
end
defmodule Main do
def run(str) do
Enum.map(String.split(str, " "), fn s ->
cond do
s == "+" ->
Forth.add
s == "-" ->
Forth.sub
s == "*" ->
Forth.mul
s == "/" ->
Forth.div
s == "dup" ->
Forth.dup
s == "drop" ->
Forth.drop
s == "." ->
IO.inspect Forth.get
true ->
Forth.push(s)
end
end)
end
end
Forth.start_link
Main.run("9 9 - 9 9 / .")
Main.run("9 9 / 9 9 / + .")# 2 ok
Main.run("9 9 + 9 + 9 / .")# 3 ok
Main.run("9 9 9 + 9 / dup + .")# 4 ok
Main.run("9 9 9 + 9 / dup + - .")# 5 ok
Main.run("9 dup 9 + 9 + 9 / - .")# 6 ok
Main.run("9 9 9 + 9 / - .")# 7 ok
Main.run("9 9 9 drop 9 / - .")# 8 ok
Main.run("9 9 - 9 * 9 + .")# 9 ok
Main.run("9 9 / 9 dup 9 / + .")# 10 ok
Main.run("9 9 9 + 9 / + .")# 11 ok
Main.run("9 dup 9 9 + + 9 / + .")# 12 ok
Main.run("9 9 9 + 9 / dup + + .")# 13 ok
Main.run("9 dup 9 9 + 9 / dup + - + .")# 14 ok
Main.run("9 dup dup 9 + 9 + 9 / - + .")# 15 ok
実行結果
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9
10.0
11.0
12.0
13.0
14.0
15.0
成果物
以上。