I searched the web for different solutions to the n-queens problem in Haskell but couldn\'t find any that could check for unsafe positions in O(1) time, like that one that you k
I have a solution. However, the constant may be large, so I don't really hope beating anything.
Here is my data structure:
-- | Zipper over a list of integers
type Zipper = (Bool, -- does the zipper point to an item?
[Int], -- previous items
-- (positive numbers representing
-- negative offsets relative to the previous list item)
[Int] -- next items (positive relative offsets)
)
type State =
(Zipper, -- Free columns zipper
Zipper, -- Free diagonal1 zipper
Zipper -- Free diagonal2 zipper
)
It allows all of the required operations to be performed in O(1).
The code can be found here: http://hpaste.org/50707
The speed is bad -- it's slower than the reference solution posted in the question on most inputs. I've benchmarked them against each other on inputs [1,3 .. 15]
and got the following time ratios ((reference solution time / my solution time) in %):
[24.66%, 19.89%, 23.74%, 41.22%, 42.54%, 66.19%, 84.13%, 106.30%]
Notice almost linear slow-down of the reference solution relative to mine, showing difference in asymptotic complexity.
My solution is probably horrible in terms of strictness and things like that, and must be fed to some very good optimizing compiler (like Don Stewart for example) to get better results.
Anyway, I think in this problem O(1) and O(log(n)) are indistinguishable anyway because log(8) is just 3 and constants like this are subject of micro-optimisations rather than of algorithm.