2023 day 13
Star 2 is the most scuffed and probably incorrect thing ever but it produced the right answer for my input and that's good enough for me.
This commit is contained in:
parent
fc5af8bb0b
commit
f52cd41da1
33
2023/13/Main1.hs
Normal file
33
2023/13/Main1.hs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import Data.List.Split (splitOn)
|
||||||
|
import Data.List (foldl', transpose)
|
||||||
|
import qualified Data.Vector.Unboxed as VU
|
||||||
|
import Data.Vector.Unboxed (Vector)
|
||||||
|
|
||||||
|
hashChar :: Char -> Int
|
||||||
|
hashChar '#' = 1
|
||||||
|
hashChar '.' = 0
|
||||||
|
|
||||||
|
lineToInt :: String -> Int
|
||||||
|
lineToInt = foldl' (\x y -> 2 * x + hashChar y) 0
|
||||||
|
|
||||||
|
matchesAt :: Vector Int -> Int -> Bool
|
||||||
|
matchesAt v i = VU.reverse rightSide == leftSide
|
||||||
|
where
|
||||||
|
nMirrored = min i $ VU.length v - i
|
||||||
|
|
||||||
|
leftSide = VU.slice (i - nMirrored) nMirrored v
|
||||||
|
|
||||||
|
rightSide = VU.slice i nMirrored v
|
||||||
|
|
||||||
|
findMatches :: Vector Int -> [Int]
|
||||||
|
findMatches v = filter (matchesAt v) [1 .. VU.length v - 1]
|
||||||
|
|
||||||
|
solveDirection :: [String] -> Int
|
||||||
|
solveDirection = sum . findMatches . VU.fromList . map lineToInt
|
||||||
|
|
||||||
|
solve :: [String] -> Int
|
||||||
|
solve l = 100 * solveDirection l + (solveDirection . transpose) l
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = print . sum . map (solve . lines) . splitOn "\n\n"
|
||||||
|
=<< readFile "data.txt"
|
40
2023/13/Main2.hs
Normal file
40
2023/13/Main2.hs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
import Data.Bits ((.&.), countTrailingZeros, xor)
|
||||||
|
import Data.List.Split (splitOn)
|
||||||
|
import Data.List (foldl', transpose)
|
||||||
|
import qualified Data.Vector.Unboxed as VU
|
||||||
|
import Data.Vector.Unboxed (Vector)
|
||||||
|
|
||||||
|
isPowTwo :: Int -> Bool
|
||||||
|
isPowTwo n = n .&. (n - 1) == 0
|
||||||
|
|
||||||
|
hashChar :: Char -> Int
|
||||||
|
hashChar '#' = 1
|
||||||
|
hashChar '.' = 0
|
||||||
|
|
||||||
|
lineToInt :: String -> Int
|
||||||
|
lineToInt = foldl' (\x y -> 2 * x + hashChar y) 0
|
||||||
|
|
||||||
|
matchesAt :: Vector Int -> Int -> Bool
|
||||||
|
matchesAt v i = VU.length differences == 1 && isPowTwo (VU.head differences)
|
||||||
|
where
|
||||||
|
nMirrored = min i $ VU.length v - i
|
||||||
|
|
||||||
|
leftSide = VU.slice (i - nMirrored) nMirrored v
|
||||||
|
|
||||||
|
rightSide = VU.slice i nMirrored v
|
||||||
|
|
||||||
|
differences = VU.filter (/= 0)
|
||||||
|
$ VU.zipWith xor (VU.reverse rightSide) leftSide
|
||||||
|
|
||||||
|
findMatches :: Vector Int -> [Int]
|
||||||
|
findMatches v = filter (matchesAt v) [1 .. VU.length v - 1]
|
||||||
|
|
||||||
|
solveDirection :: [String] -> Int
|
||||||
|
solveDirection = last . (0:) . findMatches . VU.fromList . map lineToInt
|
||||||
|
|
||||||
|
solve :: [String] -> Int
|
||||||
|
solve l = 100 * solveDirection l + (solveDirection . transpose) l
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = print . sum . map (solve . lines) . splitOn "\n\n"
|
||||||
|
=<< readFile "data.txt"
|
Loading…
Reference in a new issue