Added solution for day 3
This commit is contained in:
parent
a3ae16a66e
commit
c1be68903e
3 changed files with 1067 additions and 0 deletions
12
3/example.txt
Normal file
12
3/example.txt
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
00100
|
||||||
|
11110
|
||||||
|
10110
|
||||||
|
10111
|
||||||
|
10101
|
||||||
|
01111
|
||||||
|
00111
|
||||||
|
11100
|
||||||
|
10000
|
||||||
|
11001
|
||||||
|
00010
|
||||||
|
01010
|
1000
3/input.txt
Normal file
1000
3/input.txt
Normal file
File diff suppressed because it is too large
Load diff
55
3/solution.hs
Normal file
55
3/solution.hs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import Data.Bits ( complement, Bits (shift, shiftR, rotate, complementBit), shiftL, (.|.) )
|
||||||
|
import Data.List (transpose, isPrefixOf, inits, find, tails, sort)
|
||||||
|
import Debug.Trace
|
||||||
|
import Data.Maybe
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = readFile "3/input.txt" >>= print . solve . parse . lines
|
||||||
|
|
||||||
|
parse :: [String] -> [String]
|
||||||
|
parse = id
|
||||||
|
|
||||||
|
solve :: [String] -> (Int,Int)
|
||||||
|
solve input = (f input, g input)
|
||||||
|
where f = powerUse . transpose
|
||||||
|
g = lifeSupport
|
||||||
|
|
||||||
|
powerUse :: [String] -> Int
|
||||||
|
powerUse i = gamma i * epsilon i
|
||||||
|
where
|
||||||
|
gamma = pack . rate (>=)
|
||||||
|
epsilon = pack . rate (<)
|
||||||
|
|
||||||
|
rate :: (Int -> Int -> Bool) -> [String] -> [Int]
|
||||||
|
rate op = foldr (\c -> (:) (
|
||||||
|
let ones = count '1' c;
|
||||||
|
zeroes = count '0' c;
|
||||||
|
in if ones `op` zeroes
|
||||||
|
then 1
|
||||||
|
else 0
|
||||||
|
)) []
|
||||||
|
where
|
||||||
|
count x = length . filter (== x)
|
||||||
|
|
||||||
|
lifeSupport :: [String] -> Int
|
||||||
|
lifeSupport i = oxygen x * scrubber x
|
||||||
|
where
|
||||||
|
x = reverse i
|
||||||
|
oxygen = rating 0 (>=)
|
||||||
|
scrubber = rating 0 (<)
|
||||||
|
|
||||||
|
rating :: Int -> (Int -> Int -> Bool) -> [String] -> Int
|
||||||
|
rating _ _ [result] = convert result
|
||||||
|
rating n op list = rating (n + 1) op (filter (\a -> (a !! n) == (f (transpose list) !! n)) list)
|
||||||
|
where
|
||||||
|
f = map (head . show) . rate op
|
||||||
|
|
||||||
|
pack :: [Int] -> Int
|
||||||
|
pack = foldl f 0
|
||||||
|
where
|
||||||
|
f acc i = acc `shiftL` 1 .|. i
|
||||||
|
|
||||||
|
unpack :: String -> [Int]
|
||||||
|
unpack = map (\x -> if x == '0' then 0 else 1)
|
||||||
|
|
||||||
|
convert = pack . unpack
|
Loading…
Reference in a new issue