Advertisement
Guest User

Untitled

a guest
Dec 23rd, 2022
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Data.List
  2. import Data.Map (Map, (!))
  3. import Data.Set (Set)
  4. import qualified Data.Set as S
  5. import qualified Data.Map as M
  6.  
  7. type Elf = (Int,Int)
  8. type Elves = Set Elf
  9. type Proposal = Maybe (Int,Int)
  10. type Proposals = Map Elf Proposal
  11. type PMech = Elves -> Elf -> Proposal
  12.  
  13. readData :: IO Elves
  14. readData = do
  15.     xs <- lines <$> readFile "puzzle.txt"
  16.     let ys = zipWith (\n x -> zipWith (\m y -> (y,(m,-n))) [0..] x) [0..] xs
  17.     return $ S.fromList [c | (x,c) <- concat ys, x == '#']
  18.  
  19. pMechPart :: Int -> PMech
  20. pMechPart n es (x,y) = if any (flip S.member es) checkList then Nothing else Just (checkList !! 1)
  21.     where checkList = case n of 0 -> [(x-1,y+1),(x,y+1),(x+1,y+1)]
  22.                                 1 -> [(x-1,y-1),(x,y-1),(x+1,y-1)]
  23.                                 2 -> [(x-1,y+1),(x-1,y),(x-1,y-1)]
  24.                                 3 -> [(x+1,y+1),(x+1,y),(x+1,y-1)]
  25.  
  26. pSched :: Int -> PMech
  27. pSched n es e = resolve $ mapMaybe (\m -> pMechPart m es e) $ take 4 $ drop n [0,1,2,3,0,1,2,3]
  28.     where resolve xs = if length xs `elem` [0,4] then Nothing else Just $ head xs
  29.  
  30. proposals :: PMech -> Elves -> Proposals
  31. proposals pmech es = M.fromList [(e,pmech es e) | e <- S.toList es]
  32.  
  33. countVals :: (Ord a) => Map k a -> Map a Int
  34. countVals m = let vals = M.elems m in M.fromList [(v,length $ filter (==v) vals) | v <- vals]
  35.  
  36. update :: PMech -> Elves -> Elves
  37. update pm es = S.map updateElf es
  38.     where props = proposals pm es
  39.           propCounts = countVals props
  40.           updateElf e = case props ! e of Nothing -> e
  41.                                           Just e' -> if propCounts ! (Just e') > 1 then e else e'
  42.                                          
  43. stabElves :: Elves -> (Elves,Int)
  44. stabElves es = let xs = scanl' (\e n -> update (pSched n) e) es (cycle [0..3])
  45.                in head [(y,n) | ((y,y'),n) <- zip (zip xs (tail xs)) [0..], y == y']
  46.                
  47. main = do
  48.     es <- readData rf
  49.     let (_,n) = stabElves es
  50.     print (n+1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement