Skip to content

Instantly share code, notes, and snippets.

@brweber2
Last active June 16, 2017 12:00
Show Gist options
  • Save brweber2/227c41f6aa7daf7a35e1 to your computer and use it in GitHub Desktop.
Save brweber2/227c41f6aa7daf7a35e1 to your computer and use it in GitHub Desktop.
defmodule Permutations do
@moduledoc """
An answer to the problem from: http://www.theguardian.com/science/alexs-adventures-in-numberland/2015/may/20/can-you-do-the-maths-puzzle-for-vietnamese-eight-year-olds-that-has-stumped-parents-and-teachers
iex> Permutations.main parallel: false
iex> Permutations.main parallel: true
"""
def main(parallel: parallel?) do
permutations
|> find_answer(66, parallel?)
|> :timer.tc
|> show_results
end
def main(_args) do
IO.puts "Usage: You must provide an argument in the form of [parallel: true] or [parallel: false]"
end
def show_results({time,answers}) do
IO.puts "It took " <> IO.ANSI.green() <> "#{time} MICROSECONDS" <> IO.ANSI.reset() <>
" to find " <> IO.ANSI.cyan() <> "#{Enum.count(answers)} answers." <> IO.ANSI.reset() <>
" They are:"
answers
end
def permutations do
1..9
|> Enum.into([])
|> Permute.perms
end
def find_answer(perms, answer, true) do
fn ->
IO.puts "running multiple processes"
perms
|> Enum.map(&pcalc/1)
|> Enum.map(&pwait/1)
|> Enum.filter_map(fn t -> t |> elem(1) == answer end, &(&1 |> elem(0)))
end
end
def find_answer(perms, answer, false) do
fn ->
perms
|> Enum.map(&calc/1)
|> Enum.filter_map(fn t -> t |> elem(1) == answer end, &(&1 |> elem(0)))
end
end
def pcalc(items) do
Task.async(fn -> calc(items) end)
end
def pwait(task) do
Task.await(task)
end
def calc(numbers = [a,b,c,d,e,f,g,h,i]) do
# a + 13 * b / c + d + 12 * e - f - 11 + g * h / i - 10 == 66
# but not quite... order of precedence gets us!
answer = a
|> Kernel.+(13)
|> Kernel.*(b)
|> Kernel./(c)
|> Kernel.+(d)
|> Kernel.+(12)
|> Kernel.*(e)
|> Kernel.-(f)
|> Kernel.-(11)
|> Kernel.+(g)
|> Kernel.*(h)
|> Kernel./(i)
|> Kernel.-(10)
{numbers,answer}
end
@doc """
Creates a list of all permutations of elements in the list passed in.
This produces a list containing n! lists where n is the length of the list passed in.
This implementation is not meant to be understood by inexperienced programmers.
"""
def perms([]), do: [[]]
def perms(list) do
for h <- list, t <- perms(list--[h]) do [h|t] end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment