Skip to content

Instantly share code, notes, and snippets.

@rugyoga
Last active November 18, 2019 22:13
Show Gist options
  • Save rugyoga/d0d54e353b7a3209098ec414295c2ded to your computer and use it in GitHub Desktop.
Save rugyoga/d0d54e353b7a3209098ec414295c2ded to your computer and use it in GitHub Desktop.
n queens solutions based on Elixir Streams
import Enum, only: [all?: 2, at: 2, map: 2, join: 2, reverse: 1, zip: 2]
import Stream, only: [filter: 2, flat_map: 2, with_index: 2]
import String, only: [duplicate: 2, split_at: 2, to_integer: 1]
defmodule NQueens do
def safe?(queens, p) do
props = fn {f, r} -> [f, f+r, f-r] end
props_p = props.(p)
all?(queens, fn q -> all?(zip(props_p, props.(q)), fn {p, q} -> p != q end) end)
end
def solve(n, queens, r) when r == n, do: [{reverse(queens)}]
def solve(n, queens, r) do
0..(n-1)
|> filter(&(safe?(queens, {&1, r})))
|> flat_map(&(solve(n, [{&1, r} | queens], r+1)))
end
def to_s({{queens}, i}, dots) do
one_rank = fn {f, _} -> {a, b} = split_at(dots, f); "#{a}Q#{b}" end
"#{i}:\n#{queens |> map(one_rank) |> join("\n")}\n"
end
def print(solutions, n) do
dots = duplicate(".", n-1)
solutions |> with_index(1) |> Enum.each(&(&1 |> to_s(dots) |> IO.puts()))
end
end
n = System.argv() |> at(0) |> to_integer
n |> NQueens.solve([], 0) |> NQueens.print(n)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment