97 lines
2.4 KiB
Haskell
97 lines
2.4 KiB
Haskell
import System.IO
|
|
|
|
import Data.Set (Set)
|
|
import qualified Data.Set as Set
|
|
|
|
import Data.Char (ord,chr)
|
|
|
|
|
|
|
|
|
|
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
|
|
|