diff --git a/Cargo.lock b/Cargo.lock index e7d3b91..7808695 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -257,6 +257,13 @@ version = "0.1.0" name = "day_8" version = "0.1.0" +[[package]] +name = "day_9" +version = "0.1.0" +dependencies = [ + "criterion", +] + [[package]] name = "either" version = "1.6.1" diff --git a/Cargo.toml b/Cargo.toml index 1aeb412..ba7f44f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "day_6", "day_7", "day_8", + "day_9", "day_10", "day_11", "day_12", diff --git a/day_9/Cargo.toml b/day_9/Cargo.toml new file mode 100644 index 0000000..e546cb9 --- /dev/null +++ b/day_9/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "day_9" +version = "0.1.0" +authors = ["Smaug123 "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +[dev-dependencies] +criterion = "0.3" + +[[bench]] +name = "day_9" +harness = false diff --git a/day_9/benches/day_9.rs b/day_9/benches/day_9.rs new file mode 100644 index 0000000..a20132e --- /dev/null +++ b/day_9/benches/day_9.rs @@ -0,0 +1,19 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use day_9::day_9::{input, part_1, part_2}; + +fn criterion_benchmark(c: &mut Criterion) { + let input = input(); + c.bench_function("day 9 part 1", |b| { + b.iter(|| { + part_1(&input); + }) + }); + c.bench_function("day 9 part 2", |b| { + b.iter(|| { + part_2(&input); + }) + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/day_9/input.txt b/day_9/input.txt new file mode 100644 index 0000000..f9aa9d9 --- /dev/null +++ b/day_9/input.txt @@ -0,0 +1 @@ +{{{{{{!>,},i!!,!>,<,{{{},,!!!>!!!>{"!>},},!,'>}}}},{{<{!!!>},!!!>!!e!a!!!!},u!>,!!u!!!!!>},!>,<{>}},{<"a!!!!'!>},!!,<,!>!>,}},{{ue>,{},,,{<'>}}}},{{<"a,!>},,,<',}>,{{!}!!!!!>!a!!!>!>!!a!!!!,!!u!!!>,<>}}}},{{{<{i!!>}},{{},,{}}}}}},{{{,{<>}}},{{{{},},<"u{!>,},}},{{{},<"u>},<'oa!!<,'!!"!!!!!>!!!!!>{!!!!aa>},{{!>!!!>!>!!!>'}!o{!!{>}},{,!>!!!!},<<}a}>}},{e!>,!!<{!!i!>,<>}},{{{},{},<"!!!>!>},,<,ea>}},{{<},"a"oeie!>},}},{}}},{{{}},{{<}e},<"!!e"<">},{{<'!!{!>},}},{}},{{<"oe!!!>"o{>},{{},,!!!!!>>},{}},{{{{!>,},,<>}},{}},{{{"i{''>},{{},{{},<"}<",!>>,{{},{{}}}}}}}},{{,,,},{,}}}}},{{{{{{}},{}},{{{"!!!!oa!>},<{a<}>,<'i"a!!!>>},{<"!"ea!}e!!!>!>},<}o{>,{,ie!{{!>},},<'!>},!!!>">}}},{{},{}},{{{},<}!>},<{!ae!>,,,'i!!>},{}},{<{!!!>!!!>a,!!!}!!!!}!>,}e}<{!!'!!!>!>},<>,,""e}}}},{{{{{},{,!>!!!>>},{{{{<,>}},<","!>},!>!i!>,<{!!!>}!>,{ou>}}},{{{},!u!!!>!>,{"<},{uo!!!>,}},{},{{{{{a{i{a!>,'>},<"{!!!>}!a!!!,<>}},{{{<>},{!,{{>,<{!!!>u!oi!"{''oo!!!o,i}ao,e>},{{<},},,<}!!!>!e}o!>},<<>}},{}},{{{},{!>},i!e"!!!>!!",!>},},<'!!>},{{<>}}}}},{{{<{"!>"!!e!"}>,{}},{},!!!}u!,<,{!!o!!!>!>,},{{{,<}u">}},{{}},{},,",!!!>""!!ee,!>},},,<,'!!aa!!>}}},{{{}},{{!>!>,<>},{<}a{i},<'!>,<"e{!>,!!u,!!!!!>>,!}!o>},{{{,">},{<,eoe>}}}},{{!>},,,!>u!!!>e'!>,>,,<<'i'!!!>a!!u!!!>>},{<,ui{>}},{{{{}},{<{!!!>,o">,},"}e!>},<>}},{},{}}},{{},{<>,{<'{u!>!!!>},<{!!!!!>i"!!>}},{!!!>!!!!!>!!u>}},{}},{{{<,!>!!!>!>,,<}!>},<,{{{},<,!!!>>}},<>}},{<<"a!!"!>,!!!>u>,{>}},{{}}},{{{{<,!>,,,},},}>},{{i>},{,}}},{{{{},{>,},<"!!!>!>e{e<",,!!!>!!i>}},{<}}!!!>!>!!}e!>,,<"}!!e}{>,{<}u>,,e,>}}},{{{{},{{{}!>o!,},<}!>,e!!aa<",!!'>}},<{'i!>!!!!u{}!!!>},}},{{,<'!{"!{!!!!ei!>>}}},{{{!!i!!!!!!!a<}"i}!>},}},{{a<>}},{},,!u}u>,{<"!!iu!!!>}>}}},{{<{i<,,{>},{},{{>},{,i!!{'u<""u!>o"{}!i!>}!!,>}}}},{{<{u!!!!!>"{!>!!!!!>!!!i!>aue{,<,>}},{{{{}}},{,e"},i!>},,{<"!!}!>,o!!!!"!!u{!>,}},{{{{<"!u!>},,>},{a}},}o}!>a!!},!!!>!>}!!!>,<>},{<{!>,>}}}},{{{<!!!>,},,}},{,,},,{<{!!!!!>},{!>,<},">}},{},<>,<}!!o!>!!!>a!!!>!{<'a!>,e!!!>u>}},{{},{{{<>},{e!!>}}},{{{a!!!>'!!a!!{u!!!a>}},},,!!!>},<>}}},{{{}}},{{o!!!>o!!!!eu{"}!o,e}>}}},{{{{<},,>}},{{},,>},{{},{{<,"!>},<>}}}},{{{>,{{},},},<,u<,},},<,{!!!!!>,}},>},{{{<,!>!>ou!!u!>,,,<{!!>},},e'u!>io!,>},{!!}!>},!>},!>,<'!>,>}},{{}}},{{{,<}'{!i}!>"!!u"a,a!!!><>}}}},{{{,<,,!>},<>},{},{{>},,},,,<,<>}},{{{{{!!!>"!"a!>,!>},},}}}}},{{{{},{{,},<{!!!>i!>},<>},{}}},<,uu>},{}}},{{{},{}},{{{<"a!>,<<{!>!>},<'!>!>,<,<}'!>!>,<>},{{}!!!>>}},{{!>!!!>},!!!>}}!ee!!!>!!!>,>}}},{{{{,<"!!{'}!!!!!>'!""!!!>!>u!!o}!>},<>}}},{,<>,{}}},{{,{,!!}i,!!ai!>},},}},{<{!>,,}},{{{{}}},{{{}},{<'!>ai,!>},oei!!!>"!>,<'!>},,{,,'!!!!!!!>!!e,!!}o<>}}}}},{{{{,,<}!>,}!>},i!>,<'i>}},{{e'i!!o!!}},{{{},<}{a!!!>,,'!!!>u">},e!>},,!!<"!!!>,<{u!>,},{<"}',!ui,!!!!!>>},{}},{{{,<'!!!>!>,},<,eu,>}},{<{"!>'"!>,<}!>,<,!!!>}o!!a!>ei'o>,{{}}},{{<<}!",},{{},{!>},},<>}},{{<},<},{<{!!!!,!>!>},},<'o},,<>}}}}},{{{},<,!,!>},>},{},{{,,">}}}},{{{{<<,!!!!!!!!!>},!!,'!!!!a!>,<>}},{},,},}},{{},{{{,{!!!'>},{{<"!>},},{eai!u}!>},},<<,ae>}}},{,<,<>}},{{<}!'!!o!!!>a'!!!>!>,<"!!!!!!"!!!>},>,{}},{!><{>}}},{{{<}!!,">}}}},{{{},{{{{{{<"i!>},<',!>"'!>"{!!"!>e!>u>},{<'}>}},{{<,i{>},{<{!aa}u!!!>!!!!ia'!>,}}},{<"!">}},{},{{<{o!,'}a!!u!>},<}"{<>},{!}!!'ea!>,!!!>},},<>}}},{{{},{{},!>},<>},<>}},{{}},{{,{<!!!!!>,!!e!!!!',{{o!>>}}}},{{{{,!!!>,},}},{{{<"u,,,<>},{uou!>>}},{<",!!!>,!>>,},},<>},{<},!>},}!>},!>,}}},{<>,<''!>,},<}}},{{{}}}},{{{{,},<>,{{!!!>}!oe!},u>},{{e<>}}}},{},{{{},,u}e}!!u">},{{{<}o'!>',!>},<{,''>},{{!>>}}},{!!!iaiu,<'!>},}}}},{},{{<{!,i!!!>,"i!!<"!!i!>,<>},{{},<{!>,u!!!!!>!!}uo!!!!a!>,<{">},{<>,{<<""oa!>},<}ao{i!a!!!>">}}}},{{{},{,!!i!!!!!>,},},}},{{{},!!u>}}},{{!>},">,{{,<"o}>},<">}},{{},!>!>>},>},{{{}a<>}}}}},{{{{}}},{{<'!>,,},<}>},{{{{<"!>o'e,eu!!i!!!!{!!o!>>}},{<>}},{<{!},<>}}},{{{{<>},uee!},{{iu}!>>}}},{}}},{{{}},{{{{},{},{'ea}>,o,a'!>,}},{<''{,}},{,<{oi!>},uaa!>},u!!>,},{}}},{{{{{}}},{<},<,e!>,<{}},{{{{}},{{},!!!>!>!!!>{!>,,,<'!>!!{>}}},{{},{{}}},{{{<"!a!>,},<,io!!!>!>,,!!!>},>},{{,,<'u!!!>,u!i!!"!!!>"!!">}}},{!!!>!>},<<>}}}}},{{{{{<'au!>,},>}},{,<{ii!>},!!>,{'aou{!>},}},{{{>},<"!>>}},{{!!!e>,!!}!>},},{{},{,{{},<},{}}}}},{{{<"!>!!u!>}i!!!>ua!>},},>},<,o!!!>},,},{,},<{'!>>,{}}}},{{{{a!>,<{>}},{}},{{ui!!}'e>,{}},{<"!!i!!,a!!!!ui,>,{<,!>},}},{{!>,<""o,"oo>}}},{{{{},{}},{},{{!>,!!!e!>{e!!>,{<{!!!i{"!>},,<>}}},{{,<,!!'>}},{},<"o"!>,}}},{{,<>,{<'>}},{{},},<!>,}}}},{{{<<!>,<}">},{{{{'{>}}}},{{<,e<>},{}}},{{{{},!>},<{!>u}!!!>{a<,!>'>,}}},{{{,},,<},o!>,"">},{{{}},}},{{{<>}}}},{{{{"!e!>">},!>!>,},{{{,},<"!>},<>,{}},{{<>},},!!i!>,},,i>}},{{<{i<"!!!>{!!aa!!!>!!!>ai!>'ui!{!!!>>,{<,<}!!!>!>!!{!!!>!iiu>}},{{},,'e>,,!>,},},!>,},<'>},{{,!!!!!>},<{<'!o},>},{,<{},<{},}},{,,,{<'!>},,!!""'!!a!>!>ui'!>>}}}},{<{!>,,>,{}}}},{<'!!!>,<>,<}i"!>,!!}!!"!>},!a!!iu">},{}}},{{{{{{{<{eee!!!>}!>,'>}},{},}},{{}!!'!!,o!>},<}o>,},},!{},,!u'u}o<>}}},{{<"'}',!a!!!,},!!!!u{!au>,{{},{<,,!!!>,<"!!>}}}},{{!!!>e!i,,>}}},{{{{{{},e!oa{}!>},<"}!,,,}},{{,{<">,{,,<'e{e!!!>!!!>},iu!!!>"!i>}}},{{<,!!!>},oa"!a!oa!!!>>,},,<"e!>,<}}},{{{!>,,<{!!!!!>i!>},<<"!>!!!!>}}}},{},{{{{},{{{'{'!!!>},},},},{{{{<!>},''>}},!>,!!!!!>},<,"}!e!!!!!>>},{{}}}}},{{{{{{}},<"i}>},{{<'a!>},},<>,{,i,!>},<'},>}},<,!>,,<>}}},{{},{}}},{}},{{{}},{{},<{!>i"'!>!!!!,}}},{{<"!!>,{},}{!>},<}!!{!>,}},{>,i!o!!!!}"!!!!u{!>},<'!>!},<>},{{},!>,,},<{{a>}}},{{{!!!a!i!>,},<>}}}},{{},{{},{}}},{{{{<,!!!>!!!!"}!>},,},<}>},},oeo,!!{o},{{},{},i,>}},{{{{,,<>}},{}},{{{}},!>,,<{>}}},{{{},{{{{}},{},<>}},{}}}},{<!>!!!>!!eiu>,,<},<,!!!>'{'!!"ao}u!!!>'o>}}},{{},!!!>},<'>,{a!!!>,>}}}},{{{{,<">},{{{},{<>,!>},<}!!!>!!!!!!!>!>,<>}}},{!!!eao!>!!!>i<{o!>,},}},{{},{{{}},{{{},{!!!>!o!!eu!!<}},{{{<"!!!>!>"!e!>e"!!eu!>},},<'>},},<{!>},},<>}},{{{}}}},{{},{{{{<"iu!!!aoo,!">,!!!>,!>,,,>},{{<}!>},!!!>},}},{{a!!{,!!!"!>,<"i!!!a}!''>}}},{},{{{{},{!<,}}"o!!!!!>},<<}!!!>',>}},{,!u!>{!}!!e>}},{{eo>}}}}},{{},{,!i,'!!!>e"aa!>,<>}}}},{{{},{{}}},{},{{}}},{}},{{{!,u}!>uo!>},<,"},},<>},{{}}},{{{},<},,},<'<>}},{{{},{{',,!"!>eia!>},,<{<,>},,<>},{{},{,<,'i!!!!,!!!>i!},<,!>},<>}}},{{!!}o!>},!!!>e,{!>},,{{},<>},eea!!{!>},!!!>,<>}},{!>},!>,uee'>},{{i!!e!!!>>},},,<{!>},e!>eu!!!!!!!!!>,},<'!!>}},{{{'ooeaa!>,<{>}}}}},{{},{!uo!!o}}},{{{{<>}}},{{{{}},{{{">},{}},{{},<<>}},{{}}}},{{{{{{{{},}}},{o!!o!!{o!!u{>}}},{{},{<,!!ueua,{o{!!!>,<<>}},{}},{{<>},<}'!>,>}}}}},{{},{{{!!!>!>!>,},,,{<'!!!>,<,},,}}},{{{<}!!,!!!!!>!>},}},{{<>},{!>u>}},{{},{{<,"!!!>!!{>,},<},{u}'!!e!"{''o>}},{,}}},{{{<}>,{!>},,>}},{},{,,!>},,<'!!'!>},}},{{{{{{{{iu!!',!>},,<>}},{{,>}}}},{!>,}}},{}},{{{<},<}{!!auo!!!!!>},>},{{},{},{{{},<'{oi>}},"!>!>},,>}},{{},{{{}}},{{{,},!>,},,>},!>u!!a>}}}},{}}},{{{{e}'"oi!!!>a"!>,},{<'}>},{<"!>},<,{!u!i!e!!uee!i!!a"u{>}},{<{{!,!u!!,!!<"!!{>,{}}}}},{{{{!!!>,'!!,>},<>},{{{}}}}}},{{{<>},{<>,,},},{<{>}},{{{},<>,<,''e{!!{i!!'>},{{!e}!>,,<{>}},{},!!,a!!'!!}e'!e!>},,,{<,!!a,aoo!>!!,{!>},}!!,o!'>,<>}}},{{},<}u!!a>},{{{{{<',},},}}},{{o!'o!>,!>},!>,<>}}}}},{},{{{o!>u!!!>!>>},<>},{{<,,>},<'{ao!i,!!!>e!ua"{!"!!!>>},{<"!>},e",'!!!>},<'oo!!!>!>>}}},{{{>,{<{!!!!!>}!!!>a!<}!!ea!>!!>,{,<,!>},,}}}},{{{i!!u,!i!i>},{{}>},},,,a!>>}},{{},,<>},{{i'o!!"">},{<">}}},{{},<}!!!>"i!>!!!!u!!!>"!{u'!!e'!!"!!>,<},{<"!>!>,<,!!>},{}},{{{{}}},{{},{<,!!!>u>}}}}},{{{{},<}!>ia,!>!>},},<>},{{<>}}},{{'},<,>},{}},{{{{{{<>},{,}},{{{<,o!!{!>"i!>!},<,>}}}}},{{},'!!e"">,{<},!!u!>,,<"'!!!>!>>}}},{{!!!>!!!i!o!!{!!e!!"u!iaa!>,<}o,}ao>}}},{{{,o}a!!}ui!!!!!>!>},>},{,{}}},{{{},{},},<,,!"'!>,<>}},{{<"!>},,!{,!}e!!!u!}!o>},{,<{{o},<'>}},{{}}},{{}}},{{},{},{<{!!!>,},<'!!!!o!>},}!i>,{}}},{{<}!!!>},,{}},{{<},!>},,<'!!!!e!>!>,<"},},<>,{<<}<>,{}}},{{},}},{{<{},},,},,>},{<>}}}},{{},{{!!!>o!!!><'{'!!!!!!},i'"uu>},{{{},},<'!!!i}!>}!!!>!>u!"!!!!}!!!>!"!>'!>,<>}},{{!e!!!!a'!!!!}o'},,,<>},>}}},{}}},{{{}},{{{},{{},},<,!>},{!!{i!>},},,<>},},<}!!!>u!i"},<>},{{,}{!>},},{{>}}}}},{{{},{{<,oi"a>}}},{{{"{e!>,},<}<,e>}},{,,<"!,o!!!!'!!e',>}},{{"u{>,{<}!},}!>,!!,,e}<,{!>>,{}}}}},{{{{<"!>},<"a!>},!!!!a}"<}!!!>!!!!!!"!!!!!>,>},},{{,}}},{{{<>},{iu!!!!{!>},<>}},{{{},,{{}}},{{!!!>,>,<,<ui,!!!!!>,},<}!!!>>}},{{},{{{{},{e!>e>}},{!o!>},,{}},{{{{},i!!o!>},!>},'>}},{}}}},{{},},},},{{}}}}},{{{{},{<'ua,}},{{},},,<>},{<{e!!!>!!!>},<{{>}},{{<}e!!}!!!>},<>,{,{<>}}}}},{{{},!!!>{'!!!>ia!>,},<>},{,i>}},{{},},}},{{{<'u"o!!!>a!!!>,},<,!}!,{>,!>},!!!>a!>,},}},{},{},<<{}!>{!o"!>,!>,},<>}}}},{{{}},{{{<>,{{<}'i!!o}!!{!!!>}!!}!>},<{>}}}},{{,!,!>},<{'o!!!,>,{}}}}},{{{}},{{,<},!!!!!>uo}}i!>,!!o!>,<,!!">},{,}},{{,<'u!!!>!,u{""!!{}!!!>,<>,{{{{},{<'oea!e!!,oe!>},}},,,<>},{}}},{!>},}}}}},{{{},{{{{},<,!!!>},<"o!!!>a!!!>!!,!!!!!>e>,{,>}},{{{<>}},{{{},{!!""!>,o!!!>!!i!>,<>}}},{{{<}ua!>},},ee}a>}},{},,<>}}},{{{}}},{{{e">}},{{{{{}}},{{!{!!!>>}},{{{{!!!!!!e!>,<"!!!>},,},,,},{{},u,},{},,<>}}},{!!'u,aao!>{!>,<>,<'"'!{!>!!u!!!>ia"!!!>u!>},},{{{}}}}},{{,<{!!!>},},<"}a!!!>!">},<{!!}u}!!!>>}},{{},!>},},},<>},{>}}}},{{{{},,{},!>},,u}{>},{{},{<>},{}},{{},{{},{}}}}},{{{},{{{},{{{"!>},!>},},{!>!i!>},}},{{<'!>,},"!>"ou>},!!!!!!!!ae!>,<'!>},,<,!>},<{!>,,!>},<>},{{!!{,i"!>!>,}}}},{{{<>},<'!>a>},{>,{{{!>,<{oe},{ea{!>!>,<>}}}},{{,o'!!i"<"!>,!>,}}},{{{!!>}}}},{{{!>,!!eu>}}},{{},!>},<}o}>},{{<}o,!e!!!>,,,{>}},<""u!>,<>},{}}},{{{{{{<<>},{!!e}'"!>!!!>i{!>},<>}},{}},<>}},{{{},{{<!i},},{<}}!>!!!>!{!<<{{e!!!>!!,e"!!!!{,>}}},<{!!!><'>}},{{{{o},},},<{!>,},<>},{{},,{,<,!>>}},{!>},,<{<'!'},<>}},{{},{{{},},,<}!,!>!!uu!!!!u!>},},o}!!!>!>,'i}>},<<}a>},{{<>},{}}}}},{{<}}io,<>},{'>}}},{{},{{{},{,<{'!!!!!>e},<>}},{{{"u!>},<}u!!e>}}},{{{{{},o!>o!!u{{>},{}},{,ai!o!>,,,{<,u!!a!!!!uu},<}},{<,!!{!!i,a!!''ue!!"!>i,!}!>,<,a!<>}}}},{{!!"u!>,,<>,{}},{{<,,u">},{{},},<}}o!>},<<>,{{{,,<"!i!!!>a!!"o<{>,{ueo!">}},{},!!!>>,{}}},{a!'}a!>e!!,!>,<>}}},,}},{<}a!>,},"<<>,{}}},{{<{{a"!}{>},{{},{!>!!!>i!>,ea,>,{,<"i!>a"!!<,,ii'>}}},{{"e!!},,{{{},{{<'!>},!!<,},},},}}}}},{!>},<>}}}}},{{{{},},}},{,<<"!!}!!!{!!<<{!'e!!!!!!!!>>,{{<,!>},ia!!"o!!!!!>}>}}}},{{<"!>,>,!>,<{!{!!i!!!>,,<"i},!>!>,!!o>},{},<{!!i!>,<,,!!!>,>},{!>!a{'!!!>>,,}},{{{{{},!e!!!!ia}{!>},<{o!>,,<{<"e>},<>},{}},{{},,{!!e},{},},,},,>}}},{{{{<'>}}},{},<{e!!!>,<>,{{{},<"!!!>!>},<"a>},}e}}!>!>o!>},}},{{<>,{<,o{!"!!!>eu!>},<"a>}}}}},{{{{{},},<u!!!>!'!!u'!>,<},,{}},<}!!!!!>!!!>},{},<,!>},<}!!ia,!!!a!!"!!'!!!>ea>,{{{,<"ea"!!!>io!!!!!>},<>}}}},{},i,,<}>,<<}o!>},},<>}},{},{{},{{!>},,!>,,},,}},{{<{!>},}}},{{{,<>}},{<,{}}}},{{},{{},{{,<"a},'<"o>}}}}}},{{{{{<>},{<}!!a,}!!!>!>,<"!!!>u!!!>>,<},!!!>oe!>},<{u!>,<'>}},{},,,,}},{{{{{},,},,{{>,<,,o!>,>}}},{,,<>}},{{{},,>},<}!!i!!!>!!!>},>},{{{},<>},{},},<}!!!>,}},{{,,<>},<},!!!>ee!>},},},{}}}},{{{<<''o!>,<}>,{{!>},>}}},{{{<{}!>},{a!!}<<'>},{}}},{{}}},{{{{},{{{!!,},{>,{,,>}}},{o>}},{{,,}},{},,!!!>u!!!>"!!u>,{}}},{{},,{<,!i!!!!!!uoi>}},{<>,{<}{,u!!}}},{<>,{,!>!!>}}}},{{}}}},{{<,o>,{<>}}},{{{{{{},{{{,}},{,<>}}},<},},,},{{},<"!!!>,!!!!}}},{},{!>>,{aa!!!!a!}e,"!>,<}<},}},{{},{}}}}}},{{},{{{{{{{}}},{<>}},,,},},},{{<'!>,},},<<>}},{{u!}!>},!}>},{u>}}}}},{{{{},{<}u"i!!!>!!a!!u!!a{u'!!e<>},{{<>}}}},{{{{{}}},{<>,{!i,}ie!!u!>,,,<>},{{{},{}},{}}},{{<"}!!"!!!>"""!>,<>,{<"!!!>},},<{'a}!!a!!!>eo{!!!!!>!>,<,>}},{,{}},{,,!>eo!!!>",}},{{{{{<>}}},{,},,a!>>}},{,>}},{{{{},{!>!>!>},,<,,!u>}},{{{{<,o!>a>,,}!!i>},{<{>,<"',e!!!>},{!>},,<}u!>},},{{},{<>,{}}}},{{<"!>,u!>},<>},{{{<{!>!!"i!>,<<"!>i!!"a}}"i>}},{{},,},'<>,{{}}},{{}}},{},<}a>,{{},"u>}}}},{,<,<>}},{{{{o!a<}!>">},{}},{{},{{!!!!{,{"!!}'!!,<>}}}}},{{{{},!!!!i!!a}o!!u!!'!>,<{!,ouo,e>},{},,,}!>!!!><>,{{o!!!>{},<>},{<}{o!,a!>!!!>>}}},{{},<>},<"ou"!>},>}},{{<,>}},{!!!!!>},}}},{{{<}o!!!>},<,}a!}e!!!>'>},{}},{<{"{!!{!!,>},{{{,<>,{}},{},>,{,<"e{!>,,,<,}},{e{},},,{}}},{}}},{{{,{<'{!!}e},,,<>},{{},{}},{{},{'!>},!!!>u<{!u>},{{{}},{{},{{},{<!>>}}}}}},{{{{<"u!>},>,{}}},{{<"!>",,>,{'u!>'<{u!>u>}},{{,,>}},{{{!>,},!>,>},{<{,"!!"'i>}}}},{{{{{},{i,},<,>}},{}},{{>},{{,},o!>},},!>},}},{<<"oie!>},!!u,{}}},{'!!!>"o,u}>},{{{{}},{{},},<!!!<"!>,<}!!!>>},{,{<{e!!!>'!!!>'!!e{ue'!!o!!!!!>!!!!!>!>,<<>}}}},{<{!!!>u!!!!u!!!!'>,<}{i!!,o">},{<"ea""!>e}!>,<},<">}}},{{{{<>},{}}}}},{{{!!,!>},<''ue,>}},{'{o!>!!!!!>!!">,<<}o!o{!>},},{{},>},},<{'o!!,,"'>}}},{}},{{{!>},<{!!>}},{!!!>},,{}},{{{},uu>}},{{{<,!!!>!!}"!>},<{'!>!>a}!!a!!'a!>{>}},{{{{}},{{}}},<},{{<'>},e},!!<<>}},{{<,e{!!!>a!!},<"!!}iu!!}!>i<>}}}}}},{{{},{{{},{{{}}}}},{{"!>i!!>,}io!!!>!>,<,},u!!!>>}}},{{{{o'!>i!!a!,!!>}},}},{{{{{{<,!>,,<,'>}}}},{{<'u'!!'"!aou{e}!!!>,<<>},<{a!>,},'!o}>},{}},{{{e>},{{<>},{}}},{{{}},<,!>,<>},{{{<"'{i,'!!!>,<"!>,,!i>}},!!aui!!}>}}}},{{"!!{<>},{{<>},<"!>},<{}{e},>},{{},<},>},{!>!!"iu!!a"u}>}}},{{{{,},<'a!>,>},{,,,}},{<{"!},},<,u,!>,},}}}}},{{{{},}"!>!!i"e!!!!>}}}},{{{{!!},{,}}},{{{{<'{i>}},{}}},{{}}},{{{}},{{{{{{},{},<}!!!!e{!},i>}},<}{>}},{{<',!>},},e!e}>}}},{{<'e!!'!>}}>,,!}',!!u{iei!}},{{}},{{{{},<{!>},<''i}{!u!!!>!>,}}}}}},{{{{{{{<"!!!!}u"o!>},!>},},}},{!!!>},,<},<{!>},<>}}},{{<'e!!a'!>},}},{,<,o,}{!!">}},{},{{{{{>,{}},{},!>},<},!!!!}i!!,!>},ao!!e'<}>}},{{{<}>},u">}}},{{},<,},!!!>},},},{}},{{{{},{{{<,'{'}!!!!e!!{>},{<,!a'a!,!!!>>}},!!!>,}!!}'>},{,<,!e,{<>}}},{{}},{{<>}}},{{},{}},{{{{<"i{}'!>},<{,"{!!!>!!oe{{o>}},{{},{!>!!!>!<}"!>>}}}},{{{},{<},<{>}},{,},<,{i>,,,<},!!!!!!!>"ua!!}>}}}}}},{{},{{{},{{{},{"!!!>o{'!!u"!!"!!!!!!',>}},{},,!!!>ea>,{}},{{{<,'{"e,!>},>},{},<}{!>,},o!'!>!!!!>{uo>}},,!}'!!{!u"a>}},{{aue"!>},<>,},{!!!!!>>},{{}}}},{{{{,},<{i!!!>i>}},{{<'a}>},<{i"!!a!a"!!!!!>'!>,<!>},<{>},{}},{{{"!>,<'!!}e"a"a!>,},<"}>,{},!!"",!!}},{{{!!!>!>},<,!,!!!'!a!!<>}}},{{,<'!<>},{}}},{{{{{},>}},{}}},{{ee},,<>},{<}}iu!>},i!!!>!>!!>}}},{{{{}},{,},},{}'>}}},{{!>,!>,,{!>!>oi{!!>}},{{<},{}},{{{}}}}},{{{},{{<'"!!>},{}},{{'"!!!>i'>}}}},{{{{<"}!>i!!o!!!>u,!>!i!!!>ii>},,},,<>},{{},<},u!,<<>},aiu!>!!!!e!!!>,!!>}},{{,},},<,u<,}!>},,{{},{}}},{}},{{{{<",>},{<>}},{'i!!!>,}}}}},{{{}},{}},{{{,,},i>},{<,<}}ao!>},},>}},{{{!}!!'"!>,<<"!>,'>},{}},{{{'u!!{!!!>e}'o!e!!!!!>o>},{<"!!!>}!!'!!!uooeo!a!"!iio!!>}},!u!"{,!>!>!>},},{},{!i!!!!auo}},{<"'!>},<{e!!!>!!uu!>,,{},,},<>}}}},{{{},},{{}},{{{}},{<!>,,,<'!>"!!!>{>}}}},{}}} diff --git a/day_9/src/lib.rs b/day_9/src/lib.rs new file mode 100644 index 0000000..29465a8 --- /dev/null +++ b/day_9/src/lib.rs @@ -0,0 +1,247 @@ +pub mod day_9 { + + #[derive(Debug, Eq, PartialEq)] + pub(crate) struct GroupIndex { + pub(crate) i: usize, + } + + #[derive(Debug)] + pub(crate) struct Group { + pub(crate) entries: Vec, + } + + #[derive(Debug)] + pub(crate) enum GroupEntry<'a> { + Garbage(&'a str), + Group(Group), + } + + pub struct Stream<'a> { + pub(crate) groups: Vec>, + pub(crate) head_group: GroupIndex, + } + + impl Stream<'_> { + fn cata_inner<'a, 'b, T>( + entries: &'b [GroupEntry<'a>], + head: &GroupIndex, + depth: usize, + at_garbage: fn(&'a str) -> T, + combine: fn(&mut dyn Iterator, usize) -> T, + ) -> T + where + T: 'static, + { + let e = &entries[head.i]; + match e { + GroupEntry::Garbage(s) => at_garbage(s), + GroupEntry::Group(Group { entries: e }) => { + let mut v = e + .iter() + .map(|i| Stream::cata_inner(entries, i, depth + 1, at_garbage, combine)); + combine(&mut v, depth) + } + } + } + + pub fn cata<'a, 'b, T>( + s: &'b Stream, + at_garbage: fn(&'a str) -> T, + combine: fn(&mut dyn Iterator, usize) -> T, + ) -> T + where + 'b: 'a, + T: 'static, + { + Stream::cata_inner(&s.groups, &s.head_group, 0, at_garbage, combine) + } + } + + pub(crate) fn parse<'a>(s: &'a str) -> Stream<'a> { + let mut iter = s.chars().enumerate(); + match iter.next().unwrap() { + (_, '{') => {} + (_, c) => { + panic!("Group didn't start with open-brace, but '{}'!", c); + } + } + let mut groups: Vec> = vec![]; + let mut stack: Vec> = vec![vec![]]; + + let mut garbage = None; + let mut skip = false; + + for (pos, c) in iter { + if let Some(start) = garbage { + if skip { + skip = false; + } else { + match c { + '!' => { + skip = true; + } + '>' => { + groups.push(GroupEntry::Garbage(&s[start + 1..pos])); + let constructing_group = stack.len() - 1; + stack[constructing_group].push(GroupIndex { + i: groups.len() - 1, + }); + garbage = None; + } + _ => {} + } + } + } else { + match c { + '<' => { + // New garbage. Consume up until the next non-cancelled '>'. + garbage = Some(pos); + } + '{' => { + // New group. Consume up to the next non-cancelled '}'. + stack.push(vec![]); + } + '}' => { + let entries = stack.pop().unwrap(); + groups.push(GroupEntry::Group(Group { entries })); + match stack.last_mut() { + None => {} + Some(l) => { + l.push(GroupIndex { + i: groups.len() - 1, + }); + } + } + } + ',' => {} + c => { + panic!("Expected a known character, got: {}", c); + } + } + } + } + let max = groups.len() - 1; + Stream { + groups, + head_group: GroupIndex { i: max }, + } + } + + pub fn input() -> Stream<'static> { + let input = include_str!("../input.txt"); + parse(input.trim()) + } + + pub fn part_1(numbers: &Stream) -> usize { + Stream::cata( + numbers, + |_| 0, + |v, depth| { + let mut sum = depth + 1; + for i in v { + sum += i; + } + sum + }, + ) + } + + pub fn part_2(numbers: &Stream) -> u32 { + Stream::cata( + numbers, + |g| { + let mut skip = false; + let mut ans = 0; + for c in g.chars() { + if skip { + skip = false; + } else { + match c { + '!' => { + skip = true; + } + _ => { + ans += 1; + } + } + } + } + ans + }, + |v, _| { + let mut sum = 0; + for i in v { + sum += i; + } + sum + }, + ) + } +} + +#[cfg(test)] +mod tests { + use super::day_9::*; + + #[test] + fn test_empty_parse() { + let result = parse("{}"); + assert_eq!(result.groups.len(), 1); + match &result.groups[0] { + GroupEntry::Group(Group { entries: e }) => { + assert_eq!(e.len(), 0); + } + e => { + panic!("Wrong match: {:?}", e); + } + } + assert_eq!(result.head_group, GroupIndex { i: 0 }); + } + + #[test] + fn test_triple_empty_parse() { + let result = parse("{{{}}}"); + assert_eq!(result.groups.len(), 3); + let (zero_count, one_count) = Stream::cata( + &result, + |_| panic!("No garbage"), + |i, _| { + let (mut zero_count, mut one_count) = (0, 0); + let mut my_count = 0u32; + for (z, o) in i { + zero_count += z; + one_count += o; + my_count += 1; + } + match my_count { + 0 => (zero_count + 1, one_count), + 1 => (zero_count, one_count + 1), + l => { + panic!("Unexpected count: {}", l); + } + } + }, + ); + assert_eq!(zero_count, 1); + assert_eq!(one_count, 2); + } + + #[test] + fn part_1_known() { + assert_eq!(part_1(&parse("{}")), 1); + assert_eq!(part_1(&parse("{{{}}}")), 6); + assert_eq!(part_1(&parse("{{},{}}")), 5); + assert_eq!(part_1(&parse("{{{},{},{{}}}}")), 16); + assert_eq!(part_1(&parse("{,,,}")), 1); + assert_eq!(part_1(&parse("{{},{},{},{}}")), 9); + assert_eq!(part_1(&parse("{{},{},{},{}}")), 9); + assert_eq!(part_1(&parse("{{},{},{},{}}")), 3); + } + + #[test] + fn test_day_9() { + let input = input(); + assert_eq!(part_1(&input), 16869); + assert_eq!(part_2(&input), 7284); + } +} diff --git a/day_9/src/main.rs b/day_9/src/main.rs new file mode 100644 index 0000000..3003187 --- /dev/null +++ b/day_9/src/main.rs @@ -0,0 +1,7 @@ +use day_9::day_9; + +fn main() { + let input = day_9::input(); + println!("part 1 => {}", day_9::part_1(&input)); + println!("part 2 => {}", day_9::part_2(&input)); +}