Skip to content

Instantly share code, notes, and snippets.

@youknowcast
Last active March 11, 2023 17:54
Show Gist options
  • Save youknowcast/a8d0a5433043f76a9ef935d4acd8387c to your computer and use it in GitHub Desktop.
Save youknowcast/a8d0a5433043f76a9ef935d4acd8387c to your computer and use it in GitHub Desktop.
3,4,7,8 を使って 10 を作る
defmodule Calculator do
def calc() do
tests()
end
defp tests() do
val_permutation()
|> Enum.map(fn v ->
expr_product()
|> Enum.map(fn x ->
templates()
|> Enum.map(fn t ->
keywords = [
A: Enum.at(v, 0),
B: Enum.at(v, 1),
C: Enum.at(v, 2),
D: Enum.at(v, 3),
a: Enum.at(x, 0),
b: Enum.at(x, 1),
c: Enum.at(x, 2)
]
expr = Enum.reduce(keywords, t, fn {key, value}, acc ->
String.replace(acc, ~r/#{key}/, to_string(value))
end)
try do
{ret, _} = Code.eval_string(expr)
if ret == 10 do
IO.puts expr
end
rescue
# エラーは無視
ArithmeticError ->
nil
end
end)
end)
end)
end
defp templates() do
[
"(AaBbCcD)",
"((AaB)bCcD)",
"((AaBbC)cD)",
"(Aa(BbCcD))",
"((AaB)b(CcD))",
"(Aa(BbC)cD)",
"(AaBb(CcD))"
]
end
defp val_permutation() do
permutations([3, 4, 7, 8])
end
defp permutations([]), do: [[]]
defp permutations(list) do
for elem <- list, p <- permutations(list -- [elem]), do: [elem | p]
end
defp expr_product() do
base = ["+", "-", "*", "/"]
for x <- base, y <- base, z <- base, do: [x, y, z]
end
end
Calculator.calc()
class Calculator
def call
# X+X+X+X
calc("%s%s%s%s%s%s%s")
# (X+X)+X+X
calc("(%s%s%s)%s%s%s%s")
# (X+X+X)+X
calc("(%s%s%s%s%s)%s%s")
# X+(X+X+X)
calc("%s%s(%s%s%s%s%s)")
# (X+X)+(X+X)
calc("(%s%s%s)%s(%s%s%s)")
# X+(X+X)+X
calc("%s%s(%s%s%s)%s%s")
# X+X+(X+X)
calc("%s%s%s%s(%s%s%s)")
end
private
def tests
return @tests if @tests
# / で計算するので 10 と判定するために float にする
# (厳密にはダメなケースもありそうだけど今回は妥協)
vals = %w[3.0 4.0 7.0 8.0]
exprs = %w[+ - * /]
val_perm = vals.permutation(4)
expr_products = exprs.product(exprs, exprs)
@tests = []
val_perm.each do |v|
expr_products.each do |x|
@tests << [ v[0], x[0], v[1], x[1], v[2], x[2], v[3] ]
end
end
@tests
end
def calc(template)
tests.each do |t|
test = sprintf(template, *t)
ret = eval(test)
p "#{ret} : #{test}" if ret == 10
end
end
end
Calculator.new.call
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment