summaryrefslogtreecommitdiff
path: root/2015/day04_05_06.hs
blob: fd3f1fc76762e33d09e6cf11a42aa44ae7bdc6f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import Data.Char
import Data.List
import Data.Maybe
import Debug.Trace
import qualified Crypto.Hash.MD5 as MD5
import qualified Data.ByteString.Char8 as BS
import qualified Data.Map.Strict as Map

b2i :: Bool -> Int
b2i False = 0
b2i True = 1

contains :: (Eq a) => [a] -> a -> Bool
contains l i = isJust $ find (==i) l

isVowel :: Char -> Bool
isVowel = contains "aeiou"

maptup2 :: (a -> b) -> (a,a) -> (b,b)
maptup2 f (a,b) = (f a,f b)

convHex :: String -> String
convHex "" = ""
convHex (x:xs) = toHexDigit a : toHexDigit b : convHex xs
    where n = ord x
          (a,b) = divMod n 16
          toHexDigit n = "0123456789abcdef" !! n


day4_mine :: MD5.Ctx -> Int
day4_mine ctx = day4_mine' ctx 1

day4_mine' :: MD5.Ctx -> Int -> Int
day4_mine' ctx n = if take 6 (convHex $ BS.unpack $ MD5.finalize $ MD5.update ctx $ BS.pack $ show n) == "000000" then n else day4_mine' ctx (n+1)

day4 :: IO ()
day4 = do
    let prefix = "bgvyzdsv" :: String
    let ctx = MD5.update MD5.init (BS.pack prefix)
    putStrLn $ show $ day4_mine ctx




day5_count :: String -> (Int,Bool,Bool)
day5_count "" = (0,False,False)
day5_count s = day5_count' (tail s) (head s) (b2i (isVowel (head s)),False,False)

day5_count' :: String -> Char -> (Int,Bool,Bool) -> (Int,Bool,Bool)
day5_count' "" last t = t
day5_count' (x:xs) last (v,d,f) = day5_count' xs x (v + (b2i $ isVowel x),d||x==last,f||contains ["ab","cd","pq","xy"] [last,x])

day5_check :: (Int,Bool,Bool) -> Bool
day5_check (v,d,f) = v>=3&&d&&not f

day5_count2 :: String -> (Map.Map (Char,Char) Int,Bool,Bool)
day5_count2 s
    | length s < 2 = (Map.empty,False,False)
day5_count2 (a:b:cs) = day5_count2' a b (a,b) cs (Map.insert (a,b) 1 Map.empty,False,False)

day5_count2' :: Char -> Char -> (Char,Char) -> String -> (Map.Map (Char,Char) Int,Bool,Bool) -> (Map.Map (Char,Char) Int,Bool,Bool)
day5_count2' a b _ "" tup = tup
day5_count2' a b lastp (c:cs) (m,t,y) = day5_count2' b c (if lastp==(b,c) then ('\0','\0') else (b,c)) cs (if lastp==(b,c) then m else Map.insertWith (+) (b,c) 1 m,t||a==c,y||(lastp/=(b,c) && (isJust $ Map.lookup (b,c) m)))

day5_check2 :: (Map.Map (Char,Char) Int,Bool,Bool) -> Bool
day5_check2 (_,t,y) = t && y

day5 :: IO ()
day5 = do
    input <- readFile "input.txt"
    let strings = lines input
    putStrLn $ show $ sum [b2i $ day5_check2 $ day5_count2 s | s <- strings]





type Lighttype = Int

lightfuncs :: [Lighttype -> Lighttype]
lightfuncs = [succ,\x -> max 0 $ pred x,\x -> x+2] -- part 2
--lightfuncs = [\_ -> 1,\_ -> 0,\x -> 1-x] -- part 1

day6_spl :: String -> (Int,Int)
day6_spl s = (read $ take i s,read $ drop (i+1) s) :: (Int,Int)
    where i = fromJust $ findIndex (==',') s

--day6_set :: [[Lighttype]] -> (Lighttype -> Lighttype) -> (Int,Int) -> (Int,Int) -> [[Lighttype]]
--day6_set m f a b = trace (show m ++ "  " ++ show a ++ "  " ++ show b) $ traceShowId $ day6_set' m f a b

day6_set :: [[Lighttype]] -> (Lighttype -> Lighttype) -> (Int,Int) -> (Int,Int) -> [[Lighttype]]
day6_set m f a@(ax,ay) b@(bx,by)
    | ax==bx||ay==by = m
    | ay>by = day6_set m f b a
    | ax>bx = day6_set m f (bx,ay) (ax,by)
    | ay>0 = take ay m ++ day6_set (drop ay m) f (ax,0) (bx,by-ay)
    | by<length m = day6_set (take by m) f a b ++ drop by m
    | ax>0 = let splitted = map (splitAt ax) m in map (uncurry (++)) $ zip (map fst splitted) (day6_set (map snd splitted) f (0,ay) (bx-ax,by))
    | bx<length (m!!0) = map (uncurry (++)) $ zip (day6_set [take bx row | row <- m] f a b) ([drop bx row | row <- m])
    | otherwise = map (\row -> map f row) m

day6_exec :: [[Lighttype]] -> [String] -> [[Lighttype]]
day6_exec m l   -- = -- fixing sublime syntax highlighting
    | take 2 l == ["turn","on"] = day6_set m (lightfuncs!!0) (day6_spl (l!!2)) (maptup2 succ $ day6_spl (l!!4))
    | take 2 l == ["turn","off"] = day6_set m (lightfuncs!!1) (day6_spl (l!!2)) (maptup2 succ $ day6_spl (l!!4))
    | l!!0 == "toggle" = day6_set m (lightfuncs!!2) (day6_spl (l!!1)) (maptup2 succ $ day6_spl (l!!3))

day6 :: IO ()
day6 = do
    let size = 1000
    input <- readFile "input.txt"
    --let input = "turn on 0,0 through 3,2\ntoggle 1,1 through 3,3\n"
    --let input = ""
    --let input = "turn on 0,0 through 0,0"
    let wrd = [words l | l <- lines input]
    print $ sum $ [sum row | row <- foldl day6_exec (replicate size $ replicate size 0) wrd]





main = day6