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&¬ 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
|