39 lines
1.1 KiB
Text
39 lines
1.1 KiB
Text
defmodule AKS do
|
|
def iterate(f, x), do: fn -> [x | iterate(f, f.(x))] end
|
|
|
|
def take(0, _lazy), do: []
|
|
def take(n, lazy) do
|
|
[value | next] = lazy.()
|
|
[value | take(n-1, next)]
|
|
end
|
|
|
|
def pascal, do: iterate(fn row -> [1 | sum_adj(row)] end, [1])
|
|
|
|
defp sum_adj([_] = l), do: l
|
|
defp sum_adj([a, b | _] = row), do: [a+b | sum_adj(tl(row))]
|
|
|
|
def show_binomial(row) do
|
|
degree = length(row) - 1
|
|
["(x - 1)^", to_char_list(degree), " =", binomial_rhs(row, 1, degree)]
|
|
end
|
|
|
|
defp show_x(0), do: ""
|
|
defp show_x(1), do: "x"
|
|
defp show_x(n), do: [?x, ?^ | to_char_list(n)]
|
|
|
|
defp binomial_rhs([], _, _), do: []
|
|
defp binomial_rhs([coef | coefs], sgn, exp) do
|
|
signchar = if sgn > 0, do: ?+, else: ?-
|
|
[0x20, signchar, 0x20, to_char_list(coef), show_x(exp) | binomial_rhs(coefs, -sgn, exp-1)]
|
|
end
|
|
|
|
def primerow(row, n), do: Enum.all?(row, fn coef -> (coef == 1) or (rem(coef, n) == 0) end)
|
|
|
|
def main do
|
|
for row <- take(8, pascal), do: IO.puts show_binomial(row)
|
|
IO.write "\nThe primes upto 50: "
|
|
IO.inspect for {row, n} <- Enum.zip(tl(tl(take(51, pascal))), 2..50), primerow(row, n), do: n
|
|
end
|
|
end
|
|
|
|
AKS.main
|