This commit is contained in:
Oskar Winkels 2022-12-11 01:20:24 +01:00
parent 44cbadb388
commit 115d8a60eb
Signed by: o.winkels
GPG Key ID: E7484A06E99DAEF1
2 changed files with 97 additions and 1 deletions

View File

@ -1,4 +1,4 @@
DAY = 8 DAY = 9
DIR = day$(DAY) DIR = day$(DAY)

96
day9/main.hs Normal file
View File

@ -0,0 +1,96 @@
import System.IO
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Char (ord,chr)
import Debug.Trace
type Pos = (Int,Int)
ppinsert :: Char -> [Pos] -> ([String],Int,Int) -> [String]
ppinsert _ [] (b,_,_) = b
ppinsert id ((x,y):xs) d@(b,minx,miny) = nbrd
where
nextid
| id == '#' = '#'
| id == 'H' = '1'
| otherwise = chr $ (ord id)+1
(brows,(orow:arows)) = splitAt (y-miny) $ ppinsert nextid xs d
(bchars,(_:achars)) = splitAt (x-minx) orow
nrow = bchars ++ [id] ++ achars
nbrd = brows ++ [nrow] ++ arows
ppp :: Char -> [Pos] -> String
ppp h l = concat $ reverse $ ppinsert h l (start,minx,miny)
where
(x,y) = unzip l
minx = min (-10) (minimum x)
miny = min (-5) (minimum y)
maxx = max 10 (maximum x)
maxy = max 5 (maximum y)
srow = replicate (-minx) '.' ++ "s" ++ replicate maxx '.' ++ "\n"
brow = replicate (-minx) '.' ++ "." ++ replicate maxx '.' ++ "\n"
start = replicate (-miny) brow ++ [srow] ++ replicate maxy brow
parseMove :: String -> [Pos]
parseMove s = replicate n dv
where
d = head s
n = read (drop 2 s) :: Int
dv = case d of 'U' -> (0,1)
'R' -> (1,0)
'D' -> (0,-1)
'L' -> (-1,0)
parseMoves :: String -> [Pos]
parseMoves = concat . map parseMove . lines
dragTail :: [Pos] -> [Pos]
dragTail [t] = [t]
dragTail l@( h@(hx,hy) : (nx,ny) : xs)
| dx > 1 = (h : dragTail ((nx+1 ,ny+dyu) : xs))
| dy > 1 = (h : dragTail ((nx+dxu,ny+1 ) : xs))
| dx < -1 = (h : dragTail ((nx-1 ,ny+dyu) : xs))
| dy < -1 = (h : dragTail ((nx+dxu,ny-1 ) : xs))
| otherwise = l
where
(dx,dy) = (hx-nx,hy-ny)
(dxu,dyu) = (signum dx,signum dy)
sim :: (Set Pos,[Pos]) -> Pos -> (Set Pos,[Pos])
sim (s,((hx,hy):t)) (dx,dy) = (ns,nl) -- trace (ppp 'H' nl)
where
nh = (hx+dx,hy+dy)
nl = dragTail (nh:t)
ns = Set.insert (last nl) s
handler :: String -> String
handler s = (show $ Set.size trail2) ++ "\n" ++
(show $ Set.size trail10) ++ "\n"
where
moves = parseMoves s
start2 = (Set.empty,[(0,0),(0,0)])
start10 = (Set.empty,replicate 10 (0,0))
(trail2,_) = foldl sim start2 $ moves
(trail10,_) = foldl sim start10 $ moves
main :: IO ()
main = do
interact handler