Commit 33ea1e47 authored by Neil Smith's avatar Neil Smith
Browse files

Done day 7

parent a391f550
......@@ -30,9 +30,9 @@ blankLines = skipMany1 endOfLine
personP = S.fromList <$> many1 letter
groupP = sepBy1 personP endOfLine
groupsP = sepBy1 groupP blankLines
groupsP = sepBy groupP blankLines
-- successfulParse :: Text -> [Passport]
successfulParse :: Text -> [[S.Set Char]]
successfulParse input =
case parseOnly groupsP input of
Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
......
# This YAML file describes your package. Stack will automatically generate a
# Cabal file when you run `stack build`. See the hpack website for help with
# this file: <https://github.com/sol/hpack>.
name: advent07
synopsis: Advent of Code
version: '0.0.1'
default-extensions:
- AllowAmbiguousTypes
- ApplicativeDo
- BangPatterns
- BlockArguments
- DataKinds
- DeriveFoldable
- DeriveFunctor
- DeriveGeneric
- DeriveTraversable
- EmptyCase
- FlexibleContexts
- FlexibleInstances
- FunctionalDependencies
- GADTs
- GeneralizedNewtypeDeriving
- ImplicitParams
- KindSignatures
- LambdaCase
- MonadComprehensions
- MonoLocalBinds
- MultiParamTypeClasses
- MultiWayIf
- NamedFieldPuns
- NegativeLiterals
- NumDecimals
# - OverloadedLists
- OverloadedStrings
- PartialTypeSignatures
- PatternGuards
- PatternSynonyms
- PolyKinds
- RankNTypes
- RecordWildCards
- ScopedTypeVariables
- TemplateHaskell
- TransformListComp
- TupleSections
- TypeApplications
- TypeFamilies
- TypeInType
- TypeOperators
- ViewPatterns
executables:
advent07:
main: advent07.hs
source-dirs: src
dependencies:
- base >= 2 && < 6
- text
- attoparsec
- containers
\ No newline at end of file
-- import Debug.Trace
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import Data.Attoparsec.Text
-- import Data.Attoparsec.Combinator
import Control.Applicative
import qualified Data.Set as S
import qualified Data.Map.Strict as M
import Data.Map.Strict ((!))
import Data.Maybe
data QuantifiedBag = QuantifiedBag Integer String
deriving (Show, Eq, Ord)
main :: IO ()
main =
do text <- TIO.readFile "data/advent07.txt"
let bags = successfulParse text
-- print bags
-- print $ invertBags bags
print $ part1 bags
print $ part2 bags
part1 bags = S.size $ S.delete "shiny gold" containers
where containers = bagsContaining (invertBags bags) (S.singleton "shiny gold") S.empty
part2 bags = (nContainedBags bags "shiny gold") - 1
invertBags bags = foldr addInvert M.empty $ concatMap swapPair $ M.assocs bags
where swapPair (a, bs) = [(qName b, a) | b <- S.toList bs]
addInvert :: (String, String) -> (M.Map String (S.Set String)) -> (M.Map String (S.Set String))
addInvert (k, v) m =
if k `M.member` m
then M.insert k v' m
else M.insert k (S.singleton v) m
where v' = S.insert v (m!k)
qName (QuantifiedBag _ n) = n
qCount (QuantifiedBag n _) = n
bagsContaining :: (M.Map String (S.Set String)) -> (S.Set String) -> (S.Set String) -> (S.Set String)
bagsContaining iBags agenda result
| S.null agenda = result
| otherwise = bagsContaining iBags agenda'' (S.insert thisColour result)
where thisColour = S.findMin agenda
agenda' = S.delete thisColour agenda
agenda'' = if thisColour `S.member` result
then agenda'
else S.union (fromMaybe S.empty (M.lookup thisColour iBags)) agenda'
nContainedBags :: (M.Map String (S.Set QuantifiedBag)) -> String -> Integer
nContainedBags bags thisBag = 1 + (sum $ map subCount others)
where others = S.toList $ bags!thisBag
subCount b = (qCount b) * (nContainedBags bags (qName b))
-- -- Parse the input file
bagNameP = manyTill anyChar ((string " bags") <|> (string " bag"))
quantifiedBagP = QuantifiedBag <$> decimal <* space <*> bagNameP
emptyBagListP = "no other bags" *> pure S.empty
bagListP = S.fromList <$> sepBy quantifiedBagP (string ", ")
bagContentsP = emptyBagListP <|> bagListP
ruleP = (,) <$> bagNameP <* " contain " <*> bagContentsP <* "."
rulesP = M.fromList <$> sepBy ruleP endOfLine
-- successfulParse :: Text -> [[S.Set Char]]
successfulParse input =
case parseOnly rulesP input of
Left _err -> M.empty -- TIO.putStr $ T.pack $ parseErrorPretty err
Right bags -> bags
This diff is collapsed.
light red bags contain 1 bright white bag, 2 muted yellow bags.
dark orange bags contain 3 bright white bags, 4 muted yellow bags.
bright white bags contain 1 shiny gold bag.
muted yellow bags contain 2 shiny gold bags, 9 faded blue bags.
shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags.
dark olive bags contain 3 faded blue bags, 4 dotted black bags.
vibrant plum bags contain 5 faded blue bags, 6 dotted black bags.
faded blue bags contain no other bags.
dotted black bags contain no other bags.
\ No newline at end of file
shiny gold bags contain 2 dark red bags.
dark red bags contain 2 dark orange bags.
dark orange bags contain 2 dark yellow bags.
dark yellow bags contain 2 dark green bags.
dark green bags contain 2 dark blue bags.
dark blue bags contain 2 dark violet bags.
dark violet bags contain no other bags.
\ No newline at end of file
......@@ -2,7 +2,7 @@
<html lang="en-us">
<head>
<meta charset="utf-8"/>
<title>Day 4 - Advent of Code 2020</title>
<title>Day 7 - Advent of Code 2020</title>
<!--[if lt IE 9]><script src="/static/html5.js"></script><![endif]-->
<link href='//fonts.googleapis.com/css?family=Source+Code+Pro:300&subset=latin,latin-ext' rel='stylesheet' type='text/css'/>
<link rel="stylesheet" type="text/css" href="/static/style.css?25"/>
......@@ -87,123 +87,67 @@ If you'd like to hang out, I'm @ericwastl on Twitter.
-->
<body>
<header><div><h1 class="title-global"><a href="/">Advent of Code</a></h1><nav><ul><li><a href="/2020/about">[About]</a></li><li><a href="/2020/events">[Events]</a></li><li><a href="https://teespring.com/stores/advent-of-code" target="_blank">[Shop]</a></li><li><a href="/2020/settings">[Settings]</a></li><li><a href="/2020/auth/logout">[Log Out]</a></li></ul></nav><div class="user">Neil Smith <a href="/2020/support" class="supporter-badge" title="Advent of Code Supporter">(AoC++)</a> <span class="star-count">8*</span></div></div><div><h1 class="title-event">&nbsp;&nbsp;&nbsp;<span class="title-event-wrap">0x0000|</span><a href="/2020">2020</a><span class="title-event-wrap"></span></h1><nav><ul><li><a href="/2020">[Calendar]</a></li><li><a href="/2020/support">[AoC++]</a></li><li><a href="/2020/sponsors">[Sponsors]</a></li><li><a href="/2020/leaderboard">[Leaderboard]</a></li><li><a href="/2020/stats">[Stats]</a></li></ul></nav></div></header>
<header><div><h1 class="title-global"><a href="/">Advent of Code</a></h1><nav><ul><li><a href="/2020/about">[About]</a></li><li><a href="/2020/events">[Events]</a></li><li><a href="https://teespring.com/stores/advent-of-code" target="_blank">[Shop]</a></li><li><a href="/2020/settings">[Settings]</a></li><li><a href="/2020/auth/logout">[Log Out]</a></li></ul></nav><div class="user">Neil Smith <a href="/2020/support" class="supporter-badge" title="Advent of Code Supporter">(AoC++)</a> <span class="star-count">14*</span></div></div><div><h1 class="title-event">&nbsp;&nbsp;&nbsp;<span class="title-event-wrap">$year=</span><a href="/2020">2020</a><span class="title-event-wrap">;</span></h1><nav><ul><li><a href="/2020">[Calendar]</a></li><li><a href="/2020/support">[AoC++]</a></li><li><a href="/2020/sponsors">[Sponsors]</a></li><li><a href="/2020/leaderboard">[Leaderboard]</a></li><li><a href="/2020/stats">[Stats]</a></li></ul></nav></div></header>
<div id="sidebar">
<div id="sponsor"><div class="quiet">Our <a href="/2020/sponsors">sponsors</a> help make Advent of Code possible:</div><div class="sponsor"><a href="https://medium.com/building-trayio" target="_blank" onclick="if(ga)ga('send','event','sponsor','sidebar',this.href);" rel="noopener">tray.io</a> - Building a platform that connects people with technology.</div></div>
<div id="sponsor"><div class="quiet">Our <a href="/2020/sponsors">sponsors</a> help make Advent of Code possible:</div><div class="sponsor"><a href="https://whimsical.com/advent-of-code-2020-get-unstuck-with-whimsical-7hoTGmwqttswvigWHqAgpU@2Ux7TurymLzKXw2f4wcD" target="_blank" onclick="if(ga)ga('send','event','sponsor','sidebar',this.href);" rel="noopener">Whimsical</a> - Brainstorm visually. FAST. Stuck on a puzzle? We can help!</div></div>
</div><!--/sidebar-->
<main>
<script>window.addEventListener('click', function(e,s,r){if(e.target.nodeName==='CODE'&&e.detail===3){s=window.getSelection();s.removeAllRanges();r=document.createRange();r.selectNodeContents(e.target);s.addRange(r);}});</script>
<article class="day-desc"><h2>--- Day 4: Passport Processing ---</h2><p>You arrive at the airport only to realize that you grabbed your North Pole Credentials instead of your passport. While these documents are extremely similar, North Pole Credentials aren't issued by a country and therefore aren't actually valid documentation for travel in most of the world.</p>
<p>It seems like you're not the only one having problems, though; a very long line has formed for the automatic passport scanners, and the delay could upset your travel itinerary.</p>
<p>Due to some questionable network security, you realize you might be able to solve both of these problems at the same time.</p>
<p>The automatic passport scanners are slow because they're having trouble <em>detecting which passports have all required fields</em>. The expected fields are as follows:</p>
<article class="day-desc"><h2>--- Day 7: Handy Haversacks ---</h2><p>You land at the regional airport in time for your next flight. In fact, it looks like you'll even have time to grab some food: all flights are currently delayed due to <em>issues in luggage processing</em>.</p>
<p>Due to recent aviation regulations, many rules (your puzzle input) are being enforced about bags and their contents; bags must be color-coded and must contain specific quantities of other color-coded bags. Apparently, nobody responsible for these regulations considered how long they would take to enforce!</p>
<p>For example, consider the following rules:</p>
<pre><code>light red bags contain 1 bright white bag, 2 muted yellow bags.
dark orange bags contain 3 bright white bags, 4 muted yellow bags.
bright white bags contain 1 shiny gold bag.
muted yellow bags contain 2 shiny gold bags, 9 faded blue bags.
shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags.
dark olive bags contain 3 faded blue bags, 4 dotted black bags.
vibrant plum bags contain 5 faded blue bags, 6 dotted black bags.
faded blue bags contain no other bags.
dotted black bags contain no other bags.
</code></pre>
<p>These rules specify the required contents for 9 bag types. In this example, every <code>faded blue</code> bag is empty, every <code>vibrant plum</code> bag contains 11 bags (5 <code>faded blue</code> and 6 <code>dotted black</code>), and so on.</p>
<p>You have a <code><em>shiny gold</em></code> bag. If you wanted to carry it in at least one other bag, how many different bag colors would be valid for the outermost bag? (In other words: how many colors can, eventually, contain at least one <code>shiny gold</code> bag?)</p>
<p>In the above rules, the following options would be available to you:</p>
<ul>
<li><code>byr</code> (Birth Year)</li>
<li><code>iyr</code> (Issue Year)</li>
<li><code>eyr</code> (Expiration Year)</li>
<li><code>hgt</code> (Height)</li>
<li><code>hcl</code> (Hair Color)</li>
<li><code>ecl</code> (Eye Color)</li>
<li><code>pid</code> (Passport ID)</li>
<li><code>cid</code> (Country ID)</li>
<li>A <code>bright white</code> bag, which can hold your <code>shiny gold</code> bag directly.</li>
<li>A <code>muted yellow</code> bag, which can hold your <code>shiny gold</code> bag directly, plus some other bags.</li>
<li>A <code>dark orange</code> bag, which can hold <code>bright white</code> and <code>muted yellow</code> bags, either of which could then hold your <code>shiny gold</code> bag.</li>
<li>A <code>light red</code> bag, which can hold <code>bright white</code> and <code>muted yellow</code> bags, either of which could then hold your <code>shiny gold</code> bag.</li>
</ul>
<p>Passport data is validated in batch files (your puzzle input). Each passport is represented as a sequence of <code>key:value</code> pairs separated by spaces or newlines. Passports are separated by blank lines.</p>
<p>Here is an example batch file containing four passports:</p>
<pre><code>ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
byr:1937 iyr:2017 cid:147 hgt:183cm
iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
hcl:#cfa07d byr:1929
hcl:#ae17e1 iyr:2013
eyr:2024
ecl:brn pid:760753108 byr:1931
hgt:179cm
hcl:#cfa07d eyr:2025 pid:166559648
iyr:2011 ecl:brn hgt:59in
</code></pre>
<p>The first passport is <em>valid</em> - all eight fields are present. The second passport is <em>invalid</em> - it is missing <code>hgt</code> (the Height field).</p>
<p>The third passport is interesting; the <em>only missing field</em> is <code>cid</code>, so it looks like data from North Pole Credentials, not a passport at all! Surely, nobody would mind if you made the system temporarily ignore missing <code>cid</code> fields. Treat this "passport" as <em>valid</em>.</p>
<p>The fourth passport is missing two fields, <code>cid</code> and <code>byr</code>. Missing <code>cid</code> is fine, but missing any other field is not, so this passport is <em>invalid</em>.</p>
<p>According to the above rules, your improved system would report <code><em>2</em></code> valid passports.</p>
<p>Count the number of <em>valid</em> passports - those that have all required fields. Treat <code>cid</code> as optional. <em>In your batch file, how many passports are valid?</em></p>
<p>So, in this example, the number of bag colors that can eventually contain at least one <code>shiny gold</code> bag is <code><em>4</em></code>.</p>
<p><em>How many bag colors can eventually contain at least one <code>shiny gold</code> bag?</em> (The list of rules is quite long; make sure you get all of it.)</p>
</article>
<p>Your puzzle answer was <code>247</code>.</p><article class="day-desc"><h2 id="part2">--- Part Two ---</h2><p>The line is moving more quickly now, but you overhear airport security talking about how passports with invalid data are getting through. Better add some data validation, quick!</p>
<p>You can continue to ignore the <code>cid</code> field, but each other field has <span title="GLORY TO ARSTOTZKA">strict rules</span> about what values are valid for automatic validation:</p>
<p>Your puzzle answer was <code>242</code>.</p><article class="day-desc"><h2 id="part2">--- Part Two ---</h2><p>It's getting pretty expensive to fly these days - not because of ticket prices, but because of the ridiculous number of bags you need to buy!</p>
<p>Consider again your <code>shiny gold</code> bag and the rules from the above example:</p>
<ul>
<li><code>byr</code> (Birth Year) - four digits; at least <code>1920</code> and at most <code>2002</code>.</li>
<li><code>iyr</code> (Issue Year) - four digits; at least <code>2010</code> and at most <code>2020</code>.</li>
<li><code>eyr</code> (Expiration Year) - four digits; at least <code>2020</code> and at most <code>2030</code>.</li>
<li><code>hgt</code> (Height) - a number followed by either <code>cm</code> or <code>in</code>:
<ul>
<li>If <code>cm</code>, the number must be at least <code>150</code> and at most <code>193</code>.</li>
<li>If <code>in</code>, the number must be at least <code>59</code> and at most <code>76</code>.</li>
</ul>
</li>
<li><code>hcl</code> (Hair Color) - a <code>#</code> followed by exactly six characters <code>0</code>-<code>9</code> or <code>a</code>-<code>f</code>.</li>
<li><code>ecl</code> (Eye Color) - exactly one of: <code>amb</code> <code>blu</code> <code>brn</code> <code>gry</code> <code>grn</code> <code>hzl</code> <code>oth</code>.</li>
<li><code>pid</code> (Passport ID) - a nine-digit number, including leading zeroes.</li>
<li><code>cid</code> (Country ID) - ignored, missing or not.</li>
<li><code>faded blue</code> bags contain <code>0</code> other bags.</li>
<li><code>dotted black</code> bags contain <code>0</code> other bags.</li>
<li><code>vibrant plum</code> bags contain <code>11</code> other bags: 5 <code>faded blue</code> bags and 6 <code>dotted black</code> bags.</li>
<li><code>dark olive</code> bags contain <code>7</code> other bags: 3 <code>faded blue</code> bags and 4 <code>dotted black</code> bags.</li>
</ul>
<p>Your job is to count the passports where all required fields are both <em>present</em> and <em>valid</em> according to the above rules. Here are some example values:</p>
<pre><code>byr valid: 2002
byr invalid: 2003
hgt valid: 60in
hgt valid: 190cm
hgt invalid: 190in
hgt invalid: 190
hcl valid: #123abc
hcl invalid: #123abz
hcl invalid: 123abc
ecl valid: brn
ecl invalid: wat
pid valid: 000000001
pid invalid: 0123456789
</code></pre>
<p>Here are some invalid passports:</p>
<pre><code>eyr:1972 cid:100
hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926
iyr:2019
hcl:#602927 eyr:1967 hgt:170cm
ecl:grn pid:012533040 byr:1946
hcl:dab227 iyr:2012
ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277
hgt:59cm ecl:zzz
eyr:2038 hcl:74454a iyr:2023
pid:3556412378 byr:2007
</code></pre>
<p>Here are some valid passports:</p>
<pre><code>pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980
hcl:#623a2f
eyr:2029 ecl:blu cid:129 byr:1989
iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm
hcl:#888785
hgt:164cm byr:2001 iyr:2015 cid:88
pid:545766238 ecl:hzl
eyr:2022
iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719
<p>So, a single <code>shiny gold</code> bag must contain 1 <code>dark olive</code> bag (and the 7 bags within it) plus 2 <code>vibrant plum</code> bags (and the 11 bags within <em>each</em> of those): <code>1 + 1*7 + 2 + 2*11</code> = <code><em>32</em></code> bags!</p>
<p>Of course, the actual rules have a <span title="100%">small</span> chance of going several levels deeper than this example; be sure to count all of the bags, even if the nesting becomes topologically impractical!</p>
<p>Here's another example:</p>
<pre><code>shiny gold bags contain 2 dark red bags.
dark red bags contain 2 dark orange bags.
dark orange bags contain 2 dark yellow bags.
dark yellow bags contain 2 dark green bags.
dark green bags contain 2 dark blue bags.
dark blue bags contain 2 dark violet bags.
dark violet bags contain no other bags.
</code></pre>
<p>Count the number of <em>valid</em> passports - those that have all required fields <em>and valid values</em>. Continue to treat <code>cid</code> as optional. <em>In your batch file, how many passports are valid?</em></p>
<p>In this example, a single <code>shiny gold</code> bag must contain <code><em>126</em></code> other bags.</p>
<p><em>How many individual bags are required inside your single <code>shiny gold</code> bag?</em></p>
</article>
<p>Your puzzle answer was <code>145</code>.</p><p class="day-success">Both parts of this puzzle are complete! They provide two gold stars: **</p>
<p>Your puzzle answer was <code>176035</code>.</p><p class="day-success">Both parts of this puzzle are complete! They provide two gold stars: **</p>
<p>At this point, you should <a href="/2020">return to your Advent calendar</a> and try another puzzle.</p>
<p>If you still want to see it, you can <a href="4/input" target="_blank">get your puzzle input</a>.</p>
<p>If you still want to see it, you can <a href="7/input" target="_blank">get your puzzle input</a>.</p>
<p>You can also <span class="share">[Share<span class="share-content">on
<a href="https://twitter.com/intent/tweet?text=I%27ve+completed+%22Passport+Processing%22+%2D+Day+4+%2D+Advent+of+Code+2020&amp;url=https%3A%2F%2Fadventofcode%2Ecom%2F2020%2Fday%2F4&amp;related=ericwastl&amp;hashtags=AdventOfCode" target="_blank">Twitter</a>
<a href="javascript:void(0);" onclick="var mastodon_instance=prompt('Mastodon Instance / Server Name?'); if(typeof mastodon_instance==='string' && mastodon_instance.length){this.href='https://'+mastodon_instance+'/share?text=I%27ve+completed+%22Passport+Processing%22+%2D+Day+4+%2D+Advent+of+Code+2020+%23AdventOfCode+https%3A%2F%2Fadventofcode%2Ecom%2F2020%2Fday%2F4'}else{return false;}" target="_blank">Mastodon</a
<a href="https://twitter.com/intent/tweet?text=I%27ve+completed+%22Handy+Haversacks%22+%2D+Day+7+%2D+Advent+of+Code+2020&amp;url=https%3A%2F%2Fadventofcode%2Ecom%2F2020%2Fday%2F7&amp;related=ericwastl&amp;hashtags=AdventOfCode" target="_blank">Twitter</a>
<a href="javascript:void(0);" onclick="var mastodon_instance=prompt('Mastodon Instance / Server Name?'); if(typeof mastodon_instance==='string' && mastodon_instance.length){this.href='https://'+mastodon_instance+'/share?text=I%27ve+completed+%22Handy+Haversacks%22+%2D+Day+7+%2D+Advent+of+Code+2020+%23AdventOfCode+https%3A%2F%2Fadventofcode%2Ecom%2F2020%2Fday%2F7'}else{return false;}" target="_blank">Mastodon</a
></span>]</span> this puzzle.</p>
</main>
......
......@@ -41,6 +41,7 @@ packages:
- advent04
- advent05
- advent06
- advent07
# Dependency packages to be pulled from upstream that are not in the resolver.
# These entries can reference officially published versions as well as
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment