day9
This commit is contained in:
		
							
								
								
									
										96
									
								
								day9/main.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								day9/main.hs
									
									
									
									
									
										Normal 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
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user