tangled
alpha
login
or
join now
eldridge.cam
/
advent-of-code
2
fork
atom
Advent of Code solutions
2
fork
atom
overview
issues
pulls
pipelines
2020:21
eldridge.cam
1 year ago
07467b69
c0d6be2f
+56
-1
3 changed files
expand all
collapse all
unified
split
2020
21
p1.hs
p2.hs
Justfile
+22
2020/21/p1.hs
···
1
1
+
import Text.Parsec
2
2
+
import Data.Set qualified as Set
3
3
+
import Data.Set ((\\))
4
4
+
import Data.Map.Strict qualified as Map
5
5
+
import Data.List (foldl1)
6
6
+
7
7
+
food = do
8
8
+
ingredients <- many1 letter `endBy` char ' '
9
9
+
string "(contains "
10
10
+
allergens <- many1 letter `sepBy` string ", "
11
11
+
char ')'
12
12
+
return (ingredients, allergens)
13
13
+
14
14
+
answer contents = length $ filter (`elem` safe) $ concat $ (fst <$> foods)
15
15
+
where
16
16
+
Right foods = parse (food `endBy` newline) "" contents
17
17
+
allergens = Set.unions (Set.fromList <$> snd <$> foods)
18
18
+
ingredients = Set.unions (Set.fromList <$> fst <$> foods)
19
19
+
candidates = Map.fromList $ Set.toList allergens `zip` fmap (\a -> foldl1 Set.intersection $ fmap (Set.fromList . fst) $ filter (\(_, i) -> a `elem` i) foods) (Set.toList allergens)
20
20
+
safe = Set.toList $ ingredients \\ (Set.unions $ Map.elems candidates)
21
21
+
22
22
+
main = getContents >>= print . answer
+32
2020/21/p2.hs
···
1
1
+
import Text.Parsec
2
2
+
import Data.Bifunctor
3
3
+
import Data.Set qualified as Set
4
4
+
import Data.Set (Set)
5
5
+
import Data.Map.Strict qualified as Map
6
6
+
import Data.Map (Map)
7
7
+
import Data.List
8
8
+
9
9
+
food = do
10
10
+
ingredients <- many1 letter `endBy` char ' '
11
11
+
string "(contains "
12
12
+
allergens <- many1 letter `sepBy` string ", "
13
13
+
char ')'
14
14
+
return (ingredients, allergens)
15
15
+
16
16
+
solve :: [(String, Set String)] -> Map String String
17
17
+
solve [] = Map.empty
18
18
+
solve candidates = Map.fromList singles `Map.union` rest
19
19
+
where
20
20
+
singles = second Set.findMin <$> filter (\(_, c) -> Set.size c == 1) candidates
21
21
+
eliminating = snd <$> singles
22
22
+
eliminate = Set.filter (`notElem` eliminating)
23
23
+
rest = solve $ filter (not . null . snd) $ fmap (second eliminate) candidates
24
24
+
25
25
+
answer contents = intercalate "," $ Map.elems $ solve candidates
26
26
+
where
27
27
+
Right foods = parse (food `endBy` newline) "" contents
28
28
+
allergens = Set.unions (Set.fromList <$> snd <$> foods)
29
29
+
ingredients = Set.unions (Set.fromList <$> fst <$> foods)
30
30
+
candidates = Set.toList allergens `zip` fmap (\a -> foldl1 Set.intersection $ fmap (Set.fromList . fst) $ filter (\(_, i) -> a `elem` i) foods) (Set.toList allergens)
31
31
+
32
32
+
main = getContents >>= putStrLn . answer
+2
-1
Justfile
···
2
2
set quiet
3
3
set shell := ["fish", "-c"]
4
4
5
5
-
default_year := "2024"
5
5
+
default_year := env_var_or_default("YEAR", "2024")
6
6
session := env_var("SESSION")
7
7
8
8
[no-cd]
···
73
73
end
74
74
75
75
get day year=default_year:
76
76
+
echo "Getting {{year}} day {{day}}"
76
77
mkdir -p {{year}}/{{day}}
77
78
curl https://adventofcode.com/{{year}}/day/{{day}}/input \
78
79
-X GET \