4-rings or 4-squares puzzle: Difference between revisions

m (→‎{{header|Phix}}: added syntax colouring the hard way)
Line 2,749:
Probably less readable, but already fast, and could be further optimised.
<lang haskell>import Data.List (delete, sortBy, (\\))
 
import Control.Monad (when)
--------------- 4 RINGS OR 4 SQUARES PUZZLE --------------
import Data.Bool (bool)
 
type Rings = [(Int, Int, Int, Int, Int, Int, Int)]
Line 2,756:
rings :: Bool -> [Int] -> Rings
rings u digits =
((>>=) <*> (queen u =<< head))
let ds = sortBy (flip compare) digits
in ds >>= queen u(sortBy (headflip dscompare) dsdigits)
 
queen :: Bool -> Int -> [Int] -> Int -> Rings
queen u h ds q = xs >>= leftBishop u q h ts ds
where
let ts = filter ((<= h) . (q +)) ds
in bool ds (delete q ts) u= >>filter ((<= leftBishoph) u. (q h ts+)) ds
xs
| u = delete q ts
| (lRookotherwise <= h)ds
 
leftBishop u q h ts ds lb =::
leftBishop :: Bool -> Int -> Int -> [Int] -> [Int] -> Int -> Rings
Bool ->
leftBishop u q h ts ds lb =
Int ->
let lRook = lb + q
inInt bool->
[Int] ->
[Int] ->
(bool ds (ts \\ [q, lb, lRook]) u >>= rightBishop u q h lb ds lRook)
Int ->
(lRook <= h)
Rings
leftBishop u q h ts ds lb
| lRook <= h = (bool ds (ts \\ [q, lb, lRook]) uxs >>= rightBishop u q h lb ds lRook)
| otherwise = []
where
let lRook = lb + q
xs
| (let ksu = bool ds (dsts \\ [q, lb, rb, rRook, lRook]) u
| otherwise = ds
 
rightBishop ::
rightBishop :: Bool -> Int -> Int -> Int -> [Int] -> Int -> Int -> Rings
Bool ->
rightBishop u q h lb ds lRook rb =
Int ->
let rRook = q + rb
inInt bool->
Int []->
[Int] ->
(let ks = bool ds (ds \\ [q, lb, rb, rRook, lRook]) u
Int ->
in ks >>= knights u (lRook - rRook) lRook lb q rb rRook ks)
Int ->
((rRook <= h) && (not u || (rRook /= lb)))
Rings
rightBishop u q h lb ds lRook rb =
| ((rRook <= h) && (not u || (rRook /= lb))) =
let ks
| u = (ds \\ [q, lb, rb, rRook, lRook])
| otherwise = ds
in ks
>>= knights
u
(lRook - rRook)
lRook
lb
q
rb
rRook
ks
| otherwise = []
where
let rRook = q + rb
 
knights ::
knights :: Bool -> Int -> Int -> Int -> Int -> Int -> Int -> [Int] -> Int -> Rings
Bool ->
Int ->
Int ->
Int ->
Int ->
Int ->
Int ->
[Int] ->
Int ->
Rings
knights u rookDelta lRook lb q rb rRook ks k =
in [ (lRook, k, lb, q, rb, k2, rRook)
let k2 = k + rookDelta
| (k2 `elem` ks)
in [ (lRook, k, lb, q, rb, k2, rRook)
| (k2 `elem` ks) && ( not u || notElem k2 [lRook, k, lb, q, rb, rRook]) ]
|| notElem
 
k2
in ks >>= knights u (lRook - rRook) [lRook, k, lb, q, rb, rRook ks)]
)
]
where
let k2 = k + rookDelta
 
-- TEST -------------------------- TEST -------------------------
main :: IO ()
main = do
Line 2,795 ⟶ 2,842:
mapM_
f
[ ("rings True [1 .. 7]", rings True [1 .. 7]),
, ("rings True [3 .. 9]", rings True [3 .. 9])
]
f
f ("length (rings False [0 .. 9])", [length (rings False [0 .. 9])])</lang>
( "length (rings False [0 .. 9])",
f ("length (rings False [0 .. 9])", [length (rings False [0 .. 9])])</lang>
)</lang>
{{Out}}
<pre>rings True [1 .. 7]
9,655

edits