diff --git a/2024/24-Crossed_Wires/example b/2024/24-Crossed_Wires/example new file mode 100644 index 0000000..8e277c1 --- /dev/null +++ b/2024/24-Crossed_Wires/example @@ -0,0 +1,10 @@ +x00: 1 +x01: 1 +x02: 1 +y00: 0 +y01: 1 +y02: 0 + +x00 AND y00 -> z00 +x01 XOR y01 -> z01 +x02 OR y02 -> z02 diff --git a/2024/24-Crossed_Wires/example2 b/2024/24-Crossed_Wires/example2 new file mode 100644 index 0000000..94b6eed --- /dev/null +++ b/2024/24-Crossed_Wires/example2 @@ -0,0 +1,47 @@ +x00: 1 +x01: 0 +x02: 1 +x03: 1 +x04: 0 +y00: 1 +y01: 1 +y02: 1 +y03: 1 +y04: 1 + +ntg XOR fgs -> mjb +y02 OR x01 -> tnw +kwq OR kpj -> z05 +x00 OR x03 -> fst +tgd XOR rvg -> z01 +vdt OR tnw -> bfw +bfw AND frj -> z10 +ffh OR nrd -> bqk +y00 AND y03 -> djm +y03 OR y00 -> psh +bqk OR frj -> z08 +tnw OR fst -> frj +gnj AND tgd -> z11 +bfw XOR mjb -> z00 +x03 OR x00 -> vdt +gnj AND wpb -> z02 +x04 AND y00 -> kjc +djm OR pbm -> qhw +nrd AND vdt -> hwm +kjc AND fst -> rvg +y04 OR y02 -> fgs +y01 AND x02 -> pbm +ntg OR kjc -> kwq +psh XOR fgs -> tgd +qhw XOR tgd -> z09 +pbm OR djm -> kpj +x03 XOR y03 -> ffh +x00 XOR y04 -> ntg +bfw OR bqk -> z06 +nrd XOR fgs -> wpb +frj XOR qhw -> z04 +bqk OR frj -> z07 +y03 OR x01 -> nrd +hwm AND bqk -> z03 +tgd XOR rvg -> z12 +tnw OR pbm -> gnj diff --git a/2024/24-Crossed_Wires/first.hs b/2024/24-Crossed_Wires/first.hs new file mode 100644 index 0000000..5e9cf5b --- /dev/null +++ b/2024/24-Crossed_Wires/first.hs @@ -0,0 +1,87 @@ +-- requires cabal install --lib megaparsec parser-combinators heap vector +module Main (main) where + +import Control.Monad (void, when) +import Data.Functor +import qualified Data.List as L +import qualified Data.Map as M +import Data.Maybe +import Data.Ord (comparing) +import Data.Void (Void) +import Text.Megaparsec +import Text.Megaparsec.Char + +import Debug.Trace + +exampleExpectedOutput = 4 +example2ExpectedOutput = 2024 + +type In = (String, Bool) +data Op = And | Or | Xor deriving (Show, Eq) +type Gate = (String, Op, String, String) +data Input = Input [In] [Gate] deriving Show + +type Parser = Parsec Void String + +parseIn :: Parser In +parseIn = (,) <$> some alphaNumChar <* string ": " + <*> (char '1' $> True <|> char '0' $> False) + +parseOp :: Parser Op +parseOp = string "AND" $> And + <|> string "OR" $> Or + <|> string "XOR" $> Xor + +parseGate :: Parser Gate +parseGate = (,,,) <$> some alphaNumChar <* space + <*> parseOp <* space + <*> some alphaNumChar <* string " -> " + <*> some alphaNumChar + +parseInput' :: Parser Input +parseInput' = Input <$> some (parseIn <* eol) <* eol + <*> some (parseGate <* eol) <* eof + +parseInput :: String -> IO Input +parseInput filename = do + input <- readFile filename + case runParser parseInput' filename input of + Left bundle -> error $ errorBundlePretty bundle + Right input' -> return input' + +exec And = ( && ) +exec Or = ( || ) +exec Xor = ( /= ) + +type Gates = M.Map String Bool + +compute :: Input -> Int +compute (Input ins gates) = sum [if b then 2^i else 0 | (b, i) <- zip outs [0..]] + where + outs = map (fullMap M.!) $ M.keys $ M.filterWithKey (\(z:_) _ -> z == 'z') gatesMap + startMap = M.fromList ins + gatesMap = M.fromList $ map (\(a, b, c, d) -> (d, (a, b, c))) gates + fullMap = M.foldlWithKey compute' startMap $ gatesMap + compute' :: Gates -> String -> (String, Op, String) -> Gates + compute' gates c (a, op, b) = case M.lookup c gates of + Just _ -> gates + Nothing -> let (va, gates') = case M.lookup a gates of + Just g -> (g, gates) + Nothing -> let gates' = compute' gates a $ gatesMap M.! a + in (gates' M.! a, gates') + (vb, gates'') = case M.lookup b gates' of + Just g -> (g, gates') + Nothing -> let gates'' = compute' gates b $ gatesMap M.! b + in (gates'' M.! b, gates'') + in M.insert c (exec op va vb) gates'' + +main :: IO () +main = do + example <- parseInput "example" + let exampleOutput = compute example + when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput) + example2 <- parseInput "example2" + let example2Output = compute example2 + when (example2Output /= example2ExpectedOutput) (error $ "example2 failed: got " ++ show example2Output ++ " instead of " ++ show example2ExpectedOutput) + input <- parseInput "input" + print $ compute input diff --git a/2024/24-Crossed_Wires/input b/2024/24-Crossed_Wires/input new file mode 100644 index 0000000..7e1537f --- /dev/null +++ b/2024/24-Crossed_Wires/input @@ -0,0 +1,313 @@ +x00: 1 +x01: 1 +x02: 0 +x03: 0 +x04: 0 +x05: 1 +x06: 0 +x07: 1 +x08: 1 +x09: 0 +x10: 1 +x11: 0 +x12: 0 +x13: 1 +x14: 0 +x15: 1 +x16: 0 +x17: 1 +x18: 0 +x19: 1 +x20: 0 +x21: 1 +x22: 0 +x23: 1 +x24: 0 +x25: 0 +x26: 1 +x27: 0 +x28: 1 +x29: 0 +x30: 1 +x31: 1 +x32: 0 +x33: 0 +x34: 1 +x35: 0 +x36: 1 +x37: 0 +x38: 1 +x39: 0 +x40: 0 +x41: 0 +x42: 0 +x43: 0 +x44: 1 +y00: 1 +y01: 0 +y02: 1 +y03: 1 +y04: 0 +y05: 0 +y06: 1 +y07: 1 +y08: 0 +y09: 1 +y10: 1 +y11: 1 +y12: 1 +y13: 1 +y14: 0 +y15: 1 +y16: 1 +y17: 0 +y18: 0 +y19: 0 +y20: 0 +y21: 0 +y22: 0 +y23: 0 +y24: 0 +y25: 1 +y26: 0 +y27: 0 +y28: 1 +y29: 1 +y30: 1 +y31: 0 +y32: 1 +y33: 0 +y34: 0 +y35: 0 +y36: 1 +y37: 0 +y38: 1 +y39: 0 +y40: 0 +y41: 0 +y42: 0 +y43: 0 +y44: 1 + +y33 AND x33 -> bfn +y32 XOR x32 -> rck +x30 AND y30 -> gns +y36 XOR x36 -> hbh +cng XOR mwt -> z42 +bsw OR bfp -> pwp +x00 XOR y00 -> z00 +y26 XOR x26 -> wkb +x31 AND y31 -> hjq +jhg AND gfd -> bbr +y43 XOR x43 -> fhk +mrg OR hjq -> ftq +jks OR cwn -> qvq +wrc XOR hbw -> z17 +skh XOR rkt -> z15 +x27 AND y27 -> kbf +jgg OR cmm -> qpm +y17 XOR x17 -> hbw +khf AND djt -> khs +qqw XOR gkc -> wpd +rms XOR sgf -> z31 +gww XOR jmf -> z24 +x01 XOR y01 -> kjs +pwp AND nnn -> dwg +tjq OR hhj -> cmb +x05 XOR y05 -> fds +x07 AND y07 -> jbw +y32 AND x32 -> wnt +x14 XOR y14 -> cgg +rhf AND cgg -> smd +djt XOR khf -> z35 +tcq OR rjb -> pfc +qtv OR khs -> rfq +y41 XOR x41 -> jhg +jbw OR trv -> tmg +y21 XOR x21 -> csw +jkm XOR dmp -> z13 +rkh OR cqg -> jkr +y20 XOR x20 -> bvw +pwb OR jdc -> smt +x13 AND y13 -> rbg +wvt XOR sbt -> z03 +jhg XOR gfd -> z41 +x01 AND y01 -> fqg +wfc XOR cmp -> mdd +cgg XOR rhf -> z14 +wkb XOR jkr -> z26 +y36 AND x36 -> jdc +x08 AND y08 -> gdd +fds AND whf -> vvs +y19 AND x19 -> z19 +x31 XOR y31 -> rms +nss AND jmv -> vtd +pwp XOR nnn -> z30 +x23 XOR y23 -> mcp +jvf XOR jth -> z04 +y38 AND x38 -> jhv +kjs AND hjp -> wkq +sqj AND wts -> qdn +y16 XOR x16 -> rvn +kbf OR mqr -> msf +y25 XOR x25 -> prp +y26 AND x26 -> tjq +cgv OR gmf -> mkf +y12 XOR x12 -> htn +kdd AND msf -> dpr +vtd OR bnw -> khf +smd OR ttv -> rkt +fnc OR mmk -> jmf +ppk OR hwb -> jbd +jbd AND nns -> nnq +mcp XOR mkf -> z23 +kbb AND wpb -> jmp +pbb OR mdd -> hvn +dts XOR wmq -> z33 +x42 AND y42 -> hnh +rck AND ftq -> hfc +rfq XOR hbh -> z36 +y05 AND x05 -> hpn +nns XOR jbd -> z40 +x14 AND y14 -> ttv +jmv XOR nss -> z34 +vth OR gdd -> wpb +y08 XOR x08 -> rjs +y42 XOR x42 -> cng +x35 AND y35 -> qtv +y02 XOR x02 -> rvm +mcp AND mkf -> mmk +y28 AND x28 -> rsv +wfm OR mts -> wfc +wnt OR hfc -> dts +sgf AND rms -> mrg +bbr OR ncf -> mwt +wpb XOR kbb -> z09 +x06 XOR y06 -> jtg +sbw OR bfn -> jmv +kmr XOR rmb -> z10 +rvn XOR kbq -> z16 +y09 XOR x09 -> kbb +gsk XOR fhk -> z43 +y23 AND x23 -> fnc +y29 XOR x29 -> hvc +wwp AND bvr -> cgv +tnc OR dbj -> hks +tvf XOR cmb -> z27 +bvw XOR hvn -> z20 +x44 XOR y44 -> jsg +rsv OR dpr -> tsk +sqj XOR wts -> z38 +x40 AND y40 -> bdn +qpc AND qmb -> trv +qvq XOR hns -> z18 +x41 AND y41 -> ncf +qdn OR jhv -> fkq +y27 XOR x27 -> tvf +rvm XOR vdq -> z02 +whf XOR fds -> z05 +tmg AND rjs -> vth +y34 AND x34 -> bnw +y21 AND x21 -> nrg +gsk AND fhk -> tnc +x38 XOR y38 -> sqj +y18 AND x18 -> wfm +hvc AND tsk -> bfp +jqf OR kjk -> kbq +dmp AND jkm -> qpw +x19 XOR y19 -> cmp +y24 XOR x24 -> gww +prp AND pfc -> rkh +rmb AND kmr -> fws +nnq OR bdn -> gfd +y39 XOR x39 -> vqf +qpm XOR csw -> z21 +smt XOR wpp -> wts +x12 AND y12 -> bnn +x10 XOR y10 -> rmb +y33 XOR x33 -> wmq +x18 XOR y18 -> hns +vvs OR hpn -> cfn +jmf AND gww -> rjb +nrg OR mvs -> bvr +cmp AND wfc -> pbb +kbq AND rvn -> vtm +gfk OR dpv -> jth +y25 AND x25 -> cqg +wvt AND sbt -> dpv +cmb AND tvf -> mqr +hjp XOR kjs -> z01 +y00 AND x00 -> hjp +x35 XOR y35 -> djt +mwt AND cng -> hbm +y24 AND x24 -> tcq +tsk XOR hvc -> z29 +rkt AND skh -> kjk +jth AND jvf -> whn +x02 AND y02 -> nhp +hns AND qvq -> mts +y04 XOR x04 -> jvf +pfc XOR prp -> z25 +y03 XOR x03 -> sbt +csw AND qpm -> mvs +y29 AND x29 -> bsw +wkb AND jkr -> hhj +x03 AND y03 -> gfk +vqf XOR fkq -> z39 +x15 XOR y15 -> jqf +wpd OR dpf -> dtq +nrv OR jsp -> z45 +jtg AND cfn -> qhk +rhd OR vtm -> wrc +y30 XOR x30 -> nnn +htn AND dtq -> gvh +y43 AND x43 -> dbj +x17 AND y17 -> cwn +htn XOR dtq -> z12 +y20 AND x20 -> jgg +vdq AND rvm -> hmk +jgw OR rhh -> z37 +jsg XOR hks -> z44 +gns OR dwg -> sgf +fqg OR wkq -> vdq +vqf AND fkq -> hwb +x04 AND y04 -> gwv +msf XOR kdd -> z28 +rjs XOR tmg -> z08 +x16 AND y16 -> rhd +x06 AND y06 -> hhw +gkc AND qqw -> z11 +x28 XOR y28 -> kdd +fws OR gvj -> qqw +y39 AND x39 -> ppk +rfq AND hbh -> pwb +y11 AND x11 -> dpf +x40 XOR y40 -> nns +hbm OR hnh -> gsk +y09 AND x09 -> csb +y37 XOR x37 -> wpp +hmk OR nhp -> wvt +x34 XOR y34 -> nss +rck XOR ftq -> z32 +jsg AND hks -> nrv +y37 AND x37 -> rhh +wpp AND smt -> jgw +y11 XOR x11 -> gkc +x07 XOR y07 -> qpc +qpw OR rbg -> rhf +x15 AND y15 -> skh +y22 XOR x22 -> wwp +hhw OR qhk -> qmb +jmp OR csb -> kmr +hbw AND wrc -> jks +x13 XOR y13 -> dmp +gwv OR whn -> whf +dts AND wmq -> sbw +bnn OR gvh -> jkm +qmb XOR qpc -> z07 +bvw AND hvn -> cmm +y10 AND x10 -> gvj +x44 AND y44 -> jsp +jtg XOR cfn -> z06 +wwp XOR bvr -> z22 +y22 AND x22 -> gmf