Last active
June 16, 2017 12:00
-
-
Save brweber2/227c41f6aa7daf7a35e1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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