Skip to content

Instantly share code, notes, and snippets.

@al2o3cr
Created May 23, 2021 03:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save al2o3cr/1bfd8f7c4570d6c08b102912386e4fc6 to your computer and use it in GitHub Desktop.
Save al2o3cr/1bfd8f7c4570d6c08b102912386e4fc6 to your computer and use it in GitHub Desktop.
Solution for "four fours" problem

Fours

A partial solution to the problem posed here: https://twitter.com/mikelikesbikes/status/1396159019837018117

This solution represents the expressions in reverse Polish notation (RPN) - see also Forth and HP48s.

The version presented here does NOT produce all values from 1 to 100, as it does not use enough operators.

Extending the search to additional operators only requires adding the value to @operators and a clause to eval to handle it.

defmodule Fours do
@operators [:add, :sub, :mul, :div]
def seqs(prefix, 0, 1), do: Enum.map(@operators, &(prefix ++ [&1]))
def seqs(prefix, fours, _) when fours < 0, do: []
def seqs(prefix, fours, 0), do: [prefix ++ List.duplicate(4, fours)]
def seqs(prefix, fours, ops) do
@operators
|> Enum.map(&seqs(prefix ++ [&1], fours, ops-1))
|> Kernel.++([seqs(prefix ++ [4], fours-1, ops)])
|> Stream.concat()
end
def eval(expr), do: eval(expr, [])
def eval([:add | rest], [y, x | stack_rest]) do
eval(rest, [1.0*(x + y) | stack_rest])
end
def eval([:sub | rest], [y, x | stack_rest]) do
eval(rest, [1.0*(x - y) | stack_rest])
end
def eval([:mul | rest], [y, x | stack_rest]) do
eval(rest, [1.0*(x * y) | stack_rest])
end
def eval([:div | rest], [y, x | stack_rest]) when y != 0 do
eval(rest, [x / y | stack_rest])
end
def eval([val | rest], stack) when is_integer(val) do
eval(rest, [val | stack])
end
def eval([], [result]) do
result
end
def eval(_, _) do
:crash
end
def possible_value_map(exprs) do
exprs
|> Stream.map(&{&1, Fours.eval(&1)})
|> Enum.to_list()
|> Enum.group_by(&elem(&1, 1), &elem(&1, 0))
end
end
Fours.seqs([4, 4], 2, 3) |> Fours.possible_value_map()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment