summaryrefslogtreecommitdiff
path: root/2015
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2016-12-14 20:19:02 +0100
committertomsmeding <tom.smeding@gmail.com>2016-12-14 20:19:02 +0100
commit2d02f553aa4cc4ded630628eccdf34f55937cee5 (patch)
treed5377ebdff68788725b5820d5331ce7b6c9d4a84 /2015
parent97b4c5d86cc12447ac6845e25a863e26a88aec35 (diff)
Add 2015 sources
Diffstat (limited to '2015')
-rw-r--r--2015/day04_05_06.hs122
-rw-r--r--2015/day07.hs106
-rw-r--r--2015/day08.hs39
-rw-r--r--2015/day08.txt300
-rw-r--r--2015/day09.hs73
-rw-r--r--2015/day09.txt28
-rw-r--r--2015/day10.hs18
-rw-r--r--2015/day11.hs52
-rw-r--r--2015/day12.hs46
-rw-r--r--2015/day12.txt1
-rw-r--r--2015/day13.hs47
-rw-r--r--2015/day13.txt56
-rw-r--r--2015/day14.hs42
-rw-r--r--2015/day14.txt9
-rw-r--r--2015/day15.hs30
-rw-r--r--2015/day15.txt4
-rw-r--r--2015/day16.hs36
-rw-r--r--2015/day16.txt500
-rw-r--r--2015/day17.hs20
-rw-r--r--2015/day17.txt20
-rw-r--r--2015/day18.hs34
-rw-r--r--2015/day18.txt100
-rw-r--r--2015/day19.cpp89
-rw-r--r--2015/day19.hs41
-rw-r--r--2015/day19.txt45
-rw-r--r--2015/day20.cpp23
26 files changed, 1881 insertions, 0 deletions
diff --git a/2015/day04_05_06.hs b/2015/day04_05_06.hs
new file mode 100644
index 0000000..fd3f1fc
--- /dev/null
+++ b/2015/day04_05_06.hs
@@ -0,0 +1,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
diff --git a/2015/day07.hs b/2015/day07.hs
new file mode 100644
index 0000000..215355f
--- /dev/null
+++ b/2015/day07.hs
@@ -0,0 +1,106 @@
+module Main where
+
+import Data.Char
+import Data.List
+import Control.Monad
+import Data.Bits
+import Data.Word
+import qualified Data.Map as Map
+import qualified Data.Set as Set
+
+type Inttype = Word16
+
+data Literal = LNum Inttype | LName String
+
+data Command = Immediate Literal |
+ Monadic (Inttype -> Inttype) Literal |
+ Dyadic (Inttype -> Inttype -> Inttype) Literal Literal
+
+type Statement = (Command,String)
+
+type Cache = Map.Map String Inttype
+
+complement16 :: Inttype -> Inttype
+complement16 i = i `xor` 0xffff
+
+shiftL16 :: Inttype -> Int -> Inttype
+shiftL16 i n = (shiftL i n) .&. 0xffff
+
+shiftR16 :: Inttype -> Int -> Inttype
+shiftR16 i n = (shiftR i n) .&. 0xffff
+
+parseLit :: String -> Literal
+parseLit s = if isDigit (head s) then LNum (read s) else LName s
+
+parse :: [String] -> Statement
+parse l = (parse' (init $ init $ l),last l)
+
+parse' :: [String] -> Command
+parse' [n] = Immediate (parseLit n)
+parse' ["NOT",n] = Monadic complement16 (parseLit n)
+parse' [a,"AND",b] = Dyadic (.&.) (parseLit a) (parseLit b)
+parse' [a,"OR",b] = Dyadic (.|.) (parseLit a) (parseLit b)
+parse' [a,"LSHIFT",b] = Dyadic (\i n -> shiftL16 i (fromIntegral n)) (parseLit a) (parseLit b)
+parse' [a,"RSHIFT",b] = Dyadic (\i n -> shiftR16 i (fromIntegral n)) (parseLit a) (parseLit b)
+
+collectOutputs :: [Statement] -> [String]
+collectOutputs stmts = Set.toList $ collectOutputs' stmts Set.empty
+
+collectOutputs' :: [Statement] -> Set.Set String -> Set.Set String
+collectOutputs' [] set = set
+collectOutputs' ((_,target):ss) set = collectOutputs' ss $ Set.insert target set
+
+neededBy :: String -> Command -> Bool
+neededBy n (Immediate l) = case l of
+ LNum _ -> False
+ LName ln -> n == ln
+neededBy n (Monadic _ l) = case l of
+ LNum _ -> False
+ LName ln -> n == ln
+neededBy n (Dyadic _ (LNum _) b) = case b of
+ LNum _ -> False
+ LName bn -> n == bn
+neededBy n (Dyadic _ (LName an) b) = case b of
+ LNum _ -> n == an
+ LName bn -> n == an || n == bn
+
+leaves :: [Statement] -> [String]
+leaves stmts = leaves' (map fst stmts) (collectOutputs stmts)
+
+leaves' :: [Command] -> [String] -> [String]
+leaves' _ [] = []
+leaves' cmds (o:os) = if any (neededBy o) cmds then leaves' cmds os else o:leaves' cmds os
+
+getValue :: String -> [Statement] -> Cache -> (Inttype,Cache)
+getValue nm stmts cc = getValue' nm stmts stmts cc
+
+getValue' :: String -> [Statement] -> [Statement] -> Cache -> (Inttype,Cache)
+getValue' nm [] _ cc = case Map.lookup nm cc of
+ Nothing -> undefined
+ Just i -> (i,cc)
+getValue' nm ((cmd,target):ss) stmts cc = case Map.lookup nm cc of
+ Nothing -> if nm == target then execCmd cmd stmts cc else getValue' nm ss stmts cc
+ Just i -> (i,cc)
+
+resolveLit :: Literal -> [Statement] -> Cache -> (Inttype,Cache)
+resolveLit (LNum i) _ cc = (i,cc)
+resolveLit (LName n) stmts cc = (value,Map.insert n value cc2)
+ where (value,cc2) = getValue n stmts cc
+
+execCmd :: Command -> [Statement] -> Cache -> (Inttype,Cache)
+execCmd (Immediate l) stmts cc = resolveLit l stmts cc
+execCmd (Monadic f l) stmts cc = (f resl,cc2)
+ where (resl,cc2) = resolveLit l stmts cc
+execCmd (Dyadic f a b) stmts cc = (f resa resb,cc3)
+ where (resa,cc2) = resolveLit a stmts cc
+ (resb,cc3) = resolveLit b stmts cc2
+
+day7 :: IO ()
+day7 = do
+ input <- readFile "input.txt"
+ let stmts = [parse (words l) | l <- (lines input)]
+ let lvs = leaves stmts
+ print lvs
+ print [fst $ getValue lv stmts Map.empty | lv <- lvs]
+
+main = day7
diff --git a/2015/day08.hs b/2015/day08.hs
new file mode 100644
index 0000000..d48212b
--- /dev/null
+++ b/2015/day08.hs
@@ -0,0 +1,39 @@
+module Main where
+
+import Data.Char
+import Control.Monad
+
+parseHexSingle :: Char -> Int
+parseHexSingle x -- = -- subl syntax
+ | ord x >= ord '0' && ord x <= ord '9' = ord x - ord '0'
+ | ord x >= ord 'a' && ord x <= ord 'f' = 10 + ord x - ord 'a'
+ | ord x >= ord 'A' && ord x <= ord 'F' = 10 + ord x - ord 'A'
+ | otherwise = undefined
+
+parseHex :: String -> Int
+parseHex "" = 0
+parseHex (x:xs) = 16 * parseHexSingle x + parseHex xs
+
+parse :: String -> String
+parse s -- = -- subl syntax
+ | length s > 1 && head s == '"' && last s == '"' = parse' $ init $ tail s
+ | otherwise = undefined
+
+parse' :: String -> String
+parse' "" = ""
+parse' ('\\':'\\':xs) = '\\' : parse' xs
+parse' ('\\':'"':xs) = '"' : parse' xs
+parse' ('\\':'x':a:b:xs) = chr (parseHex $ [a,b]) : parse' xs
+parse' (x:xs) = x : parse' xs
+
+day8 :: IO ()
+day8 = do
+ input <- liftM lines $ readFile "day08.txt"
+ print $ sum [length s - length (parse s) | s <- input]
+
+day8_2 :: IO ()
+day8_2 = do
+ input <- liftM lines $ readFile "day08.txt"
+ print $ sum [length (show s) - length s | s <- input]
+
+main = day8
diff --git a/2015/day08.txt b/2015/day08.txt
new file mode 100644
index 0000000..94538e7
--- /dev/null
+++ b/2015/day08.txt
@@ -0,0 +1,300 @@
+"qxfcsmh"
+"ffsfyxbyuhqkpwatkjgudo"
+"byc\x9dyxuafof\\\xa6uf\\axfozomj\\olh\x6a"
+"jtqvz"
+"uzezxa\"jgbmojtwyfbfguz"
+"vqsremfk\x8fxiknektafj"
+"wzntebpxnnt\"vqndz\"i\x47vvjqo\""
+"higvez\"k\"riewqk"
+"dlkrbhbrlfrp\\damiauyucwhty"
+"d\""
+"qlz"
+"ku"
+"yy\"\"uoao\"uripabop"
+"saduyrntuswlnlkuppdro\\sicxosted"
+"tj"
+"zzphopswlwdhebwkxeurvizdv"
+"xfoheirjoakrpofles\"nfu"
+"q\xb7oh\"p\xce\"n"
+"qeendp\"ercwgywdjeylxcv"
+"dcmem"
+"\"i\x13r\"l"
+"ikso\xdcbvqnbrjduh\"uqudzki\xderwk"
+"wfdsn"
+"pwynglklryhtsqbno"
+"hcoj\x63iccz\"v\"ttr"
+"zf\x23\\hlj\\kkce\\d\\asy\"yyfestwcdxyfj"
+"xs"
+"m\"tvltapxdvtrxiy"
+"bmud"
+"k\"a"
+"b\"oas"
+"\"yexnjjupoqsxyqnquy\"uzfdvetqrc"
+"vdw\xe3olxfgujaj"
+"qomcxdnd\"\\cfoe\""
+"fpul"
+"m\"avamefphkpv"
+"vvdnb\\x\\uhnxfw\"dpubfkxfmeuhnxisd"
+"hey\\"
+"ldaeigghlfey"
+"eure\"hoy\xa5iezjp\\tm"
+"yygb\"twbj\\r\"\x10gmxuhmp\""
+"weirebp\x39mqonbtmfmd"
+"ltuz\\hs\"e"
+"ysvmpc"
+"g\x8amjtt\"megl\"omsaihifwa"
+"yimmm"
+"iiyqfalh"
+"cwknlaaf"
+"q\x37feg\xc6s\"xx"
+"uayrgeurgyp\\oi"
+"xhug\"pt\"axugllbdiggzhvy"
+"kdaarqmsjfx\xc3d"
+"\"vkwla"
+"d\""
+"tmroz\"bvfinxoe\\mum\"wmm"
+"\"n\"bbswxne\\p\\yr\"qhwpdd"
+"skzlkietklkqovjhvj\xfe"
+"pbg\\pab\"bubqaf\"obzcwxwywbs\\dhtq"
+"xxjidvqh\"lx\\wu\"ij"
+"daef\x5fe\x5b\\kbeeb\x13qnydtboof"
+"ogvazaqy\"j\x73"
+"y"
+"n\"tibetedldy\\gsamm\"nwu"
+"wldkvgdtqulwkad"
+"dpmxnj"
+"twybw\"cdvf\"mjdajurokbce"
+"ru\"\\lasij\"i"
+"roc\\vra\\lhrm"
+"pbkt\x60booz\"fjlkc"
+"j\x4dytvjwrzt"
+"\\uiwjkniumxcs"
+"cbhm\"nexccior\"v\"j\"nazxilmfp\x47"
+"qdxngevzrlgoq"
+"\"lrzxftytpobsdfyrtdqpjbpuwmm\x9e"
+"mdag\x0asnck\xc2ggj\"slb\"fjy"
+"wyqkhjuazdtcgkcxvjkpnjdae"
+"aixfk\xc0iom\x21vueob"
+"dkiiakyjpkffqlluhaetires"
+"ysspv\"lysgkvnmwbbsy"
+"gy\"ryexcjjxdm\"xswssgtr"
+"s"
+"ddxv"
+"qwt\"\x27puilb\"pslmbrsxhrz"
+"qdg\xc9e\\qwtknlvkol\x54oqvmchn\\"
+"lvo"
+"b"
+"fk\"aa\"\"yenwch\\\\on"
+"srig\x63hpwaavs\\\x80qzk\"xa\"\xe6u\\wr"
+"yxjxuj\"ghyhhxfj\"\xa6qvatre"
+"yoktqxjxkzrklkoeroil"
+"\"jfmik\""
+"smgseztzdwldikbqrh\""
+"jftahgctf\"hoqy"
+"tcnhicr\"znpgckt\"ble"
+"vqktnkodh\"lo\"a\\bkmdjqqnsqr"
+"ztnirfzqq"
+"s"
+"xx"
+"iqj\"y\\hqgzflwrdsusasekyrxbp\\ad"
+"\\xzjhlaiynkioz\"\"bxepzimvgwt"
+"s\x36rbw"
+"mniieztwrisvdx"
+"atyfxioy\x2b\\"
+"irde\x85\x5cvbah\\jekw\"ia"
+"bdmftlhkwrprmpat\"prfaocvp"
+"w\\k"
+"umbpausy"
+"zfauhpsangy"
+"p\"zqyw"
+"wtztypyqvnnxzvlvipnq\"zu"
+"deicgwq\\oqvajpbov\\or\"kgplwu"
+"mbzlfgpi\\\\zqcidjpzqdzxityxa"
+"lfkxvhma"
+"\xf2yduqzqr\"\\fak\"p\"n"
+"mpajacfuxotonpadvng"
+"anb\\telzvcdu\\a\xf2flfq"
+"lrs\"ebethwpmuuc\"\x86ygr"
+"qmvdbhtumzc\"ci"
+"meet"
+"yopg\x0fdxdq\"h\\ugsu\xffmolxjv"
+"uhy"
+"fzgidrtzycsireghazscvmwcfmw\\t"
+"cqohkhpgvpru"
+"bihyigtnvmevx\"xx"
+"xz"
+"zofomwotzuxsjk\"q\"mc\"js\"dnmalhxd"
+"\\ktnddux\\fqvt\"ibnjntjcbn"
+"ia"
+"htjadnefwetyp\xd5kbrwfycbyy"
+"\"\\hkuxqddnao"
+"meqqsz\x83luecpgaem"
+"cvks\x87frvxo\"svqivqsdpgwhukmju"
+"sgmxiai\\o\"riufxwjfigr\xdf"
+"fgywdfecqufccpcdn"
+"faghjoq\x28abxnpxj"
+"zuppgzcfb\"dctvp\"elup\"zxkopx"
+"xqs\x45xxdqcihbwghmzoa"
+"anbnlp\\cgcvm\"hc"
+"xf\"fgrngwzys"
+"nrxsjduedcy\x24"
+"\x71sxl\"gj\"sds\"ulcruguz\\t\\ssvjcwhi"
+"jhj\"msch"
+"qpovolktfwyiuyicbfeeju\x01"
+"nkyxmb\"qyqultgt\"nmvzvvnxnb"
+"ycsrkbstgzqb\"uv\\cisn"
+"s"
+"ueptjnn\"\"sh"
+"lp\"z\"d\"mxtxiy"
+"yzjtvockdnvbubqabjourf\"k\"uoxwle"
+"\x82\"wqm\""
+"\xb5cwtuks\x5fpgh"
+"wd"
+"tbvf"
+"ttbmzdgn"
+"vfpiyfdejyrlbgcdtwzbnm"
+"uc"
+"otdcmhpjagqix"
+"\\\xb1qso\"s"
+"scowax"
+"behpstjdh\xccqlgnqjyz\"eesn"
+"r\xe1cbnjwzveoomkzlo\\kxlfouhm"
+"jgrl"
+"kzqs\\r"
+"ctscb\x7fthwkdyko\"\x62pkf\"d\xe6knmhurg"
+"tc\"kw\x3ftt"
+"bxb\x5ccl"
+"jyrmfbphsldwpq"
+"jylpvysl\"\"juducjg"
+"en\\m\"kxpq\"wpb\\\""
+"madouht\"bmdwvnyqvpnawiphgac\""
+"vuxpk\"ltucrw"
+"aae\x60arr"
+"ttitnne\"kilkrgssnr\xfdurzh"
+"oalw"
+"pc\"\"gktkdykzbdpkwigucqni\"nxiqx"
+"dbrsaj"
+"bgzsowyxcbrvhtvekhsh\"qgd"
+"kudfemvk\"\"\"hkbrbil\"chkqoa"
+"zjzgj\\ekbhyfzufy"
+"\\acos\"fqekuxqzxbmkbnn\x1ejzwrm"
+"elxahvudn\"txtmomotgw"
+"\x2eoxmwdhelpr\"cgi\xf7pzvb"
+"eapheklx"
+"hfvma\"mietvc\"tszbbm\"czex"
+"h\"iiockj\\\xc1et"
+"d\"rmjjftm"
+"qlvhdcbqtyrhlc\\"
+"yy\"rsucjtulm\"coryri\"eqjlbmk"
+"tv"
+"r\"bfuht\\jjgujp\""
+"kukxvuauamtdosngdjlkauylttaokaj"
+"srgost\"\"rbkcqtlccu\x65ohjptstrjkzy"
+"yxwxl\\yjilwwxffrjjuazmzjs"
+"dxlw\\fkstu\"hjrtiafhyuoh\"sewabne"
+"\x88sj\"v"
+"rfzprz\xec\"oxqclu\"krzefp\\q"
+"cfmhdbjuhrcymgxpylllyvpni"
+"ucrmjvmimmcq\x88\xd9\"lz"
+"lujtt\""
+"gvbqoixn\"pmledpjmo\"flydnwkfxllf"
+"dvxqlbshhmelsk\x8big\"l"
+"mx\x54lma\x8bbguxejg"
+"\x66jdati\xeceieo"
+"\"iyyupixei\x54ff"
+"xohzf\"rbxsoksxamiu"
+"vlhthspeshzbppa\x4drhqnohjop\"\"mfjd"
+"f\"tvxxla\"vurian\"\"idjq\x3aptm\xc3olep"
+"gzqz"
+"kbq\\wogye\\altvi\\hbvmodny"
+"j\xd8"
+"ofjozdhkblvndl"
+"hbitoupimbawimxlxqze"
+"ypeleimnme"
+"xfwdrzsc\\oxqamawyizvi\\y"
+"enoikppx\xa1ixe\"yo\"gumye"
+"fb"
+"vzf"
+"zxidr"
+"cu\x31beirsywtskq"
+"lxpjbvqzztafwezd"
+"\\jyxeuo\x18bv"
+"b\"vawc\"p\\\\giern\"b"
+"odizunx\"\"t\\yicdn\"x\"sdiz"
+"\"\"tebrtsi"
+"ctyzsxv\xa6pegfkwsi\"tgyltaakytccb"
+"htxwbofchvmzbppycccliyik\xe5a"
+"ggsslefamsklezqkrd"
+"rcep\"fnimwvvdx\"l"
+"zyrzlqmd\x12egvqs\\llqyie"
+"\x07gsqyrr\\rcyhyspsvn"
+"butg\""
+"gb"
+"gywkoxf\"jsg\\wtopxvumirqxlwz"
+"rj\"ir\"wldwveair\x2es\"dhjrdehbqnzl"
+"ru\"elktnsbxufk\\ejufjfjlevt\\lrzd"
+"\"widsvok"
+"oy\"\x81nuesvw"
+"ay"
+"syticfac\x1cfjsivwlmy\"pumsqlqqzx"
+"m"
+"rjjkfh\x78cf\x2brgceg\"jmdyas\"\\xlv\xb6p"
+"tmuvo\"\x3ffdqdovjmdmkgpstotojkv\"as"
+"jd\\ojvynhxllfzzxvbn\"wrpphcvx"
+"pz"
+"\"twr"
+"n\\hdzmxe\"mzjjeadlz"
+"fb\"rprxuagvahjnri"
+"rfmexmjjgh\\xrnmyvnatrvfruflaqjnd"
+"obbbde\"co\"qr\"qpiwjgqahqm\\jjp\""
+"vpbq\"\"y\"czk\\b\x52ed\"lnzepobp"
+"syzeajzfarplydipny\"y\"\xe8ad"
+"mpyodwb"
+"\x47rakphlqqptd"
+"wa\"oj\"aiy"
+"a"
+"ropozx"
+"q\x51nbtlwa"
+"etukvgx\\jqxlkq"
+"\"tp\"rah\"pg\"s\"bpdtes\\tkasdhqd"
+"dn\"qqpkikadowssb\xcah\"dzpsf\\ect\"jdh"
+"pxunovbbrrn\\vullyn\"bno\"\"\"myfxlp\""
+"qaixyazuryvkmoulhcqaotegfj\\mpzm"
+"bvfrbicutzbjwn\\oml\"cf\"d\"ezcpv\"j"
+"rmbrdtneudemigdhelmb"
+"aq\\aurmbhy"
+"wujqvzw"
+"gf\"tssmvm\"gm\"hu\x9a\xb7yjawsa"
+"hrhqqxow\xe2gsydtdspcfqy\"zw\\ou"
+"ianwwf\\yko\\tdujhhqdi"
+"xylz\"zpvpab"
+"lwuopbeeegp"
+"aoop\x49jhhcexdmdtun"
+"\\\\mouqqcsgmz"
+"tltuvwhveau\x43b\"ymxjlcgiymcynwt"
+"gsugerumpyuhtjljbhrdyoj"
+"lnjm\xb8wg\"ajh"
+"zmspue\"nfttdon\\b\"eww"
+"\"w\x67jwaq\x7ernmyvs\\rmdsuwydsd\"th"
+"ogtgvtlmcvgllyv"
+"z\"fqi\"rvddoehrciyl"
+"yustxxtot\"muec\"xvfdbzunzvveq"
+"mqslw"
+"txqnyvzmibqgjs\xb6xy\x86nfalfyx"
+"kzhehlmkholov"
+"plpmywcnirrjutjguosh\\"
+"pydbnqofv\"dn\\m"
+"aegqof"
+"eambmxt\\dxagoogl\\zapfwwlmk"
+"afbmqitxxqhddlozuxcpjxgh"
+"vgts"
+"bfdpqtoxzzhmzcilehnflna"
+"s\"idpz"
+"\xcfhgly\"nlmztwybx\"ecezmsxaqw"
+"aackfgndqcqiy"
+"\x22unqdlsrvgzfaohoffgxzfpir\"s"
+"abh\"ydv\"kbpdhrerl"
+"bdzpg"
+"ekwgkywtmzp"
+"wtoodejqmrrgslhvnk\"pi\"ldnogpth"
+"njro\x68qgbx\xe4af\"\\suan"
diff --git a/2015/day09.hs b/2015/day09.hs
new file mode 100644
index 0000000..8437292
--- /dev/null
+++ b/2015/day09.hs
@@ -0,0 +1,73 @@
+module Main where
+
+import Data.Char
+import Data.List
+import Control.Monad
+import qualified Data.Set as Set
+
+import Debug.Trace
+
+indexof :: (Eq a) => [a] -> a -> Int
+indexof l x = indexof' l x 0
+
+indexof' :: (Eq a) => [a] -> a -> Int -> Int
+indexof' (x:xs) v n | x == v = n
+indexof' (_:xs) v n = indexof' xs v (n+1)
+
+contains :: (Eq a) => [a] -> a -> Bool
+contains [] _ = False
+contains (x:xs) v = if x == v then True else contains xs v
+
+collectnames :: [[String]] -> [String]
+collectnames l = Set.toList $ collectnames' l
+
+collectnames' :: [[String]] -> Set.Set String
+collectnames' [] = Set.empty
+collectnames' ((a:_:b:_):xs) = Set.insert a $ Set.insert b $ collectnames' xs
+
+setinarr :: [a] -> Int -> a -> [a]
+setinarr a i v = pre ++ v : post
+ where spl = splitAt i a
+ pre = fst spl
+ post = tail $ snd spl
+
+setinarr2 :: [[a]] -> (Int,Int) -> a -> [[a]]
+setinarr2 a (i,j) v = pre ++ setinarr line j v : post
+ where spl = splitAt i a
+ pre = fst spl
+ ([line],post) = splitAt 1 $ snd spl
+
+parse :: [[String]] -> [[Int]]
+parse ll = parse' ll names $ replicate numn (replicate numn 0)
+ where names = collectnames ll
+ numn = length names
+
+parse' :: [[String]] -> [String] -> [[Int]] -> [[Int]]
+parse' [] _ adj = adj
+parse' ([as,_,bs,_,ds]:ls) ns adj = parse' ls ns $ setinarr2 (setinarr2 adj (b,a) d) (a,b) d
+ where a = indexof ns as
+ b = indexof ns bs
+ d = read ds :: Int
+
+pathlen :: [Int] -> Int
+pathlen = sum
+
+genpaths :: [[Int]] -> [[Int]]
+genpaths adj = map todists $ concat [genpaths' adj [from] | from <- [0..(length adj - 1)]]
+ where todists (a:b:cs) = adj!!a!!b : todists (b:cs)
+ todists _ = []
+
+genpaths' :: [[Int]] -> [Int] -> [[Int]]
+genpaths' adj pat -- = -- subl syntax
+ | length pat == length adj = [pat]
+ | otherwise = {-traceShow pat $-} concat [genpaths' adj (from:pat) | from <- [0..(length adj - 1)], adj!!(head pat)!!from /= 0 && not (contains pat from)]
+
+day9 :: IO ()
+day9 = do
+ input <- liftM (map words . lines) $ readFile "day09.txt"
+ print $ collectnames input
+ --print $ parse input
+ --print $ genpaths $ parse input
+ print $ minimum [pathlen $ path | path <- genpaths $ parse input]
+
+main = day9
diff --git a/2015/day09.txt b/2015/day09.txt
new file mode 100644
index 0000000..a56f5e2
--- /dev/null
+++ b/2015/day09.txt
@@ -0,0 +1,28 @@
+AlphaCentauri to Snowdin = 66
+AlphaCentauri to Tambi = 28
+AlphaCentauri to Faerun = 60
+AlphaCentauri to Norrath = 34
+AlphaCentauri to Straylight = 34
+AlphaCentauri to Tristram = 3
+AlphaCentauri to Arbre = 108
+Snowdin to Tambi = 22
+Snowdin to Faerun = 12
+Snowdin to Norrath = 91
+Snowdin to Straylight = 121
+Snowdin to Tristram = 111
+Snowdin to Arbre = 71
+Tambi to Faerun = 39
+Tambi to Norrath = 113
+Tambi to Straylight = 130
+Tambi to Tristram = 35
+Tambi to Arbre = 40
+Faerun to Norrath = 63
+Faerun to Straylight = 21
+Faerun to Tristram = 57
+Faerun to Arbre = 83
+Norrath to Straylight = 9
+Norrath to Tristram = 50
+Norrath to Arbre = 60
+Straylight to Tristram = 27
+Straylight to Arbre = 81
+Tristram to Arbre = 90
diff --git a/2015/day10.hs b/2015/day10.hs
new file mode 100644
index 0000000..e5ff554
--- /dev/null
+++ b/2015/day10.hs
@@ -0,0 +1,18 @@
+module Main where
+
+import Data.Char
+import Data.List
+import Control.Monad
+
+looksay :: String -> String
+looksay "" = ""
+looksay s = chr (48 + length start) : head s : looksay rest
+ where start = takeWhile (== head s) s
+ rest = drop (length start) s
+
+day9 :: IO ()
+day9 = do
+ let input = "1113122113"
+ print $ length $ (iterate looksay input) !! 50
+
+main = day9
diff --git a/2015/day11.hs b/2015/day11.hs
new file mode 100644
index 0000000..f3c05b3
--- /dev/null
+++ b/2015/day11.hs
@@ -0,0 +1,52 @@
+module Main where
+
+import Data.Char
+import Numeric
+
+pairs :: String -> [(Char,Char)]
+pairs (a:b:cs) = (a,b) : pairs (b:cs)
+pairs _ = []
+
+allEqual :: (Eq a) => [a] -> Bool
+allEqual (a:b:cs) = if a /= b then False else allEqual (b:cs)
+allEqual _ = True
+
+
+hasStraight :: String -> Bool
+hasStraight (a:b:c:ds) = (y == x + 1 && z == x + 2) || hasStraight (b:c:ds)
+ where (x,y,z) = (ord a,ord b,ord c)
+hasStraight _ = False
+
+hasForbidden :: String -> Bool
+hasForbidden [] = False
+hasForbidden (x:xs) = x /= 'i' && x /= 'o' && x /= 'l' && not (hasForbidden xs)
+
+hasTwoPairs :: String -> Bool
+hasTwoPairs s = (not.allEqual) $ filter (\(a,b) -> a == b) (pairs s)
+
+isValid :: String -> Bool
+isValid s = hasStraight s && not (hasForbidden s) && hasTwoPairs s
+
+
+show26 :: Int -> String
+show26 n = showIntAtBase 26 (\d -> chr (97 + d)) n ""
+
+read26 :: String -> Int
+read26 = fst . head . readInt 26 (\c -> let o = ord c in 97 <= o && o <= 122) (\c -> ord c - 97)
+
+pad :: Int -> Char -> String -> String
+pad n c s = if length s < n then pad n c (c:s) else s
+
+
+nextpass :: String -> String
+nextpass s = pad (length s) 'a' $ show26 $ succ $ read26 s
+
+nextvalidpass :: String -> String
+nextvalidpass = head . dropWhile (not . isValid) . iterate nextpass
+
+
+day11 :: IO ()
+day11 = do
+ print $ nextvalidpass $ nextpass $ nextvalidpass "cqjxjnds"
+
+main = day11
diff --git a/2015/day12.hs b/2015/day12.hs
new file mode 100644
index 0000000..6dbf8a0
--- /dev/null
+++ b/2015/day12.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+import Data.Char
+import Data.Maybe
+import Data.Word
+import Data.Scientific
+import qualified Data.Aeson as JSON
+import qualified Data.Vector as Vector
+import qualified Data.HashMap.Strict as HM
+import qualified Data.ByteString.Lazy as BS
+import qualified Data.ByteString.Internal as BS (c2w,w2c)
+
+contains :: (Eq a) => [a] -> a -> Bool
+contains [] _ = False
+contains (x:xs) v = if x == v then True else contains xs v
+
+isDigitOrMinus :: Char -> Bool
+isDigitOrMinus c = isDigit c || c == '-'
+
+extractNumbers :: String -> [Int]
+extractNumbers s@(x:xs)
+ | isDigitOrMinus x = read (takeWhile isDigitOrMinus s) : extractNumbers (dropWhile isDigitOrMinus xs)
+ | otherwise = extractNumbers xs
+extractNumbers [] = []
+
+sumnumsnored :: JSON.Value -> Int
+sumnumsnored (JSON.Object o) = if any (== JSON.String "red") $ HM.elems o then 0 else HM.foldl' (\a v -> a + sumnumsnored v) 0 o
+sumnumsnored (JSON.Array a) = Vector.sum $ Vector.map sumnumsnored a
+sumnumsnored (JSON.String _) = 0
+sumnumsnored (JSON.Number n) = floor n
+sumnumsnored (JSON.Bool _) = 0
+
+day12 :: IO ()
+day12 = do
+ input <- readFile "day12.txt"
+ print $ sum $ extractNumbers input
+
+dopart2 :: String -> Int
+dopart2 s = sumnumsnored $ fromJust $ JSON.decode $ BS.pack $ map BS.c2w s
+
+day12_2 :: IO ()
+day12_2 = do
+ input <- readFile "day12.txt"
+ print $ dopart2 input
+
+main = day12_2
diff --git a/2015/day12.txt b/2015/day12.txt
new file mode 100644
index 0000000..d813484
--- /dev/null
+++ b/2015/day12.txt
@@ -0,0 +1 @@
+{"e":{"a":{"e":-39,"c":119,"a":{"c":65,"a":"orange","b":"green","d":"orange"},"g":"violet","b":{"e":6,"c":{"c":"violet","a":8,"b":["red",{"a":37},"green",84,"yellow","green",[24,45,"blue","blue",56,"yellow"],"orange"]},"a":"violet","b":{"a":85},"d":[109,66,["yellow","violet",21,-30],"violet","blue",-43,{"e":"violet","c":"red","a":"blue","b":-22,"d":[71,"red",30,"violet","red",26,120],"f":["red"]},"red"]},"d":{"e":"violet","a":"blue","d":"blue","c":"blue","h":"orange","b":{"e":"red","a":{"c":115,"a":137,"b":"green"},"d":-25,"c":"blue","h":{"a":161,"b":["yellow",56,129,-31,"yellow","red","green",105,"orange",130]},"b":142,"g":194,"f":122,"i":-16},"g":173,"f":["orange","green",54,-9],"i":-23},"f":{"c":110,"a":"yellow","b":[{"a":155},156,"violet",94,"yellow"],"d":{"e":91,"a":-18,"d":"red","c":["green","orange","orange",190,"yellow",158,"blue","orange","blue",4],"h":143,"b":"orange","g":145,"f":["orange",37,"yellow",-22,{"c":30,"a":78,"b":196,"d":84},-7,["yellow"]]}}},"b":[[{"c":0,"a":108,"b":"green","d":{"e":59,"c":119,"a":104,"b":167,"d":"blue"}},[189,"blue",121,[["green","orange","orange",-17,192,"red"],{"a":"violet"},"green",{"c":42,"a":"blue","b":"red"},{"e":78,"a":"blue","d":"violet","c":-9,"h":"violet","b":115,"g":"orange","f":"violet","i":"red"}],57,"violet"],"green"],[["blue",[1,53,"orange"],{"e":["green",-12,"blue","orange","green",136,173],"a":"violet","d":-43,"c":{"e":144,"c":133,"a":"yellow","g":154,"b":"orange","d":127,"f":194},"h":{"e":52,"a":-43,"d":"orange","c":-45,"h":"orange","b":150,"g":-12,"f":91,"i":6},"b":{"e":"yellow","c":"blue","a":"violet","g":112,"b":174,"d":"violet","f":90},"g":177,"f":"blue"},"red","violet",96],"green","violet",[{"a":["red","red",46,"red"],"b":["green",193,54,"orange"]},["orange",8,1,["violet",84,"violet"],155,"yellow",151,"blue",196],"yellow","red",{"a":["green","orange","green",61,"blue",39,-2,46,"red",54]},"violet",128]]]},"a":{"e":[{"e":["yellow"],"c":93,"a":"violet","b":{"a":{"a":"yellow","b":"blue"},"b":-4},"d":"violet"},171,103,[13,"orange",[[51,"violet","yellow",{"c":85,"a":103,"b":"green"},97,{"e":"orange","a":-11,"d":62,"j":"yellow","c":"orange","h":47,"b":83,"g":119,"f":180,"i":136},{"a":177},80],{"e":{"c":"yellow","a":"orange","b":3,"d":197},"a":130,"d":"red","j":"red","c":-44,"h":-15,"b":64,"g":125,"f":82,"i":"green"}],{"e":["orange",42,["orange",197,"violet","yellow","blue",11,"yellow"],189,"yellow","blue","green","violet"],"a":{"a":149,"b":69},"d":128,"c":[["green",150,45,86,"red",-8,41,"orange","blue"]],"h":[[-4,127,"yellow","violet",124,112,196,"violet",161,40],37,0,"orange",-30,-43,[-24,"orange",142,"violet","red"],"blue",66],"b":{"c":"violet","a":["yellow",91,182,20,"orange",159,46,55,141],"b":{"c":173,"a":-40,"b":"green","d":"violet"},"d":[67,80,27,-15]},"g":"red","f":{"c":"orange","a":99,"b":"green"}},{"e":{"c":40,"a":"orange","b":"green"},"c":"green","a":-44,"b":{"e":"blue","c":56,"a":"yellow","g":62,"b":188,"d":141,"f":-21},"d":"yellow","f":{"e":"yellow","c":67,"a":33,"g":"yellow","b":"yellow","d":51,"f":195}}],["orange","violet",["red"],["green",35,[170,-30,"orange",140,"green","violet","violet",["orange","yellow","yellow",35,"blue","violet",-36,182,"yellow",141],146]],{"a":61,"b":"orange"},[31,"blue","green",65,"red","green"],"violet"],{"c":"blue","a":["blue"],"b":17},95],"c":[[48,"blue",[49],"orange",{"e":"violet","c":"green","a":"red","b":"red","d":-29,"f":["orange",20,190,97,["orange","blue",-30,"blue","green"],"blue","yellow",-47,[123,"yellow","green"],-41]},"green",{"a":170,"b":32},[{"c":"green","a":"violet","b":"red"},["yellow",36,"yellow","violet",149,{"e":"red","c":141,"a":-24,"b":"yellow","d":-13,"f":"red"},69,"orange",19,[87,"red",167,"red",77,110]],"orange","violet"],{"a":-16}],[["red"],"violet"],{"a":[["red",83,{"e":"red","c":"blue","a":"blue","b":"orange","d":"orange"},49,"green","violet"],{"e":"yellow","a":"violet","d":17,"j":"green","c":{"e":"orange","c":"green","a":"green","b":99,"d":"yellow","f":"orange"},"h":9,"b":159,"g":"yellow","f":167,"i":147},["blue","green","violet"],"yellow",["violet",197,"blue",[170,81,"yellow","orange",196],-24,99,193],-8,["red",81,-11,"green","red","blue","yellow","blue",["blue","violet",131,184,160,-1]],"green"]},"orange"],"a":[{"e":"blue","a":"violet","d":[{"a":"blue","b":46},"violet",72,35,61,161],"j":["green",78,144,[168,["red",77,38,"green","red"],"green","yellow",-8,"yellow"],190,40,"yellow",17,171],"c":{"e":"red","c":"violet","a":"violet","b":-14,"d":"red","f":167},"h":[[[83,"green",69,"red"],"green",155,133],106,1,"orange"],"b":-41,"g":{"a":27},"f":"red","i":{"e":"green","c":"green","a":182,"g":"orange","b":"orange","d":["orange"],"f":"orange"}},"yellow","green",-26],"b":{"e":[-32,-11,{"e":"red","c":"yellow","a":{"e":"green","a":"red","d":105,"c":-20,"h":85,"b":{"e":47,"a":89,"d":"green","c":"violet","h":"orange","b":"green","g":140,"f":"green"},"g":111,"f":"orange","i":"yellow"},"b":143,"d":{"e":{"e":"orange","c":129,"a":"blue","b":142,"d":"violet"},"c":"blue","a":122,"b":["violet","orange",84,"orange"],"d":"red","f":"blue"}},58,[147]],"a":{"e":"orange","c":[{"e":141,"c":114,"a":137,"g":"orange","b":61,"d":105,"f":33}],"a":["red","red",{"e":"green","c":4,"a":"violet","b":"red","d":"blue"},"yellow",["green",15,"green",-40,149,"orange",{"e":-7,"c":74,"a":"red","b":"green","d":32}],"blue","yellow",146,[191,"blue",["orange","blue",187,"blue","orange",127,"yellow",38],120,161,55,-30,"green",-10,"violet"],"orange"],"b":{"a":-32,"b":"blue"},"d":{"e":["green",27],"c":[94,"violet","red",18,166,"yellow"],"a":{"e":"green","a":95,"d":"green","j":176,"c":84,"h":"violet","b":"yellow","g":-25,"f":51,"i":119},"b":144,"d":{"c":"violet","a":"yellow","b":"red"}}},"d":{"e":{"e":140,"a":{"e":"green","c":"green","a":0,"b":68,"d":152,"f":"red"},"d":["blue",6],"c":-29,"h":"green","b":["violet",106,"violet","orange",-38,175],"g":54,"f":[177,31,"violet","yellow"],"i":185},"a":"green","d":[111,49,"yellow","blue","orange",{"e":"yellow","a":"orange","d":"violet","j":"blue","c":"red","h":88,"b":-1,"g":"red","f":"red","i":{"e":121,"a":112,"d":195,"j":103,"c":94,"h":"red","b":12,"g":8,"f":22,"i":"orange"}},64,["violet",["blue",76,"blue","red","red"],["violet","blue","orange","yellow",144],185,{"a":66,"b":"orange"},199,"green","green"],14],"c":{"e":"green","a":"orange","d":{"c":[-23,189,-11,"green","violet",178,-4,"blue",68,"violet"],"a":["orange","red"],"b":"yellow","d":"yellow"},"j":{"c":-33,"a":"blue","b":"violet"},"c":107,"h":{"e":-16,"a":174,"d":{"e":"orange","c":"green","a":-28,"b":-30,"d":73},"j":"yellow","c":"orange","h":"orange","b":["blue","violet",-4,76,"red","red"],"g":59,"f":12,"i":199},"b":{"a":"green","b":54},"g":"violet","f":174,"i":["orange",41,85,"yellow","green",25,"red",-20,156,143]},"h":"yellow","b":"red","g":90,"f":-37,"i":{"a":146,"b":"violet"}},"j":"blue","c":[1,["yellow",-11,"green",66,"red",90,"green","yellow",3,{"e":-34,"a":194,"d":"green","c":[-11,"yellow"],"h":59,"b":"yellow","g":"blue","f":162,"i":"violet"}],81,158,170],"h":"blue","b":"green","g":["violet",["blue","blue"]],"f":[-44,"yellow",[35,[122,"red","yellow",{"a":"red","b":"violet"},"blue","orange","violet"],"violet",{"e":-48,"a":6,"d":-6,"c":4,"h":"yellow","b":"blue","g":"red","f":"red"}],[{"e":-2,"a":156,"d":"red","j":69,"c":0,"h":"violet","b":"orange","g":61,"f":102,"i":["orange","blue","violet",-1,137]},{"a":183,"b":89}],{"a":167,"b":"orange"},193,95,[97,[66,154,-32,"orange",121,{"e":198,"a":"blue","d":102,"c":"red","h":"green","b":135,"g":"orange","f":-49,"i":151},97,7,"red"],195,"blue",49,"green",10]],"i":["violet",1,{"e":"orange","c":196,"a":"blue","g":"red","b":190,"d":87,"f":128},"blue",128,147]},"d":[[{"a":"green","b":43},169,-8,"orange",{"a":["violet",["red","violet","orange","yellow",-49,"violet",-25],"violet",60,33,"violet",["yellow","orange",31,144,"red","yellow",73,"orange","red","green"],["green",-31,"red"],"orange","blue"]},"violet","blue"],40,154,{"a":{"c":"violet","a":145,"b":166,"d":["blue",["blue",125,185,"yellow","red",152,89,-18,"blue",141],26,2,35,"orange",190]}},170,"violet",-31,[[151,"orange","green",["blue",114,-5,"yellow"],"blue","green","orange","yellow",62,{"c":22,"a":"green","b":"blue"}],17,[176],"violet",129,67,{"c":{"c":"red","a":140,"b":25},"a":["blue","green",163],"b":30,"d":[60,"green","red",126,[48,"green"],-26,["yellow","green",150,"red","violet","red","violet",59,-12],167,"yellow"]},"yellow","yellow"],"blue"]},"d":{"c":"green","a":52,"b":[136,{"c":{"a":[197,["orange","red",138,67,"orange",172,2,"orange"],"red"]},"a":"violet","b":{"a":{"e":172,"c":171,"a":"yellow","b":191,"d":{"e":171,"a":"red","d":"violet","c":"green","h":"yellow","b":"yellow","g":73,"f":"yellow"}}},"d":[86,-11,-5,["orange","green",64,["blue",15,"orange","yellow","violet",181,"green","blue"],"yellow","yellow",{"e":27,"c":156,"a":"blue","g":"violet","b":38,"d":51,"f":23},"orange","violet"],10]},[55,{"e":191,"c":"blue","a":"orange","b":"yellow","d":109},"blue",{"c":164,"a":[198,-9,183,{"e":14,"a":176,"d":117,"c":"violet","h":"violet","b":-44,"g":"violet","f":"red","i":"orange"},"yellow",0],"b":58,"d":33},"red",[125,23,"blue",149,[["blue",-44,22,133,"orange","yellow","yellow","violet","violet",131],"violet",-1,"red",66,"blue"],"green","red","red",[-31,"blue",["orange","orange","yellow",44,"green","yellow","green",160,"violet"],"yellow",["orange","violet","green","violet",194,"blue",-27],"green",{"e":"violet","a":"red","d":67,"c":68,"h":"blue","b":"orange","g":"orange","f":"violet","i":"violet"},"yellow"]],"violet",[59,158,{"e":"blue","c":"blue","a":"orange","g":73,"b":97,"d":"red","f":"orange"}],["red",[31,[95,72,"orange","yellow"],"blue",192,63],[197,"green",{"e":112,"a":"violet","d":"blue","c":-2,"h":"blue","b":"green","g":124,"f":"blue"},177,"green","blue",162,107]]],43,[{"e":"red","c":{"e":["green",-33,11,154,"yellow",-4],"c":"yellow","a":[7,"orange","orange","yellow",118,169,"red","blue"],"b":"green","d":114},"a":{"e":"green","a":"green","d":187,"j":{"e":106,"c":-41,"a":"violet","b":173,"d":12},"c":"red","h":"violet","b":-4,"g":{"c":"violet","a":-26,"b":87,"d":-33},"f":"green","i":-46},"b":"green","d":13,"f":"yellow"}],["blue","violet","orange","red",{"e":"green","a":["violet",140,[76,"green",94,33,"green",31,"orange",53],"violet","yellow","violet","blue",["blue",196,"orange","yellow","orange",-42,"orange",171,-47,"violet"],"green",110],"d":31,"c":"orange","h":{"e":-45,"a":"green","d":["violet"],"c":"red","h":105,"b":130,"g":-36,"f":"orange","i":{"e":"red","c":137,"a":54,"g":"blue","b":"violet","d":102,"f":178}},"b":-41,"g":{"e":6,"a":-25,"d":66,"j":"violet","c":39,"h":30,"b":63,"g":46,"f":56,"i":"blue"},"f":6,"i":"violet"},[84,175,"orange",{"a":"green"},"green",66,{"e":"red","a":{"a":178,"b":"yellow"},"d":"yellow","c":["red","red",38,"orange","blue",136,"red",137,"red"],"h":163,"b":["orange",84,"red",178],"g":65,"f":"blue"}],[98,"yellow",[46,"orange","yellow","yellow"],"blue",151,189,["yellow",{"e":"orange","a":27,"d":45,"c":48,"h":"green","b":90,"g":180,"f":-43},"yellow"],"blue"],{"a":"green"},"blue",{"c":37,"a":{"e":59,"c":["blue"],"a":"yellow","g":38,"b":"blue","d":"violet","f":"orange"},"b":"orange","d":"violet"}],{"c":75,"a":{"e":{"a":130},"a":5,"d":1,"c":72,"h":{"e":"red","a":11,"d":157,"c":97,"h":-24,"b":"red","g":111,"f":21},"b":{"e":145,"a":"red","d":"violet","j":[-11,191,-43,"blue","orange",105,158],"c":"red","h":143,"b":{"e":"orange","c":"yellow","a":-31,"g":177,"b":"violet","d":"blue","f":"green"},"g":"green","f":48,"i":{"e":18,"a":142,"d":"yellow","c":116,"h":"violet","b":135,"g":37,"f":36}},"g":-26,"f":[186,192,"orange",117,-9,"violet",-19,55,"green",167],"i":"green"},"b":"yellow","d":{"a":138}}]},"c":"blue","h":[[19],"orange",[{"e":["yellow",68,28,29,{"e":"red","a":"violet","d":"green","c":143,"h":"red","b":"orange","g":44,"f":123,"i":"orange"},38,28,65,{"e":-26,"c":["red",132,"red",124,"yellow",115],"a":170,"g":"yellow","b":"green","d":-18,"f":{"c":1,"a":"red","b":-1}}],"a":"orange","d":129,"c":33,"h":"violet","b":"orange","g":"green","f":-24},["violet",-22],[64,-20,{"e":46,"a":76,"d":97,"c":-21,"h":98,"b":"violet","g":{"e":-7,"c":"violet","a":190,"b":"violet","d":138,"f":"violet"},"f":[178,"blue","blue"],"i":"red"},{"e":"orange","c":"red","a":{"e":"orange","a":["green"],"d":[19,"red"],"c":-32,"h":-15,"b":"yellow","g":116,"f":"blue","i":"orange"},"b":96,"d":"green","f":176},[[104,99,"yellow",-13,"red",{"c":"blue","a":"red","b":46,"d":60},-13,9],-22,-26,133,["green",["red",188,"green","green"],166,"yellow",{"e":"yellow","c":197,"a":65,"b":83,"d":-19,"f":"yellow"},[157,"violet","blue","yellow",-30,"violet",-3],21,{"a":-15}],43,["orange","blue",88,"yellow",103,31],"orange",-24]],{"c":"violet","a":{"a":26,"b":"yellow"},"b":["violet","violet",{"e":102,"a":"red","d":178,"j":187,"c":"orange","h":"violet","b":72,"g":-37,"f":"violet","i":"orange"},44,114,"yellow",85]}],{"e":150,"c":"green","a":{"e":{"e":{"e":{"e":"orange","a":48,"d":41,"j":"orange","c":"orange","h":30,"b":"yellow","g":41,"f":-40,"i":8},"c":199,"a":32,"b":"yellow","d":-28},"a":46,"d":[50,"red","violet",63,"red",56,-18,"orange","violet","red"],"c":"blue","h":{"e":"green","c":172,"a":"green","b":-30,"d":22,"f":"yellow"},"b":"orange","g":65,"f":"yellow","i":174},"a":"green","d":[196,{"e":{"e":176,"a":"violet","d":"orange","j":-37,"c":19,"h":31,"b":155,"g":"red","f":106,"i":"green"},"c":"red","a":64,"b":"orange","d":179,"f":8},"yellow",103,"violet",{"e":142,"a":111,"d":"yellow","c":"violet","h":"red","b":148,"g":29,"f":179,"i":"green"},-26],"c":-19,"h":["red",134,"green","green",105],"b":"orange","g":126,"f":76,"i":158},"b":55,"d":"green"},[[[61],[["orange","red"],[151,"yellow",127,"yellow",185,"yellow",{"e":105,"c":"yellow","a":198,"b":"orange","d":"blue","f":89},140,{"e":"violet","a":-15,"d":169,"j":3,"c":"yellow","h":74,"b":-41,"g":29,"f":112,"i":18}]],101,{"e":[45,"green","yellow","blue","violet",["violet","yellow",159,0,"orange","yellow",100,"green","blue",49],[5,-37],"blue","orange"],"c":88,"a":"blue","b":-32,"d":23},77,{"e":["yellow",119,197,["orange",-28,"yellow",179,130,74,-10,115,"violet",79],"orange",63,-15,17,"blue","violet"],"c":{"e":164,"a":83,"d":"yellow","c":119,"h":"yellow","b":148,"g":-22,"f":[-17,17,"violet","green","red"],"i":67},"a":{"e":54,"a":147,"d":"yellow","c":86,"h":113,"b":"yellow","g":77,"f":101,"i":"blue"},"g":"orange","b":[193,"orange","orange","red",39,44,43,-29],"d":"violet","f":191}],"orange",["red","violet","yellow",["red",54,{"e":{"a":41,"b":"violet"},"c":"red","a":{"e":"red","a":"yellow","d":"green","j":-33,"c":96,"h":137,"b":"yellow","g":30,"f":"green","i":"blue"},"b":181,"d":"violet","f":"green"},49,"yellow"],"orange","yellow",{"e":"orange","c":[46,"orange",["blue","green","blue","yellow","yellow","violet","orange","orange",1],"yellow",155,194,"yellow",149],"a":"green","b":-3,"d":153,"f":[-21,-26,-25,"blue","red",108,169,["green",100,43],51,-9]}],71,[[[{"a":"violet","b":27},148,109,["blue",60,47,"violet","yellow",-47,"violet"],"red",{"e":97,"c":-21,"a":"yellow","b":"green","d":126},"yellow",85,89],{"a":["red","orange","violet","blue","blue","blue",128,"blue"]},{"e":-48,"c":{"c":90,"a":"orange","b":"yellow"},"a":"yellow","b":"red","d":172},"yellow",{"a":"orange"},[{"e":"yellow","a":40,"d":-9,"j":"violet","c":153,"h":79,"b":"violet","g":178,"f":2,"i":"yellow"},"green",-29],"red",-9,[9,{"a":39,"b":"green"},5,"violet",26,{"e":167,"c":"blue","a":"yellow","b":90,"d":33},"green",88,12,"blue"]],"red",{"c":{"e":"yellow","a":-44,"d":62,"j":-19,"c":96,"h":"green","b":-12,"g":"green","f":"red","i":134},"a":22,"b":24,"d":33},"red","violet",{"e":181,"c":64,"a":"violet","g":"green","b":"yellow","d":"violet","f":101},"green",[132,93,[-6,[-3,28,"red"],-21,"red","violet",{"a":180},"red","blue",-15],{"e":171,"a":{"e":"green","c":49,"a":"orange","g":22,"b":"violet","d":"orange","f":"orange"},"d":"red","c":113,"h":"green","b":[30,"blue"],"g":{"a":139,"b":47},"f":"red","i":"red"},"violet",158,"green",5,-1],19],"red"],{"e":{"c":["orange",93,162,"green","violet",["green",178],{"a":"green","b":{"e":-12,"a":-16,"d":144,"c":"red","h":"violet","b":43,"g":"green","f":-42}}],"a":"blue","b":"blue","d":{"e":["orange","red",{"c":-19,"a":"green","b":93},"yellow","green","orange","orange","red","green"],"a":"green","d":{"e":"yellow","a":2,"d":"violet","j":"green","c":"blue","h":19,"b":"violet","g":"blue","f":[157,"green",109,59,"red",74,"red","blue","green"],"i":"orange"},"j":"yellow","c":166,"h":"yellow","b":"yellow","g":["violet",138,["violet",141,"green"]],"f":28,"i":{"e":52,"c":"yellow","a":"green","b":5,"d":{"e":153,"a":"yellow","d":191,"j":"green","c":"green","h":124,"b":"green","g":181,"f":134,"i":"yellow"},"f":193}}},"c":"violet","a":{"a":{"a":"green"},"b":[132]},"b":[{"e":11,"a":"green","d":{"e":{"e":119,"a":"violet","d":"red","c":"red","h":"violet","b":-6,"g":"blue","f":"orange","i":"orange"},"a":183,"d":[-36,"yellow"],"c":"red","h":71,"b":"yellow","g":2,"f":"orange"},"c":"green","h":"yellow","b":29,"g":"green","f":"blue","i":{"e":"yellow","a":-24,"d":[55,125,193,70,60,190,199],"c":"green","h":[49,"yellow","yellow",74,"red",163],"b":198,"g":50,"f":"blue","i":70}},"orange"],"d":"blue"},{"c":{"e":-20,"a":8,"d":["orange",157,152,"green",46,"green",7,89,"violet",[-22,-49,81,127]],"c":35,"h":["blue","yellow","orange",94,"orange","yellow"],"b":"red","g":{"a":"green","b":["yellow","orange",198]},"f":"violet","i":17},"a":-48,"b":"blue"}],"b":[[149,[{"e":"blue","c":-30,"a":"violet","g":"violet","b":"yellow","d":178,"f":-4}],"orange",131,"yellow",{"a":"red","b":"violet"},"blue"],[11],{"e":[35,118,{"e":39,"a":"yellow","d":[119,"orange",120,-43],"j":"violet","c":"orange","h":"blue","b":-32,"g":[{"e":"green","c":106,"a":144,"b":147,"d":"green"},"violet","orange"],"f":116,"i":"orange"},112,"yellow"],"a":{"e":19,"a":"orange","d":61,"c":"red","h":"blue","b":164,"g":{"c":"red","a":-10,"b":{"e":{"e":"green","c":82,"a":103,"g":67,"b":153,"d":"violet","f":22},"c":-22,"a":101,"b":71,"d":{"a":152,"b":"green"},"f":"orange"}},"f":157,"i":{"e":"green","a":"orange","d":-8,"j":[159,73,182,"red","green"],"c":13,"h":"blue","b":"yellow","g":186,"f":"orange","i":81}},"d":13,"c":[186,["yellow",["violet","violet"],"green",-28],54,["blue",[119,"red",119,91,181],117],-15,190,{"c":"red","a":13,"b":[{"c":"green","a":70,"b":8,"d":175},"orange","green","yellow","green"]},"blue",-43],"h":{"e":[{"a":"green"},88,"red","violet",10],"a":{"a":"orange","b":[62,"yellow","green"]},"d":151,"c":"red","h":"orange","b":126,"g":{"a":"orange"},"f":"orange","i":46},"b":[[-2,"violet","violet","red",{"a":192},"green",122],["orange","red",{"c":62,"a":52,"b":-45},{"e":{"a":"violet","b":-45},"a":"red","d":"orange","c":"yellow","h":{"e":67,"c":-27,"a":116,"b":"violet","d":"green","f":-18},"b":"yellow","g":"blue","f":"blue"},27,{"c":37,"a":-39,"b":"blue"}],107,"yellow",["blue","red",143],"blue",{"e":"orange","a":["yellow",["blue",8,149,141,"red",-28,"red"],18],"d":29,"c":"violet","h":-21,"b":[{"e":66,"c":"green","a":"blue","b":-29,"d":"orange","f":"violet"},"blue",-21],"g":"green","f":112},73],"g":["red",{"a":{"e":93,"a":13,"d":"violet","c":175,"h":158,"b":9,"g":194,"f":-10},"b":"blue"}],"f":130}],"g":[["red","orange","orange",172,154,{"e":{"a":"blue","b":{"a":"yellow","b":53}},"c":-11,"a":"orange","g":"yellow","b":{"e":{"e":94,"a":123,"d":184,"j":-4,"c":193,"h":152,"b":"blue","g":"red","f":101,"i":178},"c":"blue","a":178,"b":154,"d":[103,109,190,"yellow",29,"red","orange","yellow",79,"green"],"f":"orange"},"d":{"e":25,"a":{"a":"blue"},"d":"green","c":"orange","h":{"e":144,"c":["red","blue","violet",15,"green",109,72],"a":"yellow","b":"orange","d":"yellow"},"b":151,"g":[141,"orange",134,"blue","blue",4,21,"blue","green"],"f":96},"f":"blue"},"blue"],80,186,[[194,"violet",70,"green"],{"a":"orange","b":"green"},[{"e":"orange","a":179,"d":{"e":164,"c":-14,"a":"blue","g":"yellow","b":"violet","d":76,"f":-33},"c":"green","h":"violet","b":"orange","g":"blue","f":"orange","i":"green"},"blue"]],"orange","yellow",66],"f":{"a":["violet"],"b":87},"i":{"e":{"c":[{"e":"red","a":19,"d":100,"j":"red","c":"red","h":"red","b":"yellow","g":-41,"f":10,"i":"blue"},42,92,"violet","red",[149,"green",91,"blue"],-33,["green",73,129],110,{"e":168,"c":153,"a":-30,"b":"yellow","d":[192,{"c":"blue","a":"blue","b":-16,"d":-18},{"e":"red","c":"yellow","a":"violet","b":31,"d":"green"},"blue"],"f":{"c":9,"a":"yellow","b":-16,"d":128}}],"a":[[["green","violet",136,59,"orange",173,116,113,"yellow"],"green",{"e":"blue","c":"green","a":"blue","g":"red","b":98,"d":-25,"f":21},"orange",184],4,"yellow","red",-24,{"c":"orange","a":15,"b":{"e":109,"c":179,"a":61,"b":"orange","d":190,"f":9}}],"b":[[92,148,{"e":"blue","a":0,"d":108,"c":197,"h":"red","b":"orange","g":-22,"f":105,"i":"blue"},"blue"],-7,149]},"a":{"e":{"a":{"e":"green","a":["violet",172],"d":-10,"c":42,"h":"blue","b":80,"g":{"e":"red","c":"orange","a":"yellow","g":87,"b":{"e":31,"c":129,"a":"orange","b":43,"d":"blue"},"d":"blue","f":81},"f":"violet"},"b":"orange"},"a":182,"d":{"c":{"a":154},"a":"blue","b":{"e":31,"a":["yellow","blue","red",{"a":"orange"},"red",62,39,"red",["green","orange","yellow",47,"orange",55,"blue"]],"d":[72,187,"red","orange",59,"yellow","violet","green"],"j":"orange","c":"yellow","h":185,"b":{"e":"blue","c":"violet","a":["orange",7,180,150,46,"yellow",176,"orange"],"b":148,"d":"blue"},"g":"blue","f":"yellow","i":102}},"c":"red","h":-9,"b":14,"g":{"a":"green","b":{"c":-18,"a":81,"b":104}},"f":[[{"e":-33,"c":"green","a":"orange","b":"blue","d":"blue"},"yellow",141,[42,197],[-12,61,{"e":"violet","a":"violet","d":"green","c":-21,"h":-5,"b":"orange","g":39,"f":"green"},"blue"],31,[[101,"blue",-14,"red",88],58,["red","blue","violet",34],-14,"yellow",98,106,91,131],"yellow",[151,"red","green",{"e":"violet","c":"green","a":49,"g":155,"b":96,"d":"blue","f":"orange"},-18,184,{"c":"blue","a":1,"b":162},{"e":115,"a":94,"d":97,"j":-34,"c":"blue","h":115,"b":"red","g":"orange","f":149,"i":105}],38],{"c":{"e":"blue","c":90,"a":"yellow","b":142,"d":"violet"},"a":-38,"b":"violet"}],"i":189},"d":"orange","c":[[103,8,"green",13,23,"violet",55],[{"e":79,"c":74,"a":{"e":"violet","a":{"c":"red","a":"violet","b":168},"d":142,"j":"blue","c":173,"h":"yellow","b":"green","g":"blue","f":"blue","i":"blue"},"g":[{"c":"violet","a":82,"b":90},-24,{"a":"orange"},"yellow",[126,53,153,6],52,137,"violet",181],"b":105,"d":166,"f":{"e":"blue","c":-35,"a":"blue","b":188,"d":-14,"f":63}},{"e":95,"a":"green","d":"yellow","j":"red","c":81,"h":107,"b":-46,"g":162,"f":"green","i":"red"},[{"e":"violet","a":150,"d":126,"c":10,"h":{"e":"green","a":"orange","d":19,"c":"green","h":"green","b":79,"g":"red","f":"yellow","i":"blue"},"b":{"a":25,"b":147},"g":180,"f":126},{"e":-48,"a":192,"d":-45,"c":25,"h":"green","b":{"c":165,"a":"orange","b":"red","d":"blue"},"g":"green","f":-24},95,{"e":"blue","a":"violet","d":"yellow","j":"blue","c":44,"h":["blue","green","red",142,"red"],"b":[-43,"violet","green",53],"g":33,"f":"orange","i":196},"orange","green",43,[113,"violet","orange",129,{"c":6,"a":"violet","b":"green","d":"green"},20]],"green"]],"h":{"a":-11},"b":{"e":"violet","c":174,"a":"violet","g":[{"e":105,"a":{"c":-5,"a":177,"b":63},"d":-41,"c":80,"h":[110,109,113,"blue"],"b":-28,"g":"red","f":129},["green",[108],{"a":4},[182,96,29,[181,14,"yellow","violet"],13,{"e":132,"a":115,"d":"red","c":"violet","h":"violet","b":"violet","g":"green","f":"green"},{"e":"orange","a":"yellow","d":"blue","j":"red","c":137,"h":"violet","b":"green","g":-22,"f":"yellow","i":-12},"green","yellow",57],-44,{"a":88,"b":-3},22,{"c":"red","a":"violet","b":-21}],[[14,"orange"]],-36,128,"yellow",[-47,[-7,36,177],"blue","blue",["yellow","violet",-23,"violet",-40,"orange",{"e":129,"a":21,"d":51,"j":"violet","c":"red","h":15,"b":174,"g":191,"f":101,"i":105}],23,[-47,[133,66,"violet"],177,"violet","yellow","green",159,"yellow"]],{"e":[{"a":"orange"},"green",69,"orange",43,"violet","violet",192,140,"green"],"a":62,"d":"violet","j":{"c":"violet","a":-25,"b":"violet"},"c":120,"h":"red","b":{"a":13},"g":"green","f":124,"i":33},[[19,176,174,"orange","violet","violet",105,128,"red"],{"a":10,"b":"red"},["orange",37,187,"green",176],"blue","red",[153,"yellow","violet",137,"orange","blue",[70,"red",174,"blue","green","yellow",99,"red"],"violet","violet","red"]]],"b":[{"c":133,"a":"orange","b":98,"d":{"c":"red","a":-9,"b":103}},"blue",[155,"yellow"],[["yellow",-8,{"e":"blue","c":59,"a":71,"g":"orange","b":88,"d":"orange","f":17},"blue",-37],{"e":82,"c":"violet","a":99,"b":81,"d":"yellow","f":161},"blue",{"c":-7,"a":154,"b":"violet"},-9,-13,53,{"e":"violet","a":"yellow","d":-26,"c":179,"h":"green","b":"red","g":-24,"f":133,"i":-36}]],"d":{"e":[9,[49],28,"red",{"c":23,"a":157,"b":{"c":"violet","a":"green","b":-11,"d":"green"},"d":139},"orange","green",93,44,[-19]],"a":-6,"d":7,"c":{"e":{"c":"violet","a":-21,"b":12},"c":["green",[-23,-40,157],"red",["orange","blue"],"violet","red",85,"violet","yellow",150],"a":162,"g":"yellow","b":"green","d":["green","yellow",181,"green",-2,{"e":"red","a":"yellow","d":129,"c":-34,"h":129,"b":152,"g":"yellow","f":80,"i":"red"},"green","red",-9,"red"],"f":6},"h":{"e":136,"a":"violet","d":["violet",-15,129,"green",5,"green",[-28,156,141,"blue",22,"green",34],"green"],"c":149,"h":["violet"],"b":149,"g":"green","f":149},"b":{"e":123,"a":"red","d":{"e":0,"c":"green","a":"violet","b":"yellow","d":"red","f":"green"},"c":{"e":{"e":"yellow","c":"red","a":"red","b":"violet","d":"yellow"},"a":"yellow","d":{"e":-39,"a":-11,"d":63,"c":179,"h":4,"b":44,"g":"orange","f":"violet","i":"yellow"},"c":-43,"h":"green","b":"violet","g":"blue","f":"yellow","i":124},"h":48,"b":129,"g":["orange",147,174,"blue","green",115],"f":172,"i":-36},"g":"red","f":30,"i":"violet"},"f":"red"},"g":{"e":{"e":[[126,"orange",196,"orange","red",{"e":23,"a":"yellow","d":128,"c":12,"h":-49,"b":"green","g":"yellow","f":41,"i":45},"red","violet"]],"c":[["red",103,{"e":69,"a":"violet","d":"yellow","c":"green","h":"red","b":133,"g":25,"f":"violet"}],88,"green","red",-29,"red"],"a":37,"b":"green","d":{"e":"orange","c":{"e":{"e":109,"c":144,"a":"yellow","b":70,"d":83},"c":-3,"a":"green","b":"yellow","d":146},"a":86,"b":-1,"d":{"a":68}}},"c":{"c":[155,18,"blue",-16,"orange",-36,49,"red",["yellow",136,140,-10,11,"violet","red",134,156,"violet"]],"a":64,"b":{"e":"violet","c":193,"a":101,"b":["green"],"d":182,"f":86},"d":[198]},"a":"yellow","g":"violet","b":1,"d":-27,"f":"orange"},"f":{"e":20,"c":{"e":155,"c":{"c":[181,{"e":-32,"a":"orange","d":"orange","j":"yellow","c":66,"h":-39,"b":"violet","g":"violet","f":"red","i":23},4,"blue",70,"violet","blue",141,{"a":"yellow","b":184},"violet"],"a":160,"b":158,"d":197},"a":138,"g":[48],"b":26,"d":11,"f":{"c":"yellow","a":179,"b":"red","d":90}},"a":148,"g":"yellow","b":[[{"a":["yellow"]},"yellow",19,"green",39],{"c":{"a":"blue"},"a":{"e":41,"c":191,"a":173,"b":"green","d":-14,"f":19},"b":{"a":["orange",4,48],"b":193},"d":"green"},["yellow",{"e":"orange","a":"orange","d":"blue","c":-39,"h":28,"b":"yellow","g":"red","f":"orange","i":[116,"red",173,76,24,-1,"green",101,-10]},70,{"c":"violet","a":44,"b":"violet","d":36},128,{"c":"yellow","a":"red","b":["yellow",-10]},-10,6]],"d":"violet","f":{"e":"violet","c":5,"a":"violet","g":173,"b":100,"d":["violet",194,{"e":["blue",181,"violet","yellow","blue",-7,137,43,112],"c":-19,"a":120,"b":"green","d":165},-1,195,"green",104],"f":128}}}}
diff --git a/2015/day13.hs b/2015/day13.hs
new file mode 100644
index 0000000..6ffc440
--- /dev/null
+++ b/2015/day13.hs
@@ -0,0 +1,47 @@
+import Data.Maybe
+import Control.Monad
+import qualified Data.Map.Strict as Map
+import Data.Map.Strict ((!))
+
+includeSelf :: Bool
+includeSelf = True
+
+getnames :: [String] -> Map.Map String Int
+getnames [] = Map.empty
+getnames (l:ls) = Map.insert (head (words l)) (Map.size n) n
+ where n = getnames ls
+
+parse :: [String] -> Map.Map String Int -> Map.Map (Int,Int) Int
+parse [] names = Map.empty
+parse (l:ls) names = Map.insert (a,b) h $ parse ls names
+ where w = words l
+ an = head w
+ bn = init $ last w
+ a = names ! an
+ b = names ! bn
+ neg = w!!2 == "lose"
+ hp = read $ w!!3
+ h = if neg then -hp else hp
+
+permutations :: [a] -> [[a]]
+permutations [] = []
+permutations [v] = [[v]]
+permutations a = concat [map ((a!!i):) $ permutations $ take i a ++ drop (i + 1) a | i <- [0..(length a - 1)]]
+
+compute :: [Int] -> Map.Map (Int,Int) Int -> Int
+compute [] _ = 0
+compute [_] _ = 0
+compute l hm = fst $ foldl (\(acc,prev) i -> (acc + hm ! (prev,i) + hm ! (i,prev),i)) (0,last l) l
+
+addSelf :: Int -> Map.Map (Int,Int) Int -> Map.Map (Int,Int) Int
+addSelf n m = foldl (\mp i -> Map.insert (0,i) 0 $ Map.insert (i,0) 0 mp) m [1..n]
+
+day13 :: IO ()
+day13 = do
+ input <- liftM lines $ readFile "day13.txt"
+ let names = getnames input
+ let hapmap = if includeSelf then addSelf (length names) parsed else parsed where parsed = parse input names
+ let perm = permutations [(if includeSelf then 0 else 1)..(length names)]
+ print $ maximum [compute p hapmap | p <- perm]
+
+main = day13
diff --git a/2015/day13.txt b/2015/day13.txt
new file mode 100644
index 0000000..83755b0
--- /dev/null
+++ b/2015/day13.txt
@@ -0,0 +1,56 @@
+Alice would lose 57 happiness units by sitting next to Bob.
+Alice would lose 62 happiness units by sitting next to Carol.
+Alice would lose 75 happiness units by sitting next to David.
+Alice would gain 71 happiness units by sitting next to Eric.
+Alice would lose 22 happiness units by sitting next to Frank.
+Alice would lose 23 happiness units by sitting next to George.
+Alice would lose 76 happiness units by sitting next to Mallory.
+Bob would lose 14 happiness units by sitting next to Alice.
+Bob would gain 48 happiness units by sitting next to Carol.
+Bob would gain 89 happiness units by sitting next to David.
+Bob would gain 86 happiness units by sitting next to Eric.
+Bob would lose 2 happiness units by sitting next to Frank.
+Bob would gain 27 happiness units by sitting next to George.
+Bob would gain 19 happiness units by sitting next to Mallory.
+Carol would gain 37 happiness units by sitting next to Alice.
+Carol would gain 45 happiness units by sitting next to Bob.
+Carol would gain 24 happiness units by sitting next to David.
+Carol would gain 5 happiness units by sitting next to Eric.
+Carol would lose 68 happiness units by sitting next to Frank.
+Carol would lose 25 happiness units by sitting next to George.
+Carol would gain 30 happiness units by sitting next to Mallory.
+David would lose 51 happiness units by sitting next to Alice.
+David would gain 34 happiness units by sitting next to Bob.
+David would gain 99 happiness units by sitting next to Carol.
+David would gain 91 happiness units by sitting next to Eric.
+David would lose 38 happiness units by sitting next to Frank.
+David would gain 60 happiness units by sitting next to George.
+David would lose 63 happiness units by sitting next to Mallory.
+Eric would gain 23 happiness units by sitting next to Alice.
+Eric would lose 69 happiness units by sitting next to Bob.
+Eric would lose 33 happiness units by sitting next to Carol.
+Eric would lose 47 happiness units by sitting next to David.
+Eric would gain 75 happiness units by sitting next to Frank.
+Eric would gain 82 happiness units by sitting next to George.
+Eric would gain 13 happiness units by sitting next to Mallory.
+Frank would gain 77 happiness units by sitting next to Alice.
+Frank would gain 27 happiness units by sitting next to Bob.
+Frank would lose 87 happiness units by sitting next to Carol.
+Frank would gain 74 happiness units by sitting next to David.
+Frank would lose 41 happiness units by sitting next to Eric.
+Frank would lose 99 happiness units by sitting next to George.
+Frank would gain 26 happiness units by sitting next to Mallory.
+George would lose 63 happiness units by sitting next to Alice.
+George would lose 51 happiness units by sitting next to Bob.
+George would lose 60 happiness units by sitting next to Carol.
+George would gain 30 happiness units by sitting next to David.
+George would lose 100 happiness units by sitting next to Eric.
+George would lose 63 happiness units by sitting next to Frank.
+George would gain 57 happiness units by sitting next to Mallory.
+Mallory would lose 71 happiness units by sitting next to Alice.
+Mallory would lose 28 happiness units by sitting next to Bob.
+Mallory would lose 10 happiness units by sitting next to Carol.
+Mallory would gain 44 happiness units by sitting next to David.
+Mallory would gain 22 happiness units by sitting next to Eric.
+Mallory would gain 79 happiness units by sitting next to Frank.
+Mallory would lose 16 happiness units by sitting next to George.
diff --git a/2015/day14.hs b/2015/day14.hs
new file mode 100644
index 0000000..8b9aca2
--- /dev/null
+++ b/2015/day14.hs
@@ -0,0 +1,42 @@
+data Reindeer = Reindeer {speed :: Int, speedduration :: Int, resttime :: Int} deriving (Show)
+
+data Status = Status {spedfor :: Int, restedfor :: Int, travelled :: Int, points :: Int} deriving (Show)
+
+parse :: String -> Reindeer
+parse l = Reindeer s d r
+ where w = words l
+ s = read $ w !! 3
+ d = read $ w !! 6
+ r = read $ w !! 13
+
+simulate :: Int -> [Reindeer] -> [Status]
+simulate 0 r = replicate (length r) $ Status 0 0 0 0
+simulate n r = updatepoints $ map update $ zip r $ simulate (n-1) r
+ where update (rein,stat) = if spe > 0 && spe < spemax
+ then Status (spe+1) 0 (dis+speed rein) pts
+ else if spe == spemax
+ then Status 0 1 dis pts
+ else if res > 0 && res < resmax
+ then Status 0 (res+1) dis pts
+ else Status 1 res (dis+speed rein) pts
+ where spe = spedfor stat
+ res = restedfor stat
+ dis = travelled stat
+ pts = points stat
+ spemax = speedduration rein
+ resmax = resttime rein
+ updatepoints stats = [if travelled s == maxtrav
+ then Status (spedfor s) (restedfor s) (travelled s) (points s + 1)
+ else s
+ | s <- stats]
+ where maxtrav = maximum $ map travelled stats
+
+day14 :: IO ()
+day14 = do
+ input <- readFile "day14.txt"
+ let inputl = lines input
+ let rein = map parse inputl
+ let result = simulate 2503 rein
+ print $ maximum $ map points result -- part 1: map travelled; part 2: map points
+
+main = day14
diff --git a/2015/day14.txt b/2015/day14.txt
new file mode 100644
index 0000000..2af1170
--- /dev/null
+++ b/2015/day14.txt
@@ -0,0 +1,9 @@
+Vixen can fly 19 km/s for 7 seconds, but then must rest for 124 seconds.
+Rudolph can fly 3 km/s for 15 seconds, but then must rest for 28 seconds.
+Donner can fly 19 km/s for 9 seconds, but then must rest for 164 seconds.
+Blitzen can fly 19 km/s for 9 seconds, but then must rest for 158 seconds.
+Comet can fly 13 km/s for 7 seconds, but then must rest for 82 seconds.
+Cupid can fly 25 km/s for 6 seconds, but then must rest for 145 seconds.
+Dasher can fly 14 km/s for 3 seconds, but then must rest for 38 seconds.
+Dancer can fly 3 km/s for 16 seconds, but then must rest for 37 seconds.
+Prancer can fly 25 km/s for 6 seconds, but then must rest for 143 seconds.
diff --git a/2015/day15.hs b/2015/day15.hs
new file mode 100644
index 0000000..8787c9c
--- /dev/null
+++ b/2015/day15.hs
@@ -0,0 +1,30 @@
+import Data.Char
+import Control.Monad
+
+total :: Int
+total = 100
+
+isDigitOrMinus :: Char -> Bool
+isDigitOrMinus c = isDigit c || c == '-'
+
+parse :: [String] -> [Int]
+parse [_,_,a,_,b,_,c,_,d,_,e] = map (read . takeWhile isDigitOrMinus) [a,b,c,d,e]
+
+getall :: [[Int]] -> [Int]
+getall ing = map fst $ filter cal500 $ map computescore $ allcomb ing
+ where allcomb ing = allcomb' ing 0
+ allcomb' [] tot = if tot == total then [[0,0,0,0,0]] else []
+ allcomb' (i:is) tot = concat [map (\x -> map (\(a,b)->am*a+b) $ zip i x) $ allcomb' is (tot+am)
+ | am <- [0..(total-tot)]]
+ computescore x = (product $ map (\x -> if x < 0 then 0 else x) $ init x,last x)
+ cal500 (_,cal) = cal == 500 -- make this function always True for part 1
+
+day15 :: IO ()
+day15 = do
+ input <- liftM (map (parse . words) . lines) $ readFile "day15.txt"
+ --let input = [[-1,-2,6,3],[2,3,-2,-1]]
+ print input
+ let result = maximum $ getall input
+ print result
+
+main = day15
diff --git a/2015/day15.txt b/2015/day15.txt
new file mode 100644
index 0000000..d1af06e
--- /dev/null
+++ b/2015/day15.txt
@@ -0,0 +1,4 @@
+Sugar: capacity 3, durability 0, flavor 0, texture -3, calories 2
+Sprinkles: capacity -3, durability 3, flavor 0, texture 0, calories 9
+Candy: capacity -1, durability 0, flavor 4, texture 0, calories 1
+Chocolate: capacity 0, durability 0, flavor -2, texture 2, calories 8
diff --git a/2015/day16.hs b/2015/day16.hs
new file mode 100644
index 0000000..a18fce1
--- /dev/null
+++ b/2015/day16.hs
@@ -0,0 +1,36 @@
+import Data.Char
+import Data.List
+import Control.Monad
+import qualified Data.Map.Strict as Map
+import Data.Map.Strict ((!))
+
+realSue :: Map.Map String (Int -> Bool)
+realSue = Map.fromList [ -- for part 1, make all functions equalities
+ ("children", (==3)),
+ ("cats", (>7)),
+ ("samoyeds", (==2)),
+ ("pomeranians",(<3)),
+ ("akitas", (==0)),
+ ("vizslas", (==0)),
+ ("goldfish", (<5)),
+ ("trees", (>3)),
+ ("cars", (==2)),
+ ("perfumes", (==1))]
+
+parse :: String -> [(String,Int)]
+parse s = parse' $ drop 2 $ words s
+
+parse' :: [String] -> [(String,Int)]
+parse' [] = []
+parse' (k:v:xs) = (init k,read $ takeWhile isDigit v) : parse' xs
+
+matches :: [(String,Int)] -> Map.Map String (Int -> Bool) -> Bool
+matches [] _ = True
+matches ((k,v):atts) map = (map ! k) v && matches atts map
+
+day16 :: IO ()
+day16 = do
+ input <- liftM (zip [1..] . map parse . lines) $ readFile "day16.txt"
+ sequence_ $ map (print . fst) $ filter (\(i,atts) -> matches atts realSue) input
+
+main = day16
diff --git a/2015/day16.txt b/2015/day16.txt
new file mode 100644
index 0000000..b1bd498
--- /dev/null
+++ b/2015/day16.txt
@@ -0,0 +1,500 @@
+Sue 1: children: 1, cars: 8, vizslas: 7
+Sue 2: akitas: 10, perfumes: 10, children: 5
+Sue 3: cars: 5, pomeranians: 4, vizslas: 1
+Sue 4: goldfish: 5, children: 8, perfumes: 3
+Sue 5: vizslas: 2, akitas: 7, perfumes: 6
+Sue 6: vizslas: 0, akitas: 1, perfumes: 2
+Sue 7: perfumes: 8, cars: 4, goldfish: 10
+Sue 8: perfumes: 7, children: 2, cats: 1
+Sue 9: pomeranians: 3, goldfish: 10, trees: 10
+Sue 10: akitas: 7, trees: 8, pomeranians: 4
+Sue 11: goldfish: 1, perfumes: 4, cars: 6
+Sue 12: samoyeds: 6, trees: 6, perfumes: 2
+Sue 13: akitas: 10, pomeranians: 0, vizslas: 2
+Sue 14: cars: 2, perfumes: 3, children: 4
+Sue 15: goldfish: 2, children: 8, cars: 5
+Sue 16: goldfish: 9, cars: 0, vizslas: 5
+Sue 17: cats: 5, trees: 6, perfumes: 6
+Sue 18: cars: 0, perfumes: 8, pomeranians: 7
+Sue 19: trees: 2, goldfish: 5, perfumes: 4
+Sue 20: akitas: 4, vizslas: 4, trees: 0
+Sue 21: pomeranians: 7, trees: 0, goldfish: 10
+Sue 22: cars: 4, vizslas: 0, perfumes: 3
+Sue 23: vizslas: 8, trees: 1, akitas: 2
+Sue 24: children: 7, trees: 0, akitas: 1
+Sue 25: goldfish: 3, akitas: 2, trees: 2
+Sue 26: pomeranians: 4, vizslas: 4, samoyeds: 2
+Sue 27: cars: 0, trees: 8, akitas: 5
+Sue 28: perfumes: 6, cats: 0, cars: 2
+Sue 29: trees: 7, akitas: 1, vizslas: 1
+Sue 30: perfumes: 9, cars: 9, trees: 10
+Sue 31: pomeranians: 5, akitas: 9, samoyeds: 1
+Sue 32: pomeranians: 10, vizslas: 5, goldfish: 5
+Sue 33: vizslas: 2, akitas: 3, trees: 7
+Sue 34: goldfish: 10, perfumes: 0, samoyeds: 7
+Sue 35: akitas: 6, cats: 7, perfumes: 10
+Sue 36: pomeranians: 8, vizslas: 7, akitas: 6
+Sue 37: goldfish: 2, cars: 10, children: 7
+Sue 38: goldfish: 2, perfumes: 3, cars: 7
+Sue 39: trees: 9, vizslas: 10, cars: 5
+Sue 40: goldfish: 1, pomeranians: 0, trees: 2
+Sue 41: trees: 2, goldfish: 6, vizslas: 3
+Sue 42: akitas: 1, cars: 3, vizslas: 3
+Sue 43: akitas: 1, pomeranians: 1, vizslas: 3
+Sue 44: goldfish: 7, akitas: 3, vizslas: 10
+Sue 45: akitas: 8, samoyeds: 8, goldfish: 2
+Sue 46: trees: 0, vizslas: 4, cars: 9
+Sue 47: cars: 9, trees: 10, perfumes: 4
+Sue 48: akitas: 0, vizslas: 5, perfumes: 4
+Sue 49: goldfish: 9, trees: 1, cars: 4
+Sue 50: goldfish: 2, perfumes: 5, cars: 2
+Sue 51: samoyeds: 1, goldfish: 2, perfumes: 7
+Sue 52: cars: 0, perfumes: 4, goldfish: 8
+Sue 53: goldfish: 9, vizslas: 2, akitas: 9
+Sue 54: trees: 1, goldfish: 9, children: 5
+Sue 55: cars: 0, akitas: 5, trees: 4
+Sue 56: trees: 4, samoyeds: 5, children: 9
+Sue 57: children: 0, vizslas: 8, cars: 3
+Sue 58: trees: 4, pomeranians: 5, akitas: 5
+Sue 59: vizslas: 10, cats: 3, children: 2
+Sue 60: cats: 6, vizslas: 2, cars: 2
+Sue 61: akitas: 1, vizslas: 0, children: 4
+Sue 62: akitas: 4, trees: 9, children: 10
+Sue 63: pomeranians: 6, vizslas: 6, cars: 4
+Sue 64: perfumes: 8, pomeranians: 1, children: 8
+Sue 65: perfumes: 3, goldfish: 6, trees: 5
+Sue 66: goldfish: 10, akitas: 8, vizslas: 4
+Sue 67: vizslas: 10, samoyeds: 3, trees: 2
+Sue 68: samoyeds: 4, cars: 7, perfumes: 3
+Sue 69: perfumes: 2, goldfish: 0, trees: 2
+Sue 70: trees: 8, vizslas: 7, akitas: 6
+Sue 71: cars: 2, children: 7, perfumes: 3
+Sue 72: cars: 1, akitas: 9, perfumes: 0
+Sue 73: vizslas: 4, akitas: 7, cars: 5
+Sue 74: samoyeds: 3, cars: 3, akitas: 2
+Sue 75: trees: 2, cars: 1, vizslas: 7
+Sue 76: samoyeds: 9, perfumes: 1, trees: 6
+Sue 77: trees: 6, perfumes: 10, cars: 7
+Sue 78: trees: 0, children: 8, vizslas: 5
+Sue 79: vizslas: 0, trees: 0, samoyeds: 1
+Sue 80: trees: 6, goldfish: 8, perfumes: 0
+Sue 81: samoyeds: 8, pomeranians: 6, akitas: 5
+Sue 82: vizslas: 6, perfumes: 9, akitas: 4
+Sue 83: cats: 0, vizslas: 3, pomeranians: 10
+Sue 84: cars: 4, perfumes: 6, samoyeds: 5
+Sue 85: vizslas: 7, trees: 5, goldfish: 7
+Sue 86: goldfish: 2, trees: 2, vizslas: 1
+Sue 87: trees: 6, goldfish: 10, pomeranians: 4
+Sue 88: vizslas: 1, akitas: 0, perfumes: 8
+Sue 89: goldfish: 8, akitas: 3, vizslas: 7
+Sue 90: vizslas: 9, akitas: 7, perfumes: 9
+Sue 91: children: 7, cars: 7, trees: 9
+Sue 92: vizslas: 10, akitas: 8, goldfish: 1
+Sue 93: goldfish: 7, vizslas: 2, pomeranians: 0
+Sue 94: cats: 2, samoyeds: 6, pomeranians: 3
+Sue 95: samoyeds: 4, children: 4, pomeranians: 10
+Sue 96: pomeranians: 9, cats: 1, goldfish: 3
+Sue 97: trees: 1, akitas: 6, goldfish: 1
+Sue 98: vizslas: 7, akitas: 2, perfumes: 7
+Sue 99: pomeranians: 6, perfumes: 2, trees: 1
+Sue 100: cars: 3, children: 9, trees: 10
+Sue 101: children: 0, perfumes: 0, vizslas: 3
+Sue 102: cars: 4, goldfish: 5, children: 2
+Sue 103: pomeranians: 3, perfumes: 7, cats: 8
+Sue 104: akitas: 0, perfumes: 5, vizslas: 5
+Sue 105: akitas: 7, vizslas: 2, samoyeds: 8
+Sue 106: goldfish: 7, perfumes: 0, cats: 8
+Sue 107: cats: 6, pomeranians: 9, cars: 6
+Sue 108: akitas: 3, vizslas: 10, cats: 5
+Sue 109: akitas: 10, perfumes: 2, cars: 7
+Sue 110: goldfish: 7, pomeranians: 1, trees: 1
+Sue 111: akitas: 10, samoyeds: 6, vizslas: 6
+Sue 112: cats: 6, akitas: 7, trees: 9
+Sue 113: akitas: 1, trees: 9, vizslas: 8
+Sue 114: vizslas: 2, cats: 1, cars: 4
+Sue 115: akitas: 0, trees: 5, goldfish: 7
+Sue 116: goldfish: 2, trees: 10, akitas: 2
+Sue 117: cars: 4, goldfish: 10, perfumes: 5
+Sue 118: cars: 5, perfumes: 6, trees: 0
+Sue 119: perfumes: 5, vizslas: 1, cats: 0
+Sue 120: perfumes: 8, akitas: 9, vizslas: 4
+Sue 121: samoyeds: 2, vizslas: 7, perfumes: 6
+Sue 122: children: 6, trees: 9, perfumes: 2
+Sue 123: cars: 7, akitas: 0, pomeranians: 0
+Sue 124: akitas: 7, cats: 8, vizslas: 5
+Sue 125: goldfish: 3, trees: 1, cars: 4
+Sue 126: cars: 4, perfumes: 3, akitas: 0
+Sue 127: children: 10, vizslas: 5, akitas: 9
+Sue 128: akitas: 3, samoyeds: 2, cats: 8
+Sue 129: cats: 8, akitas: 1, vizslas: 8
+Sue 130: trees: 4, cars: 6, perfumes: 6
+Sue 131: akitas: 7, perfumes: 6, goldfish: 9
+Sue 132: akitas: 6, vizslas: 7, trees: 1
+Sue 133: akitas: 5, vizslas: 7, children: 9
+Sue 134: cars: 8, goldfish: 4, pomeranians: 4
+Sue 135: samoyeds: 1, pomeranians: 6, akitas: 4
+Sue 136: perfumes: 10, goldfish: 1, cars: 3
+Sue 137: cars: 3, samoyeds: 6, vizslas: 7
+Sue 138: samoyeds: 10, akitas: 3, perfumes: 4
+Sue 139: perfumes: 10, vizslas: 2, goldfish: 7
+Sue 140: samoyeds: 7, cars: 1, trees: 2
+Sue 141: children: 6, cats: 5, cars: 9
+Sue 142: cats: 0, trees: 1, akitas: 10
+Sue 143: samoyeds: 4, cars: 0, children: 7
+Sue 144: trees: 0, cars: 4, perfumes: 8
+Sue 145: goldfish: 7, cars: 5, trees: 1
+Sue 146: perfumes: 7, cars: 7, goldfish: 0
+Sue 147: trees: 2, goldfish: 7, vizslas: 5
+Sue 148: samoyeds: 8, perfumes: 1, trees: 0
+Sue 149: vizslas: 2, samoyeds: 5, trees: 0
+Sue 150: akitas: 4, perfumes: 4, pomeranians: 2
+Sue 151: trees: 2, cars: 0, goldfish: 10
+Sue 152: goldfish: 7, vizslas: 0, trees: 0
+Sue 153: children: 9, cats: 0, pomeranians: 10
+Sue 154: cars: 6, goldfish: 10, akitas: 5
+Sue 155: perfumes: 9, trees: 2, akitas: 3
+Sue 156: pomeranians: 9, perfumes: 5, cars: 9
+Sue 157: akitas: 0, trees: 2, cars: 7
+Sue 158: goldfish: 10, trees: 8, akitas: 7
+Sue 159: akitas: 5, trees: 10, cars: 10
+Sue 160: akitas: 3, trees: 5, cars: 8
+Sue 161: samoyeds: 2, cars: 7, perfumes: 4
+Sue 162: cars: 6, vizslas: 10, pomeranians: 5
+Sue 163: cars: 10, perfumes: 6, vizslas: 9
+Sue 164: pomeranians: 7, cars: 4, vizslas: 2
+Sue 165: goldfish: 9, vizslas: 3, trees: 1
+Sue 166: goldfish: 1, samoyeds: 3, trees: 1
+Sue 167: vizslas: 4, goldfish: 7, cats: 5
+Sue 168: children: 1, cars: 5, samoyeds: 7
+Sue 169: trees: 1, samoyeds: 3, goldfish: 6
+Sue 170: goldfish: 2, cars: 3, perfumes: 9
+Sue 171: cars: 4, goldfish: 0, trees: 6
+Sue 172: cats: 8, perfumes: 6, trees: 1
+Sue 173: akitas: 9, goldfish: 7, cars: 10
+Sue 174: vizslas: 2, trees: 0, akitas: 1
+Sue 175: perfumes: 3, vizslas: 8, akitas: 4
+Sue 176: perfumes: 0, akitas: 6, goldfish: 3
+Sue 177: perfumes: 6, children: 1, goldfish: 10
+Sue 178: cars: 5, vizslas: 3, children: 10
+Sue 179: perfumes: 3, trees: 8, cats: 9
+Sue 180: perfumes: 8, vizslas: 4, trees: 7
+Sue 181: perfumes: 7, vizslas: 9, samoyeds: 4
+Sue 182: vizslas: 9, trees: 4, pomeranians: 4
+Sue 183: trees: 9, cars: 3, goldfish: 5
+Sue 184: perfumes: 2, cars: 4, vizslas: 3
+Sue 185: children: 10, akitas: 10, cats: 9
+Sue 186: cars: 5, samoyeds: 0, trees: 0
+Sue 187: trees: 2, goldfish: 3, cars: 4
+Sue 188: goldfish: 3, vizslas: 1, cats: 6
+Sue 189: trees: 2, pomeranians: 10, cars: 7
+Sue 190: perfumes: 10, akitas: 3, samoyeds: 0
+Sue 191: cats: 5, vizslas: 6, akitas: 6
+Sue 192: samoyeds: 5, trees: 1, perfumes: 8
+Sue 193: pomeranians: 0, akitas: 9, cats: 0
+Sue 194: trees: 1, goldfish: 0, perfumes: 10
+Sue 195: perfumes: 2, akitas: 7, cars: 5
+Sue 196: perfumes: 5, samoyeds: 8, cars: 1
+Sue 197: vizslas: 2, pomeranians: 9, trees: 1
+Sue 198: trees: 8, vizslas: 6, children: 8
+Sue 199: pomeranians: 4, cars: 7, vizslas: 5
+Sue 200: trees: 0, perfumes: 10, akitas: 10
+Sue 201: cats: 9, akitas: 4, vizslas: 0
+Sue 202: goldfish: 9, pomeranians: 9, cats: 6
+Sue 203: cars: 5, perfumes: 5, trees: 2
+Sue 204: pomeranians: 7, children: 2, akitas: 6
+Sue 205: samoyeds: 7, pomeranians: 7, children: 6
+Sue 206: trees: 1, cars: 1, pomeranians: 4
+Sue 207: goldfish: 2, perfumes: 5, trees: 0
+Sue 208: perfumes: 2, samoyeds: 4, trees: 1
+Sue 209: cars: 8, perfumes: 6, goldfish: 9
+Sue 210: perfumes: 4, cars: 8, samoyeds: 3
+Sue 211: perfumes: 2, cars: 8, trees: 9
+Sue 212: trees: 7, perfumes: 2, akitas: 5
+Sue 213: children: 3, goldfish: 5, vizslas: 0
+Sue 214: akitas: 6, goldfish: 0, children: 0
+Sue 215: trees: 8, akitas: 3, goldfish: 1
+Sue 216: goldfish: 6, perfumes: 8, akitas: 3
+Sue 217: children: 7, trees: 2, vizslas: 6
+Sue 218: goldfish: 8, samoyeds: 4, pomeranians: 6
+Sue 219: goldfish: 8, samoyeds: 0, children: 9
+Sue 220: perfumes: 1, cars: 8, vizslas: 6
+Sue 221: perfumes: 9, cars: 10, children: 10
+Sue 222: perfumes: 9, vizslas: 1, trees: 0
+Sue 223: goldfish: 1, akitas: 2, vizslas: 8
+Sue 224: samoyeds: 8, akitas: 7, vizslas: 4
+Sue 225: goldfish: 1, cars: 4, perfumes: 10
+Sue 226: goldfish: 9, trees: 4, perfumes: 5
+Sue 227: vizslas: 5, trees: 4, goldfish: 7
+Sue 228: cars: 1, cats: 10, perfumes: 4
+Sue 229: vizslas: 8, cars: 10, akitas: 4
+Sue 230: cats: 1, children: 8, vizslas: 3
+Sue 231: perfumes: 7, cats: 6, samoyeds: 7
+Sue 232: cars: 3, children: 9, perfumes: 7
+Sue 233: vizslas: 1, samoyeds: 2, children: 2
+Sue 234: trees: 1, samoyeds: 8, children: 2
+Sue 235: trees: 6, akitas: 9, goldfish: 7
+Sue 236: children: 10, trees: 0, samoyeds: 8
+Sue 237: pomeranians: 4, trees: 1, goldfish: 2
+Sue 238: vizslas: 4, akitas: 2, cars: 0
+Sue 239: goldfish: 9, cars: 10, perfumes: 4
+Sue 240: perfumes: 3, vizslas: 6, trees: 6
+Sue 241: pomeranians: 6, akitas: 4, trees: 2
+Sue 242: cars: 8, perfumes: 5, children: 7
+Sue 243: trees: 4, perfumes: 7, cars: 3
+Sue 244: perfumes: 6, akitas: 1, vizslas: 7
+Sue 245: akitas: 3, perfumes: 9, samoyeds: 0
+Sue 246: pomeranians: 3, vizslas: 9, samoyeds: 1
+Sue 247: cars: 0, goldfish: 7, cats: 2
+Sue 248: trees: 5, goldfish: 6, perfumes: 3
+Sue 249: trees: 0, pomeranians: 7, perfumes: 9
+Sue 250: cars: 9, trees: 1, goldfish: 10
+Sue 251: perfumes: 3, cars: 8, trees: 7
+Sue 252: cars: 5, akitas: 7, trees: 8
+Sue 253: perfumes: 7, akitas: 3, trees: 8
+Sue 254: goldfish: 8, samoyeds: 1, vizslas: 7
+Sue 255: perfumes: 3, cars: 4, children: 6
+Sue 256: perfumes: 9, trees: 8, children: 7
+Sue 257: trees: 8, children: 6, cars: 4
+Sue 258: vizslas: 1, trees: 10, goldfish: 9
+Sue 259: vizslas: 5, trees: 6, goldfish: 9
+Sue 260: trees: 0, goldfish: 6, cars: 7
+Sue 261: cars: 1, perfumes: 4, goldfish: 9
+Sue 262: cars: 7, goldfish: 9, cats: 9
+Sue 263: cars: 0, children: 5, goldfish: 8
+Sue 264: cars: 2, akitas: 8, trees: 0
+Sue 265: perfumes: 9, children: 8, samoyeds: 7
+Sue 266: cats: 1, children: 1, vizslas: 10
+Sue 267: vizslas: 8, children: 2, trees: 6
+Sue 268: akitas: 10, vizslas: 3, cats: 2
+Sue 269: children: 4, goldfish: 1, cats: 6
+Sue 270: vizslas: 5, cars: 9, akitas: 9
+Sue 271: vizslas: 5, children: 4, akitas: 3
+Sue 272: cars: 1, goldfish: 0, vizslas: 0
+Sue 273: goldfish: 10, samoyeds: 1, akitas: 2
+Sue 274: goldfish: 10, children: 2, pomeranians: 0
+Sue 275: children: 0, vizslas: 1, samoyeds: 6
+Sue 276: children: 1, vizslas: 3, samoyeds: 1
+Sue 277: perfumes: 4, cats: 6, children: 10
+Sue 278: pomeranians: 7, goldfish: 3, cars: 4
+Sue 279: perfumes: 5, goldfish: 9, trees: 7
+Sue 280: goldfish: 6, trees: 5, perfumes: 8
+Sue 281: cars: 2, akitas: 1, vizslas: 7
+Sue 282: vizslas: 4, akitas: 3, children: 8
+Sue 283: pomeranians: 8, akitas: 9, vizslas: 4
+Sue 284: samoyeds: 10, trees: 10, pomeranians: 2
+Sue 285: akitas: 9, perfumes: 7, goldfish: 6
+Sue 286: akitas: 2, vizslas: 7, goldfish: 10
+Sue 287: pomeranians: 8, cars: 6, samoyeds: 5
+Sue 288: pomeranians: 1, trees: 0, goldfish: 0
+Sue 289: trees: 10, samoyeds: 1, children: 0
+Sue 290: cats: 10, samoyeds: 6, trees: 0
+Sue 291: vizslas: 9, trees: 6, goldfish: 5
+Sue 292: cats: 4, perfumes: 8, cars: 3
+Sue 293: goldfish: 10, perfumes: 10, cats: 0
+Sue 294: cats: 7, trees: 6, akitas: 4
+Sue 295: vizslas: 8, cars: 1, akitas: 6
+Sue 296: vizslas: 5, akitas: 10, trees: 1
+Sue 297: pomeranians: 8, samoyeds: 5, vizslas: 4
+Sue 298: perfumes: 10, children: 5, vizslas: 2
+Sue 299: cars: 10, akitas: 7, cats: 5
+Sue 300: trees: 1, perfumes: 7, cars: 7
+Sue 301: cars: 9, vizslas: 1, perfumes: 3
+Sue 302: perfumes: 9, vizslas: 1, akitas: 5
+Sue 303: akitas: 9, trees: 1, goldfish: 10
+Sue 304: children: 10, vizslas: 6, pomeranians: 8
+Sue 305: trees: 3, goldfish: 6, cats: 9
+Sue 306: cars: 5, perfumes: 9, vizslas: 5
+Sue 307: children: 0, goldfish: 7, trees: 2
+Sue 308: trees: 9, samoyeds: 4, cars: 0
+Sue 309: cats: 8, vizslas: 2, perfumes: 3
+Sue 310: cars: 6, pomeranians: 6, vizslas: 6
+Sue 311: vizslas: 6, akitas: 7, cats: 10
+Sue 312: trees: 0, goldfish: 7, cars: 0
+Sue 313: perfumes: 5, akitas: 5, cars: 2
+Sue 314: akitas: 10, vizslas: 3, samoyeds: 8
+Sue 315: cars: 3, perfumes: 1, goldfish: 8
+Sue 316: pomeranians: 6, goldfish: 9, perfumes: 1
+Sue 317: goldfish: 4, akitas: 6, cars: 2
+Sue 318: perfumes: 8, vizslas: 8, akitas: 0
+Sue 319: akitas: 10, cars: 5, vizslas: 6
+Sue 320: vizslas: 4, akitas: 3, cats: 4
+Sue 321: goldfish: 4, akitas: 8, cars: 8
+Sue 322: pomeranians: 5, vizslas: 7, cats: 1
+Sue 323: perfumes: 1, trees: 6, goldfish: 0
+Sue 324: goldfish: 6, trees: 10, cars: 10
+Sue 325: akitas: 2, samoyeds: 6, trees: 9
+Sue 326: vizslas: 4, akitas: 7, cars: 9
+Sue 327: children: 3, perfumes: 4, cars: 1
+Sue 328: akitas: 9, perfumes: 6, cars: 10
+Sue 329: perfumes: 2, goldfish: 0, trees: 1
+Sue 330: vizslas: 10, pomeranians: 7, goldfish: 6
+Sue 331: trees: 3, vizslas: 8, cars: 3
+Sue 332: akitas: 2, cats: 1, goldfish: 8
+Sue 333: cars: 6, trees: 2, vizslas: 0
+Sue 334: samoyeds: 7, cars: 7, trees: 3
+Sue 335: cats: 7, children: 1, perfumes: 8
+Sue 336: akitas: 5, goldfish: 10, vizslas: 5
+Sue 337: cats: 3, vizslas: 0, akitas: 10
+Sue 338: perfumes: 8, cars: 1, trees: 8
+Sue 339: cars: 4, samoyeds: 8, children: 2
+Sue 340: goldfish: 9, pomeranians: 1, samoyeds: 1
+Sue 341: akitas: 3, trees: 0, goldfish: 2
+Sue 342: perfumes: 4, vizslas: 8, pomeranians: 9
+Sue 343: akitas: 4, cars: 5, goldfish: 4
+Sue 344: samoyeds: 5, cats: 4, trees: 0
+Sue 345: samoyeds: 4, cars: 8, akitas: 2
+Sue 346: akitas: 3, vizslas: 10, perfumes: 10
+Sue 347: goldfish: 10, akitas: 4, cars: 1
+Sue 348: perfumes: 10, cats: 4, vizslas: 5
+Sue 349: akitas: 2, vizslas: 4, cars: 7
+Sue 350: akitas: 5, vizslas: 5, cars: 6
+Sue 351: vizslas: 8, perfumes: 6, cars: 3
+Sue 352: cars: 10, vizslas: 0, goldfish: 10
+Sue 353: cars: 10, perfumes: 5, children: 7
+Sue 354: vizslas: 6, akitas: 3, samoyeds: 9
+Sue 355: akitas: 2, perfumes: 7, cars: 10
+Sue 356: cars: 10, perfumes: 7, children: 6
+Sue 357: akitas: 4, cars: 8, trees: 1
+Sue 358: trees: 2, cars: 1, goldfish: 2
+Sue 359: vizslas: 5, cars: 9, trees: 4
+Sue 360: perfumes: 4, akitas: 3, cars: 3
+Sue 361: children: 3, akitas: 2, cats: 5
+Sue 362: cars: 8, cats: 4, akitas: 10
+Sue 363: cats: 2, trees: 1, vizslas: 4
+Sue 364: vizslas: 2, pomeranians: 5, samoyeds: 9
+Sue 365: samoyeds: 2, akitas: 7, goldfish: 9
+Sue 366: goldfish: 8, trees: 7, cats: 2
+Sue 367: perfumes: 2, vizslas: 6, trees: 5
+Sue 368: cars: 5, samoyeds: 0, perfumes: 6
+Sue 369: samoyeds: 10, trees: 10, vizslas: 1
+Sue 370: trees: 2, vizslas: 3, cars: 4
+Sue 371: akitas: 6, pomeranians: 2, cats: 4
+Sue 372: trees: 2, perfumes: 3, goldfish: 9
+Sue 373: vizslas: 5, children: 0, pomeranians: 6
+Sue 374: trees: 1, vizslas: 8, perfumes: 10
+Sue 375: cars: 0, akitas: 6, children: 0
+Sue 376: akitas: 1, vizslas: 0, trees: 0
+Sue 377: samoyeds: 10, cats: 5, pomeranians: 0
+Sue 378: goldfish: 3, pomeranians: 7, cats: 7
+Sue 379: perfumes: 0, cats: 0, trees: 8
+Sue 380: perfumes: 4, samoyeds: 1, akitas: 7
+Sue 381: akitas: 4, pomeranians: 2, children: 4
+Sue 382: vizslas: 9, akitas: 4, trees: 10
+Sue 383: trees: 1, vizslas: 10, akitas: 6
+Sue 384: trees: 3, akitas: 8, goldfish: 3
+Sue 385: goldfish: 6, perfumes: 2, children: 9
+Sue 386: children: 10, akitas: 7, goldfish: 7
+Sue 387: goldfish: 3, vizslas: 10, perfumes: 5
+Sue 388: children: 4, trees: 0, cars: 2
+Sue 389: trees: 0, cats: 3, goldfish: 10
+Sue 390: samoyeds: 9, pomeranians: 0, cats: 6
+Sue 391: samoyeds: 10, trees: 3, akitas: 4
+Sue 392: akitas: 9, goldfish: 10, perfumes: 7
+Sue 393: goldfish: 6, cars: 2, akitas: 9
+Sue 394: trees: 4, goldfish: 9, vizslas: 7
+Sue 395: vizslas: 4, samoyeds: 1, goldfish: 6
+Sue 396: vizslas: 5, cats: 0, samoyeds: 1
+Sue 397: goldfish: 7, cats: 0, trees: 7
+Sue 398: cars: 10, akitas: 1, vizslas: 7
+Sue 399: samoyeds: 10, cats: 6, goldfish: 6
+Sue 400: cats: 6, samoyeds: 0, trees: 2
+Sue 401: trees: 1, children: 4, goldfish: 2
+Sue 402: cats: 8, vizslas: 4, children: 3
+Sue 403: cars: 9, perfumes: 8, pomeranians: 2
+Sue 404: goldfish: 8, trees: 2, cars: 5
+Sue 405: perfumes: 1, pomeranians: 5, vizslas: 5
+Sue 406: perfumes: 6, trees: 2, pomeranians: 6
+Sue 407: trees: 0, goldfish: 6, cars: 6
+Sue 408: trees: 0, samoyeds: 7, goldfish: 9
+Sue 409: samoyeds: 10, goldfish: 6, pomeranians: 0
+Sue 410: perfumes: 5, vizslas: 6, trees: 0
+Sue 411: goldfish: 2, trees: 2, pomeranians: 0
+Sue 412: pomeranians: 4, perfumes: 8, cats: 8
+Sue 413: vizslas: 4, cars: 5, akitas: 1
+Sue 414: perfumes: 2, trees: 8, goldfish: 7
+Sue 415: akitas: 3, trees: 1, perfumes: 3
+Sue 416: cars: 7, trees: 1, perfumes: 8
+Sue 417: cars: 5, goldfish: 5, trees: 1
+Sue 418: cars: 9, goldfish: 4, samoyeds: 2
+Sue 419: pomeranians: 8, akitas: 1, goldfish: 6
+Sue 420: cars: 0, cats: 0, children: 8
+Sue 421: akitas: 10, goldfish: 1, vizslas: 8
+Sue 422: children: 8, vizslas: 6, samoyeds: 10
+Sue 423: samoyeds: 3, goldfish: 10, vizslas: 8
+Sue 424: cars: 3, children: 7, goldfish: 4
+Sue 425: cars: 9, perfumes: 9, goldfish: 8
+Sue 426: akitas: 5, trees: 10, vizslas: 10
+Sue 427: vizslas: 10, cars: 3, akitas: 7
+Sue 428: cats: 6, perfumes: 5, goldfish: 10
+Sue 429: goldfish: 7, trees: 5, vizslas: 10
+Sue 430: perfumes: 3, trees: 7, cars: 3
+Sue 431: cars: 2, vizslas: 1, akitas: 6
+Sue 432: pomeranians: 8, perfumes: 5, cars: 3
+Sue 433: children: 8, cars: 0, perfumes: 7
+Sue 434: samoyeds: 0, vizslas: 9, akitas: 10
+Sue 435: akitas: 3, vizslas: 8, cats: 4
+Sue 436: goldfish: 5, trees: 8, samoyeds: 8
+Sue 437: cars: 10, samoyeds: 9, goldfish: 7
+Sue 438: samoyeds: 5, akitas: 7, perfumes: 9
+Sue 439: goldfish: 10, perfumes: 5, cars: 0
+Sue 440: pomeranians: 1, samoyeds: 9, children: 4
+Sue 441: vizslas: 4, perfumes: 2, cats: 5
+Sue 442: trees: 0, pomeranians: 3, cars: 7
+Sue 443: akitas: 0, cars: 2, vizslas: 10
+Sue 444: children: 1, akitas: 9, trees: 0
+Sue 445: cars: 5, perfumes: 7, goldfish: 9
+Sue 446: akitas: 0, perfumes: 1, vizslas: 2
+Sue 447: vizslas: 7, perfumes: 0, cars: 5
+Sue 448: vizslas: 6, goldfish: 10, trees: 0
+Sue 449: cars: 7, vizslas: 7, trees: 3
+Sue 450: pomeranians: 4, akitas: 4, vizslas: 8
+Sue 451: cats: 4, perfumes: 8, children: 3
+Sue 452: samoyeds: 8, akitas: 9, cars: 1
+Sue 453: cars: 8, akitas: 5, vizslas: 2
+Sue 454: vizslas: 9, perfumes: 4, akitas: 4
+Sue 455: akitas: 3, goldfish: 2, vizslas: 6
+Sue 456: cars: 4, perfumes: 5, goldfish: 10
+Sue 457: trees: 9, pomeranians: 4, goldfish: 10
+Sue 458: pomeranians: 1, perfumes: 9, children: 6
+Sue 459: samoyeds: 0, goldfish: 8, vizslas: 6
+Sue 460: cars: 10, goldfish: 8, samoyeds: 8
+Sue 461: akitas: 8, goldfish: 9, vizslas: 2
+Sue 462: cars: 1, vizslas: 2, akitas: 8
+Sue 463: goldfish: 2, akitas: 4, samoyeds: 10
+Sue 464: children: 5, perfumes: 5, cars: 5
+Sue 465: perfumes: 9, trees: 0, samoyeds: 6
+Sue 466: akitas: 5, goldfish: 3, cats: 6
+Sue 467: perfumes: 3, goldfish: 0, trees: 4
+Sue 468: goldfish: 2, children: 4, trees: 1
+Sue 469: cars: 0, perfumes: 8, children: 7
+Sue 470: vizslas: 8, cats: 5, samoyeds: 9
+Sue 471: pomeranians: 7, trees: 2, goldfish: 3
+Sue 472: goldfish: 8, akitas: 4, perfumes: 5
+Sue 473: perfumes: 2, pomeranians: 3, cars: 8
+Sue 474: samoyeds: 0, akitas: 7, pomeranians: 6
+Sue 475: vizslas: 7, perfumes: 1, trees: 6
+Sue 476: vizslas: 3, samoyeds: 1, perfumes: 10
+Sue 477: cars: 6, perfumes: 5, vizslas: 2
+Sue 478: pomeranians: 1, goldfish: 3, akitas: 7
+Sue 479: goldfish: 10, trees: 0, cars: 3
+Sue 480: cats: 3, akitas: 5, vizslas: 8
+Sue 481: pomeranians: 5, vizslas: 2, trees: 3
+Sue 482: cars: 8, samoyeds: 10, goldfish: 10
+Sue 483: pomeranians: 3, vizslas: 6, goldfish: 5
+Sue 484: perfumes: 7, vizslas: 4, akitas: 7
+Sue 485: goldfish: 1, trees: 0, perfumes: 10
+Sue 486: goldfish: 6, perfumes: 0, akitas: 10
+Sue 487: cats: 2, akitas: 10, trees: 1
+Sue 488: akitas: 1, goldfish: 3, cars: 7
+Sue 489: goldfish: 3, akitas: 6, vizslas: 6
+Sue 490: goldfish: 8, perfumes: 2, akitas: 2
+Sue 491: trees: 4, vizslas: 8, perfumes: 6
+Sue 492: cars: 9, perfumes: 3, cats: 0
+Sue 493: trees: 3, vizslas: 6, goldfish: 7
+Sue 494: trees: 8, samoyeds: 1, perfumes: 5
+Sue 495: children: 9, akitas: 8, vizslas: 4
+Sue 496: vizslas: 2, pomeranians: 1, perfumes: 7
+Sue 497: trees: 2, akitas: 4, vizslas: 6
+Sue 498: akitas: 8, pomeranians: 7, trees: 0
+Sue 499: perfumes: 6, goldfish: 3, vizslas: 7
+Sue 500: cars: 1, perfumes: 6, vizslas: 1
diff --git a/2015/day17.hs b/2015/day17.hs
new file mode 100644
index 0000000..9b5af87
--- /dev/null
+++ b/2015/day17.hs
@@ -0,0 +1,20 @@
+import Control.Monad
+
+search :: Int -> [Int] -> [[Int]]
+search 0 [] = [[]]
+search _ [] = []
+search target (sz:szs)
+ | target < 0 = []
+ | target == 0 = [[]]
+ | target < sz = search target szs
+ | otherwise = map (sz:) (search (target-sz) szs) ++ search target szs
+
+day17 :: IO ()
+day17 = do
+ input <- liftM (map read . lines) $ readFile "day17.txt"
+ let fullsearch = search 150 input
+ minlength = minimum $ map length fullsearch
+ minposs = filter (\x -> length x == minlength) fullsearch
+ print $ length minposs -- part 1: do fullsearch instead of minposs
+
+main = day17
diff --git a/2015/day17.txt b/2015/day17.txt
new file mode 100644
index 0000000..588b253
--- /dev/null
+++ b/2015/day17.txt
@@ -0,0 +1,20 @@
+50
+44
+11
+49
+42
+46
+18
+32
+26
+40
+21
+7
+18
+43
+10
+47
+36
+24
+22
+40
diff --git a/2015/day18.hs b/2015/day18.hs
new file mode 100644
index 0000000..7b70266
--- /dev/null
+++ b/2015/day18.hs
@@ -0,0 +1,34 @@
+width :: Int
+width = 100
+
+width2 :: Int
+width2 = width + 2
+
+golStep :: [[Int]] -> [[Int]]
+golStep bd = replicate width2 0 : (map golLine $ zip [1..] $ init (tail bd)) ++ [replicate width2 0]
+ where golLine (y,l) = map (golCell y) $ zip [0..] l
+ golCell y (x,c) = if x == 0 || x == width2 - 1
+ then 0
+ else if golSum x y == 3 || (c == 1 && golSum x y == 2)
+ then 1
+ else 0
+ golSum x y = bd!!(y-1)!!(x-1)+
+ bd!!(y-1)!!(x )+
+ bd!!(y-1)!!(x+1)+
+ bd!!(y )!!(x+1)+
+ bd!!(y+1)!!(x+1)+
+ bd!!(y+1)!!(x )+
+ bd!!(y+1)!!(x-1)+
+ bd!!(y )!!(x-1)
+
+setCorners :: [[Int]] -> [[Int]]
+setCorners bd = bd!!0 : set2 (bd!!1) : (init $ init $ drop 2 bd) ++ [set2 (bd!!(width2-2)),last bd]
+ where set2 line = head line : 1 : (init $ init $ drop 2 line) ++ [1,last line]
+
+day18 :: IO ()
+day18 = do
+ input <- readFile "day18.txt"
+ let bd = map (\l -> 0 : l ++ [0]) $ replicate width 0 : [map (\c -> if c == '#' then 1 else 0) l | l <- lines input] ++ [replicate width 0]
+ print $ sum $ map sum $ iterate (setCorners . golStep) bd !! 100 -- part 1: setCorners -> id
+
+main = day18
diff --git a/2015/day18.txt b/2015/day18.txt
new file mode 100644
index 0000000..83f3cb2
--- /dev/null
+++ b/2015/day18.txt
@@ -0,0 +1,100 @@
+#..####.##..#...#..#...#...###.#.#.#..#....#.##..#...##...#..#.....##..#####....#.##..##....##.#....
+.#..#..#..#.###...##..#.##.....#...#..##....#####.##............####.#..######..#.#.##.#...#..#...##
+#.....##.##.##.#..##.#..###...#.#.#..##..###.####.####.#.####.#...##.#..###.........#.###...#....###
+#.###..#######..##..#.....##.#.#.###.#.##..#.##..##.##.#.##...###.#...#.#####.#.##..#.#####..#.#####
+#.##.##.###.##..###.#.##.##...##.#.#..##..###.########.#.####..####...#####...#..#...##....##.##.##.
+..#.#.#.#..#.#.###....###...#...#.##..####.###.....#.####.###.###.#......#.#.###..#..#.#....#.#####.
+...#.###.#....#.###...#.#.#...#...#.#####....#....#...#####..#..#.#..######..#.##.#.##.#..###.#...##
+.###...#...#.#..#.#.####.#...#.....##...###.#....#..##.###....#.##....###..#.#####...###.#.##.####..
+#.#....##.#.....#####.#.##..#######.#.####..###.##.#####.##.#...###...#.#...###..#...#.#.###.###.###
+...##.##.....##..#.##...#.#...#...#.#####.#...#.#.#.#####.##.#...#.#..##.##..#...#....####..###.###.
+#..#....######...#...###.#....#####....#.#.#....#....#.#######.#####..#....#....#.##..#.##.###..#...
+#####.#.######.#.#####.#..##..##..####..#....#...#######....##..##.#..###..###.###..###...#...######
+#...##..##...###....##..##.##..#.#.#.#....##.#.......###..###..###...###..##.##.##.#.#.#..#.#..#..#.
+..###....##.###..#.#..########...###...##..#######....##..###..#####.##.#....###..##.##.##.#...##.#.
+###..#.#..#.#.##.##...##.....#..###.#..##.##.#....##.#.######..##..#.#.##.###...#..####...#.#..#.###
+.######....#..##..#.####.##..#.#..#.#..#....#..##.#..#.#...####..#....#.####.#.###.#...####.#...#.#.
+#.######.##..###.###..#..###.#...#..#...#...###.##....#.#......#...#.##.#.###..#.#####.#.#..###..#.#
+...#..#...####..###.########.....###.###.#..##.##....######..#..#.....#.##.##.#..##..#..##...#..#..#
+#..#..##..#.#.########.##.#.####..#.#####.#.###.##....###..##..#.#.###..#.##..##.##.####...######.##
+.######.###....#...##...#..#....##..#.#...###.######.##...#....##.##.#.#.##..#...###.###.#....#..##.
+####.#.##..##.##.###...#.###.##..##....###..####.##..#.#.##..###.#..##...####...#..####.#.#..##...#.
+.#.#..#.....##...#..#...#.#...#.#.##..#....#..#......#####.#######....#.#..#..###..##.#.########..##
+.##.#..#..##..#..####.#...####...#...#..##.#..###.#..######..#.#...###.##...#..#####..##.#..##.#.##.
+.###..##.##.##....###.###..#.#...##.#.#...#.#######.####..#..###.#######.#...#.#...#.##...#..####..#
+##.########..#..#....#.###..##.##.#.##.#..#......####..##.##.#..####..#####..#.....#####.###..#.#.#.
+.#..####..##.#.#..#####.##..#..#.#....#.#####.#####...######........##.##..##.#.#.###..#.#.#.#..##.#
+.##..##..#.######..###....#.#.###.#........#..###..#.########.....#.##...#.....#..#...##...#..#.###.
+##.##.#..####....####.#######.....#.#.#...#.######.#.....####.####...###..####.##.##....###..#..#...
+#.#..####...#......#...###...##....##.#######..#.###.#...###.##.##...####..#.####..#......##..#####.
+.#.#...##...#....#.####.##.....#....#.#.#######..###.#.....#.....####...##...#.#.##.####..##.###.#.#
+####.#.#.####...#...####.#.....#.#######.#.......####......###..###.#...######..#.##.#.##..#..##..##
+..##.###..#..####..####.......######.##..#.....##.##...##.##......#.###..###...#.##.#####.#.######.#
+.###..####.###..#..#.......#.##...##...##.######.....#..####.#......#.#...#...#...###...#.#.##..####
+.####....##.##.#.....##.###.####.#.......#.......#.#..#.#.#.....###.#.#####.#..#.#.#####.#####.###.#
+.##.#.###.#####..#..#....###.#.#.#..#..###..##..####..##.###....#..####.####.#..###.#..######.######
+####.#.....##..###....#.....#.##.#.##..##..########.#####..###.####....##.....######.#.#.##.......#.
+#.#.##.....#.....##.###.#..#.##.##....#..##....##.#.###.##.#..#..##.##.###.#..##.###...##..###.#####
+#.###.#.#.#.#.#.#.#...#..#.###..####.##...#..####.###....#..#..##.#....####..##.##....#.#.##.##....#
+...######....#..####...#.#..#.#.#..#.##.#.#.......#..#......##..#...#..#..##...##.#...#.#.#...##.##.
+.#####..#...####....#..###..##....#####..###.#.#...###..###.###..##...#......#...#...#.#.#...#.##..#
+......#####.#...#.#.#.##..#.###..##..#.#...###..###....##..#####..#######.#..#.###....###...##.#..#.
+..##.########.##..#....##.#...##.##.#.#..#.##..#.#.#.##....#.#.#.#.##....##....#....#####.##..#.##.#
+####...#....##.#.###......##.##.#..##...#..#####..#.#....##..#####...#.#.##...#.####.####..##.######
+.##.###.##.#...#.#....###.#######...##...##..#..##.###.#.####..#..###......#.#.##.#.#....#..##...#..
+.#.###.#.###.###.#.##.#..#......####.##...#..##.#..####.....#...#.###.##.##.#..#.##..#.###......#..#
+...##.####......#.#.#..###..#....###....#.##.#####..#..#..#...#.#.###...#.#.#.##....###.####..###.#.
+##..#.#.#.#....####...#.##.###..####....#..#####.######..#.##.##..#####.#.....#.#...##.#.##.##.#.#..
+#..##.#.#.#.###.#.#.###...#.#...##..#..#.#.#.##..###...#..##.#..#.#.#..#.....#.######.#.###..###.#..
+....#.#.##.###.##...#.##.#....#..##.#..##...#...#.##.####...##..####.#.........#..##..#...#...##.#..
+.##.......##...###.##.#.##.###.##.#..#..#..####...#...#....#####...###..##..#..#..##...#....#..#####
+..####..#...#...#..###....##.#.#####..#..#.....#......#...#.......##....####...##....##.##.#.#####.#
+##.#.#.#..##..##..#.####.##.##.###.#...###.#....#.....#.###...#######..###.####.###.####.##...##.#..
+..#.#...##.#....#..#..##.####.....#.#.#...#..#..###.#..###.#####.#.#####.#.#.#.#.###.##.###..#....##
+.###.#...#....###..#...####....####..#.##..#..##.###..#.#.#.#..#...###.#.#...#......#...#.##.##.#...
+..####.####.##.#.##....#...##....#..#....#..###..#...#..###.#####.....#####..##.#.#.#.#.#.##.####...
+...##.#.##.####..##.###..#.#.#.#.#.#.#..###...#.##..#.####.##...#.#.##......###..#...###....#.#.###.
+##...##..#.#.##..#.#.#....#.####.......#.#.#######.#..#....#.###.#...###.##....###.#.#..#.#.##.####.
+...##.......######.....##....#...#..#.##.###.#..#.##.###.#.###.#.#.#...#.#...##.##.##..#.##########.
+###..#....#.#.....#....###.#...##.......##.#.#..#.#...########......###..##.#..#..####.##..####...#.
+......##.###.#.###.....#..#...#.#......##....#....#........#..#...##.##.....#...##.##.........##....
+.##.##.#.#...#....######..##....##..##.#.#.##.#.##..##...#..###......##......#.#....#.#.#.......###.
+.......#.##..##.#...#.##..#..#####.#..#.######.........###.#####.####.#...##...........##...##..####
+#......#.#..#...#...##..#.#.###.##.##.#.#..#.###.##.#..###..#.###..#...###.##..###..#...#..###...#..
+####.##..#####..####.#...#..#..###..##.#.#...#...#...#.##.####.##.###....###...#.#.#..####.######.##
+.....#..####...#.#.#.####..####..##.###......#.....########.#...#.#..#..#...#.###..##.#####..###.###
+.#######.#.##..###.#...###.#####............##.###...#.##.#.##..##.#.#..#.######..######..#..#..####
+...##..#.####...#..#.#.##.#....#.####..#..###.###..#.#...#....##.##.#......##..##..#.#.#.###..#..#..
+........#...#.##.#.#..#....####....#.##...###..####...###.#.#..######..###..##.#####.###.###.#.#...#
+##......##.#..###.####.##.#.###.#.......#.##..####..#.###.##..##..##...##...#.###...#.#..#..#.#####.
+##..#.#.....##.####.#..##.#.##.#.#...#...#.#...####.#.#.##...##....##.###..###.####.#...#.###..#####
+.#####.####.####.####.#.##.##......###....###.####...###...#...#..#.##.#.#####.###..##.#..###...##..
+.#...#..##...##...#....#.#.#..##..#.##..#.###.#.###..###.#.#.###.#....#######.####.##..#..#...####..
+..##.##..#.##..#.#.###..#.##.########...####.#.###.##..#..###.###...##..##.#..#.######.##.#....###.#
+##.#####.###.##.#.##.##.##.###..##..##..#.#.#.#.####..#......#.#.#.#.#.#.##...#####.####...#.#...#.#
+.#..###..##.#####.#.##.#..##...##..##...#####.#.####..#...##.....######.#.#...##.#..#######.###.###.
+#.#..##.#.#####.#.#.....###.###.#..##.#####....#.###.##.##.#.#..##..#.#....#######.###.#.#.....#.###
+....###...#.###.####....###.....##....#####.##.###.###.##.##.##.#..###..######...####.#.#..####..#..
+###.....#..####..#.####..#..#...##.##..##.######.####.....#...##....#..#.##.#####..###.##.#.####...#
+.##.##.#...#..####...##.##.###...#...#..#.#.#####.....####...#.#.#..#.####...####.#...###.#......###
+###.##....#.#.#...#.###....####..##...##.##.##.#..#...####..#..#..##...#####.####.####...##.#..###.#
+..####.....##..###.#.#.###.########..#...#.##..#.#.#.......#.##.#..#...####.##.#..#.######..#.#...#.
+#.#.##.#.#.##.#....##......##......#######.#..#.##...##..#.#.###...#.#..#..###...#..###.....##.....#
+..#.##.#.##.#.##..##.....#.#..#.#..#...##..#..#.#....###.#####....####.####..#####.##.###...#..###.#
+#....#.###..#..########.###..#.#.#.##...##.#..##.###..#..#..#.#.##..###...###.#.##..#.##.#..#.#.####
+#.......#######......#...#...##.##...###.#....##.#..#....####.#.##.###...#.#####...##.###........##.
+.##.####.....###.##......####.###.########..#.####..#.##.#.####.....#...#.##....#######.##..#......#
+#.#.##.##....##..##.#.###..#.##.#..#..#.#..##.....###..###.##.##.####.##.#.#.##...####..#.#..##.#.#.
+...##.#.#.#...###.#.......#.#.....#.#...##....##.##.##.####...#.#..#..#..#.#.##.#..#.#.#....###..#.#
+....#.#.###.#####.##..###..##..#...#.##.#......##.####.#..####.#.##..####.#.#...##..#####..##.#.#...
+..###.#.##..#....#..#.#.....##.#####..##....#.#...#.##..##.#.#..#...##.##..##..##....#...#..#..#..##
+##.#.##.#...#.###.##.##.##.##..##.##...#..##.#..#######.#..#...#.#.##..#....##.#..####.###........#.
+.##.#..#.....#####..##.#.#.#.#..###.#######.###.###....##....#.#.#.###....###.#..#.#....#.#..###...#
+...###.#.#.###..#...#..###.######..##.#.#..#...####.#####.##..#..###...#..#..#..###..##.#.#...#.###.
+#......#.#..#..##.##.#.##.#.###.#.##.#.#..#....#.##..#..##..##.#.#.#....##.###.###.####.#.#####...##
+...#.##..#.######.......#.#.###.....#####....##.#.#.###........#.#.###.#.#########.##.##.#..##..#...
+##..###..###....####.##.##..##.###....####..##...####.####..####..###.####..##.#...###.#####.##.##.#
+###...##.#.#.#####..#..#####...##.#...#.#.###.#..##..###.##.#.#.....####.##.#..##.###.#...##.##...##
+...#.#.##.##..##....#..#.#####.##.###..#.#.#........####.###.##....##....####..#.#....#.#.#.###..#.#
+..#.#.#.#.###...#....##..######.##....#.#.##..###..#.#.###..#.##..#.#.###......#..#..#.####..#...##.
+.....####.#.....###.#.##.#..##.#..###.#####.#..##...###.#..###..#..##....###.#..##.#..#.##.#..#...##
diff --git a/2015/day19.cpp b/2015/day19.cpp
new file mode 100644
index 0000000..7afa3e7
--- /dev/null
+++ b/2015/day19.cpp
@@ -0,0 +1,89 @@
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <unordered_map>
+#include <vector>
+#include <utility>
+
+using namespace std;
+
+bool search(const vector<pair<string,string>> &repls,const string &target,string from,int depth){
+ if(from==target)return true;
+ if(depth<=0)return false;
+ int i,j,r,l;
+ const int fromlen=from.size(),nrepls=repls.size();
+ for(i=0;i<fromlen;i++){
+ for(r=0;r<nrepls;r++){
+ l=repls[r].first.size();
+ if(fromlen-i<l)continue;
+ for(j=0;j<l;j++)if(from[i+j]!=repls[r].first[j])break;
+ if(j<l)continue;
+ if(search(repls,
+ target,
+ from.substr(0,i)+repls[r].second+from.substr(i+repls[r].first.size()),
+ depth-1)){
+ cerr<<repls[r].first<<" -> "<<repls[r].second<<" (at "<<i<<" in "<<from<<')'<<endl;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+int cheat(const vector<pair<string,string>> &repls,const string &target,string from){
+ int i,r,j,l;
+ int depth;
+ const int fromlen=from.size(),nrepls=repls.size();
+ for(depth=0;from!=target;depth++){
+ for(i=0;i<fromlen;i++){
+ for(r=0;r<nrepls;r++){
+ l=repls[r].first.size();
+ if(fromlen-i<l)continue;
+ for(j=0;j<l;j++)if(from[i+j]!=repls[r].first[j])break;
+ if(j<l)continue;
+ from=from.substr(0,i)+repls[r].second+from.substr(i+repls[r].first.size());
+ i=fromlen+41; break;
+ }
+ }
+ if(i!=fromlen+42)return -1;
+ cout<<from<<endl;
+ }
+ return depth;
+}
+
+int main(void){
+ ifstream in("day19.txt");
+ string line,target;
+ int a,b;
+ vector<pair<string,string>> repls;
+ while(true){
+ getline(in,line);
+ if(line.size()==0){
+ getline(in,target);
+ break;
+ }
+ if(!in)break;
+ a=line.find(' ');
+ b=line.find(' ',a+1);
+ // repls.emplace_back(line.substr(0,a),line.substr(b+1));
+ repls.emplace_back(line.substr(b+1),line.substr(0,a)); //reversed
+ }
+
+ // repls={{"H","HO"},{"H","OH"},{"O","HH"},{"e","O"},{"e","H"}};
+ // repls={{"HO","H"},{"OH","H"},{"HH","O"},{"O","e"},{"H","e"}}; //reversed
+ // target="HOHOHO";
+
+ //for(const pair<string,string> &p : repls)cout<<"repl: "<<p.first<<" -> "<<p.second<<endl;
+ //cout<<"target: "<<target<<endl;
+
+ cout<<cheat(repls,"e",target)<<endl;
+
+ int depth;
+ for(depth=1;;depth++){
+ cerr<<"Starting depth "<<depth<<"..."<<endl;
+ // const bool res=search(repls,target,"e",depth);
+ const bool res=search(repls,"e",target,depth); //reversed
+ if(res)break;
+ }
+ cout<<depth<<endl;
+}
diff --git a/2015/day19.hs b/2015/day19.hs
new file mode 100644
index 0000000..65d3e87
--- /dev/null
+++ b/2015/day19.hs
@@ -0,0 +1,41 @@
+import Data.List
+import qualified Data.Set as Set
+import Control.Monad
+
+import Debug.Trace
+
+parseRepl :: [String] -> (String,String)
+parseRepl [a,"=>",b] = (a,b)
+-- = -- subl syntax
+
+startsWith :: String -> String -> Bool
+startsWith s prefix = take (length prefix) s == prefix
+
+getRepls :: [(String,String)] -> String -> Set.Set String
+getRepls rs s = getRepls' rs s ""
+
+getRepls' :: [(String,String)] -> String -> String -> Set.Set String
+getRepls' _ [] _ = Set.empty
+getRepls' rs s prefix = foldl (\set s -> Set.insert (prefix++s) set) fromnext
+ $ map (\r -> replace s r)
+ $ filter (\r -> s `startsWith` (fst r)) rs
+ where fromnext = getRepls' rs (tail s) $ prefix ++ [head s]
+ replace s r = snd r ++ drop (length (fst r)) s
+
+day19_1 :: IO ()
+day19_1 = do
+ input <- liftM lines $ readFile "day19.txt"
+ let rs = map (parseRepl . words) $ init (init input)
+ start = last input
+ print $ Set.size $ getRepls rs start
+
+day19_2 :: IO ()
+day19_2 = do
+ input <- liftM lines $ readFile "day19.txt"
+ let rs = map (parseRepl . words) $ init (init input)
+ target = last input
+ stages = iterate (Set.unions . map (getRepls rs) . Set.toList . (\s -> trace (show $ Set.size s) s)) $ Set.fromList ["e"]
+ print $ (Set.unions . map (getRepls rs) . Set.toList) $ (Set.unions . map (getRepls rs) . Set.toList) $ Set.fromList ["e"]
+ print $ findIndex (Set.member target) stages
+
+main = day19_2
diff --git a/2015/day19.txt b/2015/day19.txt
new file mode 100644
index 0000000..a245944
--- /dev/null
+++ b/2015/day19.txt
@@ -0,0 +1,45 @@
+Al => ThF
+Al => ThRnFAr
+B => BCa
+B => TiB
+B => TiRnFAr
+Ca => CaCa
+Ca => PB
+Ca => PRnFAr
+Ca => SiRnFYFAr
+Ca => SiRnMgAr
+Ca => SiTh
+F => CaF
+F => PMg
+F => SiAl
+H => CRnAlAr
+H => CRnFYFYFAr
+H => CRnFYMgAr
+H => CRnMgYFAr
+H => HCa
+H => NRnFYFAr
+H => NRnMgAr
+H => NTh
+H => OB
+H => ORnFAr
+Mg => BF
+Mg => TiMg
+N => CRnFAr
+N => HSi
+O => CRnFYFAr
+O => CRnMgAr
+O => HP
+O => NRnFAr
+O => OTi
+P => CaP
+P => PTi
+P => SiRnFAr
+Si => CaSi
+Th => ThCa
+Ti => BP
+Ti => TiTi
+e => HF
+e => NAl
+e => OMg
+
+CRnCaCaCaSiRnBPTiMgArSiRnSiRnMgArSiRnCaFArTiTiBSiThFYCaFArCaCaSiThCaPBSiThSiThCaCaPTiRnPBSiThRnFArArCaCaSiThCaSiThSiRnMgArCaPTiBPRnFArSiThCaSiRnFArBCaSiRnCaPRnFArPMgYCaFArCaPTiTiTiBPBSiThCaPTiBPBSiRnFArBPBSiRnCaFArBPRnSiRnFArRnSiRnBFArCaFArCaCaCaSiThSiThCaCaPBPTiTiRnFArCaPTiBSiAlArPBCaCaCaCaCaSiRnMgArCaSiThFArThCaSiThCaSiRnCaFYCaSiRnFYFArFArCaSiRnFYFArCaSiRnBPMgArSiThPRnFArCaSiRnFArTiRnSiRnFYFArCaSiRnBFArCaSiRnTiMgArSiThCaSiThCaFArPRnFArSiRnFArTiTiTiTiBCaCaSiRnCaCaFYFArSiThCaPTiBPTiBCaSiThSiRnMgArCaF
diff --git a/2015/day20.cpp b/2015/day20.cpp
new file mode 100644
index 0000000..2da1fa2
--- /dev/null
+++ b/2015/day20.cpp
@@ -0,0 +1,23 @@
+#include <iostream>
+#include <cstdlib>
+
+using namespace std;
+
+int main(void){
+ const int limit=10000000; //1e7
+ cerr<<"Alloc...";
+ int *scores=(int*)calloc(limit+1,sizeof(int));
+ cerr<<" done."<<endl;
+ int elf,i,ilimit;
+ for(elf=1;elf<=limit;elf++){
+ ilimit=limit/elf;
+ if(ilimit>50)ilimit=50;
+ for(i=1;i<=ilimit;i++){
+ scores[elf*i]+=elf*11;
+ }
+ if(scores[elf]>=36000000)break;
+ }
+ for(i=1;i<20;i++)cout<<scores[i]<<' '; cout<<endl;
+ cout<<elf<<endl;
+ free(scores);
+}