Luubstar

Dia14 -- AoC 2023

Dec 14th, 2023
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.22 KB | None | 0 0
  1. module Dia14 where
  2.  
  3. -- ##############################################
  4. -- ## Imports ##
  5. -- ##############################################
  6.  
  7. import Data.List (sortOn,transpose, elemIndex)
  8. import Debug.Trace (trace)
  9.  
  10. -- ##############################################
  11. -- ## Definiciones de datos, tipos y clases ##
  12. -- ##############################################
  13.  
  14. type Coordenada = (Int,Int)
  15. type RocaCuadrada = Coordenada
  16. type RocaCircular = Coordenada
  17.  
  18. -- ##############################################
  19. -- ## Función main ##
  20. -- ##############################################
  21.  
  22. main = do
  23. contents <- (readFile "Input14.txt")
  24. let lin = lines contents
  25.  
  26. putStrLn $ show $ part1 lin
  27. putStrLn "--------"
  28. putStrLn $ show $ part2 lin 0 []
  29.  
  30. -- ##############################################
  31. -- ## Funciones de la 1º parte ##
  32. -- ##############################################
  33.  
  34. part1 :: [String] -> Int
  35. part1 lin =
  36. let rocas = transpose $ map (findRock 0) (transpose $ lin)
  37. in countRock (length rocas) rocas
  38.  
  39. findRock :: Int -> String -> String
  40. findRock x l
  41. | x >= length l = l
  42. | l!!x == '#' || l!!x == '.' = findRock (x+1) l
  43. | otherwise = findRock (x+1) (moveRock l (x-1) x)
  44.  
  45. moveRock :: String -> Int -> Int -> String
  46. moveRock l x fx
  47. | x < 0 = take 0 l ++ ['O'] ++ [if i == fx then '.' else j | (i,j) <- zip [1..] (drop (1) l)]
  48. | l!!x == '#' || l!!x == 'O' = take (x+1) l ++ ['O'] ++ [if i == fx then '.' else j | (i,j) <- zip [x+2..] (drop (x+2) l)]
  49. | otherwise = moveRock l (x-1) fx
  50.  
  51. -- ##############################################
  52. -- ## Funciones de la 2º parte ##
  53. -- ##############################################
  54.  
  55. part2 :: [String] -> Int -> [[String]] -> Int
  56. part2 l x lista
  57. | (length lista) > 0 && elem l (init lista) =
  58. let indexciclo = getIndex l (init lista)
  59. listam = drop (indexciclo) (init lista)
  60. in countRock (length l) (listam!!((mod (1000000000 - indexciclo - 1) (length $ listam))))
  61. | x >= 1000000000 = countRock (length l) l
  62. | otherwise =
  63. let l1 = findRockN l
  64. l2 = findRockW l1
  65. l3 = findRockS l2
  66. l4 = findRockE l3
  67. in part2 (l4) (x+1) (lista++[l4])
  68.  
  69. findRockN :: [String] -> [String]
  70. findRockN l = transpose $ map (findRock 0) (transpose $ l)
  71.  
  72. findRockE :: [String] -> [String]
  73. findRockE l = map reverse $ map (findRock 0) (map reverse $ l)
  74.  
  75. findRockS :: [String] -> [String]
  76. findRockS l = transpose $ map reverse $ map (findRock 0) (map reverse $ transpose $ l)
  77.  
  78. findRockW :: [String] -> [String]
  79. findRockW l = map (findRock 0) l
  80.  
  81. -- ##############################################
  82. -- ## Funciones generales ##
  83. -- ##############################################
  84.  
  85. countRock :: Int -> [String] -> Int
  86. countRock y ((x:xs):ys)
  87. | x == 'O' = y + countRock y ((xs):ys)
  88. | otherwise = countRock y ((xs):ys)
  89. countRock y ([]:ys) = countRock (y-1) ys
  90. countRock _ [] = 0
  91.  
  92. getIndex :: [String] -> [[String]] -> Int
  93. getIndex l s =
  94. case elemIndex l s of
  95. Just t -> t
  96. _ -> -1
Advertisement
Add Comment
Please, Sign In to add comment