44 lines
1.3 KiB
Text
44 lines
1.3 KiB
Text
defmodule KaprekarNumber do
|
|
def check(n), do: check(n, 10)
|
|
|
|
def check(1,_base), do: {"1", ""}
|
|
def check(n, base) when rem(n*(n-1), (base-1)) != 0, do: false # casting out nine
|
|
def check(n, base) do
|
|
square = Integer.to_string(n*n, base)
|
|
check(n, base, square, 1, String.length(square)-1)
|
|
end
|
|
|
|
defp check(_, _, _, _, 0), do: false
|
|
defp check(n, base, square, i, remainder) do
|
|
{a, b} = String.split_at(square, i)
|
|
if String.to_integer(b, base) == 0 do
|
|
false
|
|
else
|
|
sum = String.to_integer(a, base) + String.to_integer(b, base)
|
|
if n == sum, do: {a, b}, else: check(n, base, square, i+1, remainder-1)
|
|
end
|
|
end
|
|
end
|
|
|
|
Enum.each(1..9_999, fn n ->
|
|
if result = KaprekarNumber.check(n) do
|
|
{a, b} = result
|
|
:io.fwrite "~6w ~8s ~s + ~s~n", [n, a<>b, a, b]
|
|
end
|
|
end)
|
|
|
|
# Extra credit
|
|
count = Enum.reduce(1..999_999, 0, fn n,acc ->
|
|
if KaprekarNumber.check(n), do: acc + 1, else: acc
|
|
end)
|
|
IO.puts "\n#{count} kaprekar numbers under 1,000,000"
|
|
|
|
# Extra extra credit
|
|
base = 17
|
|
IO.puts "\nbase #{base} kaprekar numbers under 1,000,000(base10)"
|
|
Enum.each(1..999_999, fn n ->
|
|
if result = KaprekarNumber.check(n, base) do
|
|
{a, b} = result
|
|
:io.fwrite "~7w ~5s ~9s ~s + ~s~n", [n, Integer.to_string(n,base), a<>b, a, b]
|
|
end
|
|
end)
|