From 90a259febe10fb97b4d2df8aaf1d61a58d733411 Mon Sep 17 00:00:00 2001 From: Mistivia Date: Fri, 2 May 2025 19:35:09 +0800 Subject: make a spiral --- 3-kyu/make-a-spiral.hs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 3-kyu/make-a-spiral.hs diff --git a/3-kyu/make-a-spiral.hs b/3-kyu/make-a-spiral.hs new file mode 100644 index 0000000..c0e5ec0 --- /dev/null +++ b/3-kyu/make-a-spiral.hs @@ -0,0 +1,53 @@ +-- https://www.codewars.com/kata/534e01fbbb17187c7e0000c6 +module Spiral where + +setRow :: Int -> (Int, Int) -> [[Int]] -> [[Int]] +setRow r (from, to) mat = take r mat ++ [set oldRow] ++ drop (r+1) mat + where + oldRow = head $ drop r mat + set row = take from row ++ take (to - from + 1) (repeat 1) ++ drop (to+1) row + +setCol :: Int -> (Int, Int) -> [[Int]] -> [[Int]] +setCol c (from, to) mat = + take from mat + ++ map (setNth c) (drop from $ take (to+1) mat) + ++ drop (to+1) mat + where + setNth n row = take n row ++ [1] ++ drop (n+1) row + +emptySquare :: Int -> [[Int]] +emptySquare n = take n $ repeat $ take n $ repeat 0 + +data Direction = DRight | DLeft | DDown | DUp + +spiralize :: Int -> [[Int]] +spiralize n = go (emptySquare n) (0,0) [n-1,n-1,0] n DRight + where + go mat (x,y) limit prevDelta DRight = + if x >= head limit || prevDelta < 2 then mat + else go (setRow y (x,head limit) mat) + (head limit, y) + (tail limit ++ [y+2]) + (head limit - x) + DDown + go mat (x,y) limit prevDelta DDown = + if y >= head limit || prevDelta < 2 then mat + else go (setCol x (y, head limit) mat) + (x, head limit) + (tail limit ++ [x-2]) + (head limit - y) + DLeft + go mat (x,y) limit prevDelta DLeft = + if x <= head limit || prevDelta < 2 then mat + else go (setRow y (head limit, x) mat) + (head limit, y) + (tail limit ++ [y-2]) + (x - head limit) + DUp + go mat (x,y) limit prevDelta DUp = + if y <= head limit || prevDelta < 2 then mat + else go (setCol x (head limit, y) mat) + (x, head limit) + (tail limit ++ [x+2]) + (y - head limit) + DRight -- cgit v1.0