ARCHIVE

O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|O|

View on GitHub
import Data.List 
import System.IO


-- PS C:\Users\night> chcp 65001
-- Active code page: 65001
-- PS C:\Users\night> ghci
-- GHCi, version 9.4.8: https://www.haskell.org/ghc/  :? for help
-- ghci> :!chcp 65001
-- Active code page: 65001
-- ghci> :l Downloads/signpost.hs
-- [1 of 2] Compiling Main             ( Downloads\signpost.hs, interpreted )
-- Ok, one module loaded.
-- ghci> signposts 4 62348632874 1
--     |    |    |
--  1→ |  ↘ |  → |  ↓
-- ____|____|____|____
--     |    |    |
--   → |  ↓ |  ↙ |  ↙
-- ____|____|____|____
--     |    |    |
--   ↗ |  ← |  ↓ |  ←
-- ____|____|____|____
--     |    |    |
--   ↑ |  ↑ |  → | 16
-- ____|____|____|____

(%) = mod
(//) = div

rng :: Int -> Int -> [Int] 
rng _ 0 = [] 
rng o i = let n = r o in n : rng n (i-1)
  where r o = (1664525*o+1013904223) % (2 ^ 32)

permute :: Int -> [a] -> [a]
permute seed ns = let bs = rng seed (length ns) in p' bs ns []
  where p' [] _ cs = cs 
        p' (r:rs) bs cs = 
          let (ds, e:es) = splitAt (fromIntegral (r%(length bs))) bs
          in p' rs (ds++es) (e:cs) 


queenTour :: Int -> Int -> [Int]
queenTour n r = do 
  let ps = 1 : (permute r [2..n*n-1]) ++ [n*n]
  if valid n ps then inv ps else queenTour n (r+1)

sign :: Int -> [Int] -> Int -> IO ()
sign _ [] _ = return ()
sign n ns i | n==i = return () 
sign n ns i = do 
  putStrLn "    |    |    |"
  hSetEncoding stdout utf8
  hSetEncoding stdin utf8
  hSetEncoding stderr utf8
  putStrLn $ drop 2 $ prep (map (vector n ns) (take n (drop (n*i) ns)))
  if length ns == n then putStrLn "" else putStrLn "____|____|____|____"
  sign n ns (i+1)

signposts :: Int -> Int -> Int -> IO () 
signposts _ _ 0 = return ()
signposts n r i = do 
  sign n (queenTour n r) 0
  putStrLn ""
  putStrLn ""
  signposts n ((r//7)*8) (i-1)

valid :: Int -> [Int] -> Bool
valid n (x:y:zs) = (elem (y-1) (connections n (x-1))) && valid n (y:zs)
valid n _ = True

-- ↖ 	↗ 	↘ 	↙   ← 	↑ 	→ 	↓ ↖ ↗ ↘ ↙

vector :: Int -> [Int] -> Int -> String
vector n g 1 = case idx 2 g 0 of 
  x|x<n -> "1→"
  x|(x%n)==0 -> "1↓"
  _ -> "1↘"
vector n _ c | n*n == c = show $ n*n
vector n g c = let (i,j) = ((idx c g 0), (idx (c+1) g 0)) in
  if i>j && (i%n) == (j%n)            then "↑" else
  if i<j && (i%n) == (j%n)            then "↓" else
  if i<j && (i//n) == (j//n)          then "→" else
  if i>j && (i//n) == (j//n)          then "←" else
  if (i//n) < (j//n) && (i%n) < (j%n) then "↘" else
  if (i//n) < (j//n) && (i%n) > (j%n) then "↙" else
  if (i//n) > (j//n) && (i%n) < (j%n) then "↗" else
  if (i//n) > (j//n) && (i%n) > (j%n) then "↖" else " "

connections :: Int -> Int -> [Int]
connections n c = 
  let (d,m) = divMod c n in
  sort $ filter (/=c) $
  [m + i*n     | i <- [0..n-1]]                            ++ -- V
  [i + d*n     | i <- [0..n-1]]                            ++ -- H
  [c - i*(n+1) | i <- [1..min m (c//(n+1))]]               ++ -- UL
  [c + i*(n+1) | i <- [1..min (n-m-1) ((n*n - c)//(n+1))]] ++ -- DR
  [c + i*(n-1) | i <- [1..min (n-d-1) m]]                  ++ -- DL
  [c - i*(n-1) | i <- [1..min (n-m-1) d]]                     -- UR
  
  
prep :: [String] -> String
prep [] = ""
prep (x:xs) | (length x) > 1 = " | "  ++ x ++ prep xs
prep (x:xs) = " |  "  ++ x ++ prep xs

inv :: [Int] -> [Int]
inv xs = [idx x xs 1 | x <- [1..16]]

idx :: Eq a => a -> [a] -> Int -> Int
idx x (y:ys) i = if x==y then i else idx x ys (i+1)
idx _ [] _ = -1