From b2403eb6b6df07d405562650bc5df07cde035c3a Mon Sep 17 00:00:00 2001 From: red Date: Sat, 16 Mar 2024 19:24:59 +0100 Subject: [PATCH] Year 2016: Day 09 --- CHANGELOG.md | 4 + Cargo.toml | 5 +- NOTES_2016.md | 8 ++ README.md | 2 +- benches/year_2016.rs | 16 +++- benches/year_2016_day_09.rs | 136 ++++++++++++++++++++++++++++++++++ inputs/year_2016/day_09_input | 1 + src/year_2016.rs | 14 +++- src/year_2016/day_09.rs | 73 ++++++++++++++++++ 9 files changed, 255 insertions(+), 4 deletions(-) create mode 100644 benches/year_2016_day_09.rs create mode 100644 inputs/year_2016/day_09_input create mode 100644 src/year_2016/day_09.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d6be4f..f43788b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ Of note: - The changelog 2015.5.2 has been rewritten from each commit content. - This file may be amended entirely in the future to adhere to the [GNU Changelog style](https://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html#Style-of-Change-Logs) +## [2016.9.1] +### Added +- Solved [exercice for 2016, day 09](src/year_2016/day_09.rs). + ## [2016.8.1] ### Added - Solved [exercice for 2016, day 07](src/year_2016/day_07.rs). diff --git a/Cargo.toml b/Cargo.toml index a0a79af..5ebac6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "advent-rs" -version = "2016.8.1" +version = "2016.9.1" edition = "2021" authors = ["Arnaud 'red' Rouyer"] readme = "README.md" @@ -57,3 +57,6 @@ harness = false [[bench]] name = "year_2016_day_04" harness = false +# [[bench]] +# name = "year_2016_day_09" +# harness = false diff --git a/NOTES_2016.md b/NOTES_2016.md index b5ab85d..3bc0e00 100644 --- a/NOTES_2016.md +++ b/NOTES_2016.md @@ -38,3 +38,11 @@ Some iterators are annoying, but sometimes, like when calculating whethere there I wouldn't call it an "object model", but I like the way Rust works with `impl X for Y`. Also, remember the [`splice()` method](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.splice), it's very useful to replace large parts of a vector at once. + +## Day 09: Explosives in Cyberspace + +I knew the Rust version would be faster than my [Ruby implementation](https://github.com/joshleaves/advent-rb/blob/master/year_2016/day_09.rb), but I still felt I wasn't fast enough. I compared myself to [galenelias's implementation](https://github.com/galenelias/AdventOfCode_2016/blob/master/src/Day9/mod.rs) and indeed I wasn't fast enough. + +I went back to the workbench to try another implementation, and to my delight, I was the faster. But still not faster than [fornwall's implementation](https://github.com/fornwall/advent-of-code/blob/main/crates/core/src/year2016/day09.rs). + +Looking at it carefully proved very smart: both galenelias and me lost too much time **creating a string, then getting its length**, when the exercise only asked to **get the string's length**. diff --git a/README.md b/README.md index 6ff609d..a8ca7e7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ As I said, [Consistency is hard](https://github.com/joshleaves/advent-rb), and I I'm also adding notes that may be useful if you're (like me) discovering Rust: - [2015, complete!](NOTES_2015.md) -- [2016, up to day 08](NOTES_2016.md) +- [2016, up to day 09](NOTES_2016.md) # Regarding style rules I'm gonna use a mix of what `cargo fmt` does, with some stuff that feels more natural to me. diff --git a/benches/year_2016.rs b/benches/year_2016.rs index b628235..5952ae5 100644 --- a/benches/year_2016.rs +++ b/benches/year_2016.rs @@ -6,6 +6,7 @@ use advent_rs::year_2016::day_05; use advent_rs::year_2016::day_06; use advent_rs::year_2016::day_07; use advent_rs::year_2016::day_08; +use advent_rs::year_2016::day_09; use criterion::{black_box, criterion_group, criterion_main, Criterion}; pub fn year_2016_day_01(c: &mut Criterion) { @@ -104,6 +105,18 @@ pub fn year_2016_day_08(c: &mut Criterion) { g2016_day_08.finish(); } +pub fn year_2016_day_09(c: &mut Criterion) { + let mut g2016_day_09 = c.benchmark_group("year_2016::day_09"); + let input_year_2016_day_09 = include_str!("../inputs/year_2016/day_09_input"); + g2016_day_09.bench_function("year_2016::day_09_v1", |b| { + b.iter(|| day_09::day_09_v1(black_box(input_year_2016_day_09))) + }); + g2016_day_09.bench_function("year_2016::day_09_v2", |b| { + b.iter(|| day_09::day_09_v2(black_box(input_year_2016_day_09))) + }); + g2016_day_09.finish(); +} + criterion_group!( benches, year_2016_day_01, @@ -113,6 +126,7 @@ criterion_group!( year_2016_day_05, year_2016_day_06, year_2016_day_07, - year_2016_day_08 + year_2016_day_08, + year_2016_day_09 ); criterion_main!(benches); diff --git a/benches/year_2016_day_09.rs b/benches/year_2016_day_09.rs new file mode 100644 index 0000000..4e5628b --- /dev/null +++ b/benches/year_2016_day_09.rs @@ -0,0 +1,136 @@ +use advent_rs::year_2016::day_09; +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; +use regex::Regex; +use std::time::Duration; + +// This snippet was taken from fornwall +// SRC: https://github.com/fornwall/advent-of-code/blob/main/crates/core/src/year2016/day09.rs +fn fornwall_uncompressed_size(text: &[u8], recursive: bool) -> Result { + let error_mapper_uf8 = |_| "Invalid input"; + let error_mapper_parse = |_| "Invalid input"; + let mut start_parenthesis_idx = None; + let mut uncompressed_len = 0_u64; + + let mut i = 0; + while i < text.len() { + let c = text[i]; + if c == b'(' { + start_parenthesis_idx = Some(i); + } else if c == b')' { + if let Some(from) = start_parenthesis_idx { + let inside_parenthesis = &text[from + 1..i]; + let parts = inside_parenthesis + .split(|&c| c == b'x') + .collect::>(); + if parts.len() != 2 { + return Err("Invalid input".into()); + } + let chars_to_take = std::str::from_utf8(parts[0]) + .map_err(error_mapper_uf8)? + .parse::() + .map_err(error_mapper_parse)?; + let repetitions = std::str::from_utf8(parts[1]) + .map_err(error_mapper_uf8)? + .parse::() + .map_err(error_mapper_parse)?; + uncompressed_len += repetitions + * if recursive { + fornwall_uncompressed_size(&text[i + 1..i + 1 + chars_to_take as usize], true)? + } else { + chars_to_take + }; + i += chars_to_take as usize; + start_parenthesis_idx = None; + } + } else if start_parenthesis_idx.is_none() { + uncompressed_len += 1; + } + i += 1; + } + + Ok(uncompressed_len) +} + +// This snippet was taken from galenelias: +// SRC: https://github.com/galenelias/AdventOfCode_2016/blob/master/src/Day9/mod.rs +fn galenelias_decompress(mut input: &str, recursive: bool) -> String { + let mut result = String::new(); + let repeat_regex: Regex = Regex::new(r"([^(]*)\((\d+)x(\d+)\)").unwrap(); + + while !input.is_empty() { + if let Some(m) = repeat_regex.captures(input) { + let rep_len = m.get(2).unwrap().as_str().parse::().unwrap(); + let rep_count = m.get(3).unwrap().as_str().parse::().unwrap(); + let match_end = m.get(0).unwrap().end(); + + // Push the prefix into the result + result.push_str(m.get(1).unwrap().as_str()); + if !recursive { + result.push_str(&input[match_end..match_end + rep_len].repeat(rep_count)); + } else { + result.push_str( + &galenelias_decompress(&input[match_end..match_end + rep_len], true).repeat(rep_count), + ); + } + input = &input[match_end + rep_len..]; + } else { + result.push_str(input); + return result; + } + } + + return result; +} + +pub fn bench_year_2016_day_09_v1(c: &mut Criterion) { + let mut group = c.benchmark_group("year_2016::day_09_v1"); + group.warm_up_time(Duration::from_millis(100)); + let input = include_str!("../inputs/year_2016/day_09_input"); + + group.bench_with_input( + BenchmarkId::new("fornwall", input.len()), + input, + |b, input| b.iter(|| fornwall_uncompressed_size(input.as_bytes(), false)), + ); + group.bench_with_input( + BenchmarkId::new("galenelias", input.len()), + input, + |b, input| b.iter(|| galenelias_decompress(&input, false)), + ); + group.bench_with_input( + BenchmarkId::new("joshleaves", input.len()), + input, + |b, input| b.iter(|| day_09::day_09_v1(input)), + ); + group.finish(); +} + +pub fn bench_year_2016_day_09_v2(c: &mut Criterion) { + let mut group = c.benchmark_group("year_2016::day_09_v2"); + group.warm_up_time(Duration::from_millis(100)); + let input = include_str!("../inputs/year_2016/day_09_input"); + + group.bench_with_input( + BenchmarkId::new("fornwall", input.len()), + input, + |b, input| b.iter(|| fornwall_uncompressed_size(input.as_bytes(), true)), + ); + group.bench_with_input( + BenchmarkId::new("galenelias", input.len()), + input, + |b, input| b.iter(|| galenelias_decompress(&input, true)), + ); + group.bench_with_input( + BenchmarkId::new("joshleaves", input.len()), + input, + |b, input| b.iter(|| day_09::day_09_v2(input)), + ); + group.finish(); +} + +criterion_group!( + bench_year_2016_day_09, + bench_year_2016_day_09_v1, + bench_year_2016_day_09_v2 +); +criterion_main!(bench_year_2016_day_09); diff --git a/inputs/year_2016/day_09_input b/inputs/year_2016/day_09_input new file mode 100644 index 0000000..78812ed --- /dev/null +++ b/inputs/year_2016/day_09_input @@ -0,0 +1 @@ +(8x10)SBTLHXZP(141x10)(20x4)PSFDROQLSZCXJYTATIBY(2x9)NN(60x14)(3x15)WUO(2x13)WF(10x14)KRXBNHFEGQ(20x4)SWJUMHNRCRJUPDVFAKMI(35x8)(3x14)VZB(8x15)SWKZSEFU(7x1)FZTLTXZ(152x12)(59x6)(1x14)L(13x7)RYXYIAVOQLUDZ(9x13)RJEZMXTNT(1x8)J(7x5)YNAMBOU(1x4)M(65x10)(6x9)FZGSZU(20x15)JOUTNIFMADHRELAZAZXB(4x4)KDHA(12x7)VFVYZLBLKRGG(3x15)SWDGEUSLFVHBFOQCIQFDID(7506x15)(3157x7)(102x1)(95x15)(20x3)(2x6)OJ(7x12)WANSMOE(37x2)(12x2)(6x13)GFVIEP(12x11)XJNOGCDLPZFK(10x6)NZJQDFALQG(4x11)CIRV(527x9)(147x1)(28x7)(22x1)NUVOZARNIUATLYTIIBQQCZ(1x13)X(99x13)(5x15)DVHUQ(74x9)(10x11)JIFYQWJEUE(12x3)ASUFBLKRTQHO(15x3)XSUQBRFDBBILDCE(7x3)SIPAZDJ(1x7)P(3x5)JDH(366x1)(134x10)(12x15)AMZJNEATLPHT(11x5)QLFEIZHQWBC(67x15)(26x12)MMVLATJFCZAVYSWAYBOGXRWACU(27x15)JMSRLPUKKLTVSCAHINZDILQLLUW(18x5)(12x4)LQVHBCGOJYZA(26x10)(19x15)IMYPOULMTQNCVKTTSNV(184x9)(106x8)(23x11)WDRSSBUPTKPJTCWQAGZSRBZ(7x1)TPVSVAQ(11x2)AHULHRROCYJ(2x3)CH(34x7)QXUWECQBZLYQHWTQTNRXQCQYCLBROFJYQO(65x4)(16x5)OGMUNBWDIPYGQHRL(14x11)SGMQCGVBDBQHTZ(3x9)KDB(9x3)NYNNWWEZA(1761x11)(280x2)(108x7)(4x13)NGXY(3x10)BVV(13x3)DMVZONDDQDHDS(7x1)KCUPDYK(52x5)(4x12)XPJZ(6x7)FSTORB(10x11)PPPMLQBXZI(9x1)FMFCFFUTU(31x12)(13x1)BJGZGTZWUIDPO(6x11)NISLLZ(14x2)JAWFAAEDHHVJKE(14x10)(2x11)EB(1x5)Z(80x6)(74x1)(2x2)AP(26x2)ETQQNNOYWDYHUGHQDHPFLXTCAS(5x14)FEZYM(1x3)R(12x8)MDAGWSYTQSGJ(157x4)(68x6)(19x4)(4x7)RFUG(5x6)LJUHK(29x2)(2x14)JP(8x6)LHTUJFVT(3x9)GDY(3x3)LVM(76x10)(16x5)RXLMFXQBRVNONQZE(13x1)JCGQIIIVGOXQG(28x13)TBRCYMNPXBFWTADINKDUSIIWVWKJ(251x1)(181x15)(65x7)(2x9)JS(8x1)DMJXRYWV(9x11)JAFTREIZH(2x13)VI(16x1)MVOHUXRZWUIPDQRX(4x3)SWAW(3x4)FWU(73x1)(11x14)XLPCBJOIVDM(9x6)SUSZQFZKD(6x11)LZCJGL(7x11)IVOPCUS(10x2)WCMTUHFKYN(9x9)REKKFLXDB(56x4)(8x11)JSCOYIUO(16x10)(10x7)POSCVPVGCQ(13x4)MAEVQQGBGWTPJ(326x12)(144x15)(23x2)(10x8)QHBKATXYJO(2x4)BD(15x8)FALUTJDJEUNLFSG(6x8)(1x3)D(3x2)TGW(69x9)(17x9)BRXIVIUJOUWGRBBTP(6x12)IAGHFZ(2x4)NR(2x6)SR(14x3)UKKJAGYGPBQUZB(32x13)DWXVLERHAXVCTKAIUGVJNCBPRNVPKUZC(128x8)(4x5)PRHP(3x15)XYF(55x3)(4x15)SVDY(25x3)IORNPEOSEYLIJBRNQUKEDLPYZ(9x4)YOFZGOUOI(43x8)(29x3)RUIMIMISXBVSCFWRKHUHJVBQJTOWK(2x15)KD(711x7)(142x1)(25x11)(8x12)WHRETAGA(5x11)YRASE(29x13)(13x4)CBFDIYICCDTTJ(4x10)IFVL(5x11)QUQLJ(50x10)(8x14)FUNLAIVW(4x3)RVMC(4x3)DWIO(11x11)CQINFMFXOOX(1x3)Y(62x1)(48x4)(18x10)ORLEMPUSTXIMMDCAOK(1x4)D(11x3)WONNFZQPGXD(2x13)HO(156x8)(25x15)(10x7)JHVPAAMVOL(4x4)VLQZ(81x12)(34x5)STGMRGJQPCLMKMCMOAYAHFLPUSOEKOFXYE(19x9)YAYMXSEDWUJOWJTTMMS(10x4)ZWLMTIMGSJ(30x7)(7x9)WWZRBWD(4x7)BUZZ(4x2)BXVA(197x13)(9x8)(3x14)YNV(14x5)(8x10)GEINIUYR(45x7)(4x12)KNCB(2x3)UT(1x14)R(2x11)SP(8x2)XJLXDKWE(37x5)ZRCRNEVUTWDXHLNJJARHPLZJKPTTUCLWQWATX(62x11)(8x3)ALDXAAEQ(2x15)FL(8x8)QJNQZFPQ(6x1)LKAPCV(10x13)KXWJMGSQOW(119x3)(90x13)(12x9)NYWLXRMORSBF(21x4)BXNONMKXGTOJWEHGTKRGQ(17x13)HPLFMAYPEOAFKQVJX(8x15)EQEMQYUT(1x13)F(15x13)(9x12)UHDEHMMKZ(736x10)(480x1)(92x10)(17x4)GJZPWBSNECJXWLLHV(36x13)(6x10)JODAOK(4x14)JPSM(1x15)H(2x6)NI(8x10)BJBZUQMZ(6x12)ZPWROW(211x8)(77x5)(1x15)U(4x12)IUAY(37x10)KVCKPHSEXYGJCZYAIRNJCZZOQVZMEYDRJARER(4x8)CBXU(2x6)ED(11x11)(6x9)CRFQKF(12x15)GPZGMUVAETKQ(84x15)(10x15)OVNCZYNUUY(35x7)VXZDDZHUTNIAKTPEDXCYFZUGYVPHPIARJYM(6x12)SIUFNZ(9x1)GXDHFDKSW(132x11)(49x1)ZSJMTNGPNQIIWYCWGDYQFEZRHVXNWLGCYQFRMIOXEGSCAPMLX(2x11)RX(4x9)EZFD(53x15)(8x12)WVGWJZVM(9x7)VPUQJWERB(18x11)NJXQTRBJDGLCHQDHEI(17x3)DAOIMIUYPBHLHLREY(222x11)(196x15)(96x6)(21x15)FMLCBALDJJHZFEEQGIOXJ(4x15)ADBM(13x9)BATPQIPKKOQRW(12x7)LKENJLXLNRHU(15x1)CAVXHLDTDMMQHPO(4x12)VVMV(54x10)(8x4)GPMOWNVY(5x14)IFCKU(9x7)EGRBDVKEG(3x3)QAC(3x2)BLT(9x13)JOUHWBQDV(3x8)SOF(12x2)FPPLIAGYYXET(12x15)WRCWYKPWGTQN(936x15)(536x6)(80x11)(73x15)(6x14)STRJOP(28x12)(1x14)U(14x13)RINQHGGUCBSKLL(19x13)YUXWEEJMMQRAUVIDRWM(77x14)(14x10)(9x9)ZVYCUGRJI(50x1)(8x11)MGZUJHNG(21x1)(9x14)FJYLKQLZS(1x5)S(3x14)NBN(229x5)(24x4)PUNXKXDPSYWXQVMXLGTOJILI(115x9)(30x12)(3x8)XZM(8x2)JUXEGHCG(3x13)MRN(7x3)(2x3)FC(28x15)(1x6)M(5x15)FITOA(6x7)PPSHKK(15x2)XSBVRKAPOPEFJNW(4x15)CZMH(71x4)(38x5)JLSITCVCIUMEXUVKUTWUHAJCKEHRKEDWLAPCAV(15x9)TCNFHQCDISVBPZZ(1x9)L(122x9)(1x6)Z(4x10)OEMP(86x11)(80x2)(24x3)HLATVWMPPBESZCTYXGKKURLI(16x15)YJTHARGYCNXZDLZB(11x9)FUTXKYZMHUS(5x5)TTBLR(8x9)PVYNNLXP(385x14)(24x14)IMIPODVZOEYSOIBWKZJGFISM(294x7)(2x10)UI(162x7)(68x7)(37x12)NTPKXSQBVWUBYWBJLERQEEZBPQRZRWXYQOWGV(18x5)IOLEJIUYCJGOWNEESN(1x13)L(21x4)(6x10)BGSJZR(3x12)LSX(47x14)(1x5)T(5x5)SAJGM(15x11)CDUAKTVLZPXGULY(3x13)ABZ(3x6)AKF(102x1)(53x10)(16x10)YUODDQQFXDKWLHDG(6x3)TIHFOK(8x3)VDTFJWZN(1x4)A(35x10)(1x11)V(16x1)YPITMARRAZLDKDWG(1x6)R(46x10)(40x8)(34x2)(28x8)TJDGRRKOKRSQXUTSFFNLAVHOBISQ(15x13)URNDSLWYMINZKAE(3367x9)(1313x1)(371x11)(143x4)(34x11)(22x5)RVJTJNEDGMLNAYEBSSKVOR(1x7)O(16x4)(10x4)PSARQPKWUD(21x4)GCTFJPSLYCDNEATTOROJZ(39x14)(6x13)LNWYOB(4x3)XGZD(12x1)UTSCPUJSKSAK(2x8)JM(5x2)EKVLX(204x7)(86x4)(14x8)JPWIXHZDPQXPCC(1x1)K(45x10)MRFXCXIIETTGXHIQNWBSOQQWTSGBCYKMFACKTDYOTHJBQ(3x5)IET(85x9)(5x5)RFTKZ(20x2)TQDLGPEDZZPASQYQUPUO(2x14)SO(17x11)WDNITLJSNEAGRAMCX(11x8)YCTAQJZBNBE(8x1)(3x6)JCB(2x10)CN(418x2)(250x11)(89x3)(9x2)UGJNLDQXZ(20x1)YQXXUKKYLHELKAXQCXTN(10x1)BBJHQXNWPR(15x9)EHXTDJUDPYSNIFG(6x15)JQUUWU(73x12)(8x12)AZDPTFJE(52x11)IMHXOEKZDPXPWMDZHSMRMWZFKDYAFFDRWERJBPZOTUDLCWFAKVRX(42x14)(11x3)ISRNXOQBDUI(8x8)TNDIUEBL(7x6)ZQEXVLD(20x5)(4x4)CGDU(6x6)DIYBHY(56x6)(2x13)XB(26x10)(1x3)N(4x5)PSNK(5x15)PSYSY(9x13)SAKNLBYHJ(91x15)(11x2)YMQAJMTVQZD(13x7)(8x8)VRZLJWJD(40x15)(6x2)NWQFRQ(1x14)X(16x5)QXJKSSEVSQCFIFUZ(2x12)ON(17x11)ZIXRUSIHDTXUAAMRL(337x11)(136x14)(5x15)MNYAL(9x15)(3x13)PKZ(21x5)(7x4)AISWKGW(3x10)MBL(55x5)(13x6)QFCECSJKZKNMQ(1x5)X(23x11)PQEDJXCBXYYHIHLRKSIKTPT(15x13)ALZNGTVBBMZGTQP(3x14)KIS(78x8)(61x14)(19x6)KFZVHNQMBHEDDMUBDQL(18x11)NNRDUJEZRZZSPBBWAJ(5x10)JGPHQ(4x12)ODHJ(28x11)MWRLKJXCRQMKYUNGKQCGAROEBSOD(59x1)(17x4)(11x9)BZYJIUVALRZ(29x12)(1x4)O(17x1)BCOBLYPJFZDGZSWNB(132x13)(124x14)(23x6)(5x7)WHPBL(8x9)DOXFBTXA(45x14)(5x6)PVAXU(18x8)EMCPMDBCLVNGCQQSEC(5x15)OLOBE(9x15)KAPGMGKXW(22x8)ALYWPEGOJKGQPTQPQYYILD(164x4)(156x15)(20x10)(13x11)HKENJHZGTUUIG(84x10)(6x13)OFCAHG(5x8)JGBXE(6x5)VHJHSU(45x2)(1x11)A(6x6)DZLEJY(10x7)JPRGBWKANZ(5x14)KFPLA(31x15)(24x12)(7x11)SSTERSV(6x2)CRLNYQ(514x4)(285x5)(23x11)(4x10)FOVB(8x1)IBFMETHZ(73x11)(16x9)VGCBQEKJYFSZIGGN(1x7)T(29x1)(4x8)BERJ(4x3)NDLL(5x14)NDGRP(4x15)GHFK(21x1)(14x15)CQOZHUZHNYWIRO(141x4)(70x7)(2x4)QC(4x11)WBZM(22x6)KWZDQFEITIZQXRSTKJTNXZ(18x10)OKLSJFKSMNWWFQPWCQ(16x13)PNWFKSLLLGYXFKFU(36x6)UXHKFFVSFDPUJHJHDYGIQWEVFQVDUQOSIOPI(214x10)(6x13)FHQVTQ(2x4)UU(133x2)(3x13)KUL(10x10)YGMYBMBZLK(51x3)(10x12)VHODIYLUDH(14x10)MSGWYHUNGTXOTR(1x8)Y(2x5)NG(44x2)(3x7)JQT(30x8)GQBSIDPWDGVJDGGNRMZHOKMHFFKUJG(40x7)(20x10)(14x7)NEHQVHZJWKXCMD(7x13)FHQCJES(4x6)NNLG(1345x12)(214x11)(2x4)PT(193x9)(7x9)(1x14)X(104x12)(8x4)QFSSDKKU(12x13)LBRRJIYLPVZP(3x13)SCF(38x9)ZATOROAVMBHFQKKPSJQBBVFQYOFZHOIQZCAZAE(13x5)HDBQATTHPFAJU(62x10)(8x5)LJIPZICO(5x7)TIKGZ(15x4)FNTJFQIFZCGMDQL(7x4)NWQFWQA(1x1)D(2x2)SA(362x2)(50x13)(44x4)(18x10)XUKEPXLPXMLURCVSNA(7x15)CQSFEDB(1x7)P(86x6)(42x8)(6x15)PLRMVD(3x6)FAA(8x9)HSYDKIYH(4x6)CMUS(7x9)HTODFBQ(6x11)CHBYPI(1x5)B(3x3)IJA(76x5)(29x9)UAJNFBEXTSFEGYMJOZJNPKXADGQFU(34x14)(14x9)BMLKJBLZCTXCGC(2x13)UH(1x6)O(123x12)(46x13)(12x2)AMANHATHZJLR(3x7)AGG(9x6)YNFJXYGOR(1x5)K(50x8)(2x14)DY(5x4)IAQXY(25x15)OPPQMYAUSIQKNGJXIEWWUBIBJ(8x11)FTKTBRPA(63x14)(6x10)ZXWXAE(45x1)(20x13)(13x12)WSQQVGCIGVLXW(12x5)HJJJANWCFKOE(347x4)(3x11)XTH(1x4)B(16x3)GUAMQZWPSPKUKRHG(303x3)(3x5)IUA(107x14)(24x5)QKTPEKPOULAJEANONWICQVRH(4x9)VJMW(21x5)CIRVPAYPUVCAPGEDXJRJS(14x13)CUWRSISDMETQPB(13x15)KYCFHOIFHCKYO(68x1)(16x6)EODWCYHGQKKLUCBB(20x2)GWBSKULZNXSSSFZEJCZM(4x5)PECS(5x14)ROEJN(36x4)(17x7)PDYTFSNAAAJSKSGOS(7x12)RCCFUAR(58x8)(4x14)RBYW(1x14)K(34x14)SMTABOIPSIRRKKJTUCGXEJHOWDZWSBPUCV(323x7)(74x3)(68x4)(21x15)OXUBNXBUGOGHZEWAWDHRJ(23x13)UQYSTJYAKTUHCHSWCFDDRKZ(5x7)VXJOH(13x15)(8x9)EOCNIGWT(216x6)(60x13)(8x10)HMZCAJPF(13x15)DPZYCBQBJGMMC(9x13)PZPCYYLQC(5x13)GOBQG(62x10)(5x2)ZYTKA(9x5)YINOLVDPX(2x9)GH(6x2)VPHEBS(14x1)ULSCHAQADYEMNL(18x10)VKGGGWALFICNIDBBQB(15x3)RIAXMZCHSROTHEN(27x12)AUTBVRMCQKYGMABAUVFGHFBHUFB(2334x9)(2326x1)(4x7)MBKL(144x11)(2x13)UF(3x7)KTS(13x12)PBBVVBSUTJBMU(100x10)(20x14)AWSXELWFDUNLVYIITNOI(66x12)(10x8)YFGDFSIHAY(4x12)IVYI(34x4)ZOIMKLDVRDMGVNXHVSAQPXASOKAPFFCOYM(618x9)(44x13)(11x8)SSYZXHWKGDP(12x12)DAZCEESYDHGU(3x1)WJZ(287x10)(12x4)(6x10)RJCQRG(7x13)(2x2)JD(22x8)(3x11)ZWO(8x4)(2x14)DH(147x3)(112x4)(1x8)T(9x10)QKFRAICSR(11x6)NXHLSBTTOJT(22x1)OSYERWMCHRVVTMCQSLJWLE(39x12)DRUDTGZKTPOEHPTIDIOMCHRUTNMJMDOVLPLOJHU(5x1)GJALO(12x3)WHLTYMOAPKDB(68x1)(6x5)WTIQWJ(38x11)(1x11)S(1x11)C(18x1)UDTTHQUZLAZJJYBFWP(7x6)BAOOJVK(264x13)(78x11)(2x7)KU(16x15)(5x5)HWGHC(1x2)M(4x12)UZJB(23x8)OEFBFIBTJTPXBYNRAHNENLR(4x6)UQRH(22x5)CXMJULOWAXJQZYOJSBMMCH(3x14)QIB(135x9)(7x2)CHUACEG(76x6)(1x2)O(11x2)QWYBYXEHPWY(6x8)DVSMDT(5x2)PDQBI(26x7)USTGHYJTBDCKDYMEKDDCWLRJSR(35x4)(1x8)Z(7x1)OKCPSGK(3x3)YKB(4x1)JHYV(1457x13)(414x3)(156x1)(21x9)GTFEMIWUFPZKXTAPAWFSA(10x6)(5x2)BWQXU(12x10)(7x6)HIFJYHN(7x7)WAYKJZM(75x15)(50x8)VFOJKTCXBBJDQLXMJQMHNJEFOHCWTEBBBHPLFVNCDVZVUVBRFN(4x1)HLBI(5x8)NBWBW(100x15)(36x8)(6x11)QRXGWV(2x15)LM(10x2)GENWUHMDHD(43x5)(6x6)XNXOQQ(14x13)DRBVVIPKSABCRK(6x7)OOGXBK(4x8)SPIZ(84x3)(10x15)BYCCWQYTGJ(15x2)JBUWSONDXDCHCLM(10x7)GICEAFHGCP(15x11)KPOGQBLDRGMDFMI(3x5)QPL(39x9)(13x8)CNRCEVUGECJKI(6x14)KAGRWL(3x9)UNS(2x13)KD(619x9)(41x4)(1x9)R(2x5)NW(5x14)HWCSS(5x1)YBDZS(2x9)YJ(22x9)PHTCJUSABRDAEYBZPOCJCA(137x2)(3x3)TDU(6x4)(1x6)M(4x5)HOLX(79x6)(16x7)RPSBDBXECFKNNYLH(2x4)XA(10x8)HFRCAIFRAR(18x3)YTJLNOPXAFNNWCPDLO(5x9)DVQZD(18x3)ZHIWWLVSQRVDDMCYHG(294x6)(51x1)(14x14)AADOHYXXSTVMYA(5x3)VCFNJ(8x15)SMCJHLWX(1x6)Y(28x9)ALLKXWTHFJMHVGUGTNMTJXDQHJQK(51x1)(5x7)XTDMB(4x2)HIXL(11x3)CYHOTFMJWEY(2x13)IW(1x14)K(94x13)(17x6)BMSVGSGVTQFYIHFUC(10x6)IZCKUYSXAS(24x2)HTRZUXEQSQFRMLXGEZRXBPBQ(19x5)SBLVIBEJDIUAHLEENEY(38x15)(14x1)AZJFPUGHFZHBUV(12x1)XARJBQCUZROW(92x14)(3x2)DLJ(77x14)(8x5)ODSGDCXG(45x1)USLSTAPOEHYFPHWTELAPRSUCLSOQRZAYCAFBNVVHPOYPN(8x4)LSKEJHBQ(402x15)(226x13)(49x9)(4x2)TMXR(10x14)ITPKFJTHQW(2x9)OT(2x4)PH(4x6)XKXF(8x11)WTPGIKKA(26x14)NPNESBFESFSYVCAKWBOMWGYOCY(25x5)GSIEXJLWCRUOLPPCXBYMMMABY(86x14)(44x4)JVZTPHBJEPTXZHGWEDJUXBHTYWHOOMQPHDUMNJYBLUOZ(3x2)NIC(22x5)XPLBTHANGNMJRHJQWGPEYT(24x4)(18x6)(1x3)C(6x10)ERGVZB(3x4)CLU(123x4)(68x11)(8x15)UZRAWQZA(7x1)EYVNGTB(19x4)ZSLMVPWFCLAXWWMGTDY(10x12)TZGVWMOACQ(42x5)(9x11)JDPLVZOKP(7x4)AWMDYVD(9x15)DNAKSRSHQ(68x6)(17x13)(11x6)PYTCFBZWKKQ(4x12)EGHM(28x2)(3x11)WKR(13x7)(7x11)EGIIRTL(3754x12)(841x7)(226x6)(92x2)(42x14)(35x13)(10x5)IHMSJKHNJH(8x8)MYREBDDD(1x2)K(8x14)NSKZICAQ(22x10)VQUOMCIZTLWIAAIWMTMZYU(33x9)(26x11)MTCNPWASYTLWFUHVZJSMLSUYGL(1x4)S(17x13)(1x7)H(5x14)NDMFV(53x2)(47x7)(22x4)(7x12)PLHZPTA(4x6)ULAX(13x3)DTIAMKYKISRWD(600x15)(109x11)(1x15)R(27x1)(21x7)QSXFHGBHUWWRPCQFROTIY(43x15)(37x4)(8x4)AMTRDOPK(1x2)C(2x7)EN(6x8)YPBIHN(12x14)(6x12)(1x7)F(112x4)(8x9)(2x10)UX(25x2)(2x14)RZ(10x11)(5x7)HTWSD(62x6)(8x13)HUVCCWAM(4x15)RIVP(24x8)(17x13)IFHANRZFDUPOQPWTT(2x10)QT(158x6)(39x15)(10x15)VJPMYZOSCZ(15x15)GEBYKNEHPBVINHM(104x15)(27x1)(13x8)JJELZPJPUVIHJ(2x14)HF(53x10)(9x3)LLJKUEWAP(18x11)MEGYUDUSKJMJSTKZZH(8x10)IWVCLWMD(5x10)IIUWM(191x15)(85x6)(2x12)AE(7x14)YQMQGFX(49x3)(14x12)OIELHKYHJBXCLN(3x11)AXZ(13x9)GHKWSKUKKFLSU(4x6)FJTL(83x8)(76x10)(7x10)ZMMYVDK(17x14)LLOEBHBFDUJTZZWGU(18x13)SPSLVSQOYQXXWRRIMJ(2x6)AM(1x13)B(6x6)DBAFCH(830x4)(5x11)NZMBE(694x8)(6x8)GASDHC(394x6)(116x4)(11x1)KYJSDFYYPTP(8x14)(3x6)YZR(27x15)(3x8)PSG(12x10)LDDRMGPCXCMF(45x2)(2x2)JA(4x3)SRWC(1x9)O(16x13)TTLQKIIAXRKIZCUX(170x7)(13x11)ZSFACAKVMHGKS(81x4)(18x11)CPRUPOJQIBQLMYWCDE(4x3)JYGV(6x1)DAOQQV(19x5)CBPXMEDDMLMTGFRGPNC(6x8)VKCUIG(36x12)(8x8)HCVTWURX(9x7)QNLBGVJVD(4x3)ODRF(13x13)YKOQVADTVQMZK(77x13)(24x10)OYMPLHCMYYIYNJHCPXPDEGZQ(11x8)(5x15)FPMPB(23x6)(9x1)PCRDMMYDH(4x7)CENS(4x11)MPFK(9x6)(3x11)UUP(7x1)UWNYVWB(249x1)(218x1)(17x15)(11x6)VXVQAYOOIBE(131x12)(39x6)IEQHFDHCTJFPUDVGYRJPCYBCYZZFXYGRXDSCZCD(20x12)OOBXCYQYLZPBJWIBUWAA(12x8)ZHGJPKBWGXFR(25x4)OVARPSETFFMCSCPIXEGOHNUMN(4x11)RDCT(6x15)QLPQFC(36x12)(16x15)CJKGEQXTSINHPHMA(7x11)KSPSOUR(18x4)(12x9)ZTGAJDNSXHDU(111x7)(11x4)CYKIOBNFEGD(31x6)(25x2)(18x14)FGRTQESRFJGZMPNRUN(50x13)(2x2)KN(36x15)(10x4)OTUOCXHNHE(14x7)(9x8)FVRRYRFPO(224x13)(184x5)(163x8)(59x15)(7x10)LOQHMYI(22x6)(7x1)KXLOUFK(4x13)WVDI(12x2)EMXIDRTROLVC(6x10)VAHMFC(52x2)(32x15)(5x14)MAAIY(3x9)NHF(8x5)PRXKOTOR(8x2)KPTWMWKG(20x13)(8x2)PJBVGWST(1x15)R(9x1)HWFCLYOKN(27x9)(21x2)(15x6)KLJZECQKWNHWWIX(1829x2)(858x1)(12x3)KYUBBBZCYFTV(572x14)(209x15)(7x7)BGVNUYS(120x6)(9x10)RXUIJCOPN(42x15)CKKAHJSLICNUMZBKJCGDHWBCLBPUIUMAZXPXPFVTHM(5x6)NPKXA(21x2)XHXEDIXBPYQYWPAZVKTUM(12x12)JDKTGKJIPCTF(54x14)(12x1)QUDHNAYHAHXC(8x11)GPYLPFKM(8x14)AOYOVEEY(2x12)QU(3x14)GHB(130x6)(57x10)(22x12)CNNNBZZGWYXBXUMRRZMKUM(11x15)LIMWQEKCDUS(4x12)FVUJ(11x7)ULQLRKALJNX(43x4)(2x13)DU(3x2)ZWU(5x13)PIBIP(10x6)TADCHNVNWH(30x1)(1x11)I(6x13)PDQHWL(6x3)JPNNIZ(94x11)(17x8)BYMTFVMEQZUENZEDY(1x11)Y(1x3)E(52x7)(10x11)JUOMLTDPYV(6x4)VWFWSC(18x2)PEZNNWKQMIXMNMFFYV(74x14)(18x9)WSVCADWAXYSLVEXXKY(43x11)TDYRTWYPRFOJOFNNFRQAXHOYESCRESIGVPEZAQNYUZU(223x8)(36x1)(30x7)(6x13)JEMNDE(6x1)KMNDNG(1x15)P(1x7)P(167x14)(53x9)(8x11)AXHMYSMF(16x8)IBSDRSKDWAVAGHAY(10x14)WCBNJVKQFE(56x13)(18x5)CMRBGHIWNSWOFEJAKZ(2x2)ES(19x5)BGAPIYECLXZKKWQDXKJ(39x6)(1x7)Z(27x5)HJVHXJAYRJGPQJPRVLBPGNHEGAO(11x11)WSMGKGFWEZS(7x9)SMDWJAK(172x7)(137x11)(7x5)(1x12)Q(118x6)(12x1)WKMCAUMANQPO(32x3)(3x13)KUP(17x2)PIUKNKTOJQBFFBHMD(11x3)(5x12)NPDJH(39x3)(14x14)FAUXDEDTYTBXQW(6x4)ULEQRI(2x1)UG(13x2)(8x8)XLEBSQDT(2x14)HB(92x8)(8x15)(3x8)CUO(10x11)BUXSIQMEBN(41x7)(2x13)BP(8x3)KZYDBTOB(14x5)(8x12)WDFBJBUY(8x10)(3x2)EVB(1x8)L(673x14)(191x5)(7x11)OIXREMH(96x4)(16x10)(1x11)X(4x1)NIIY(23x14)(7x7)SUOVJAS(6x2)QVNPXW(1x15)L(8x6)QSUBGSRH(17x6)ZCJDKVWHBJCBXLCBZ(70x1)(8x15)AXEHKIMF(9x12)PWRLXCFMC(34x14)(5x3)EWDOK(12x3)CPWNFYUDJJII(1x6)U(468x4)(93x6)(11x3)LORBJPLKIEE(70x7)(8x6)RLAJDPIA(19x13)ZEZQMCDWLCEKPPEOPEO(4x12)HFTE(1x15)B(8x13)NJOEQIQR(95x4)(16x1)HJJJXFVITXCGUJCV(31x10)(24x11)MWPVFJPXBSGQRJSWYAXIDSXM(9x4)(3x12)UBL(15x3)TDTSFTMOCTLLGTT(88x3)(81x12)(7x13)EFFHSFR(2x3)NC(11x4)TNOIEFYHLCF(1x12)C(31x5)HCJAHWAPMFTZZFLFLJKHBGEVNHRSZLV(19x3)XETTDXQVOIZAYXNRFWG(141x12)(103x7)(21x13)XIEYNXAJUFPHYKYFMKSQM(11x13)SVAGUZYMBQY(5x8)GIDXD(40x10)XGWDXONEBMYPNHYZXSFDCCZAWZZHEZDCIHXWOCCL(15x11)QNPTGVVIIVAMPRM(4x8)VMWF(162x5)(80x3)(22x2)CLKCVKOZJBGFCWOCQFTNDV(1x9)H(18x8)YOGCMNFKXHEYWAAWFN(3x8)UNJ(9x1)MDFWYEOLI(9x9)(4x7)PLON(1x9)M(35x12)(20x5)LOJPXVGMNSOWMMEOSIND(3x14)YAQ(9x3)QPHIIRVXX(69x4)(34x6)(16x1)ADEAXTGJETYMXQLE(6x11)OKLRKI(10x4)DIRSNHOBJM(8x5)ABWMLTWW(7x13)AJTDYZC(23x5)LSLRJJOHFVRITWVIKBZLILU \ No newline at end of file diff --git a/src/year_2016.rs b/src/year_2016.rs index 6419a79..5b22609 100644 --- a/src/year_2016.rs +++ b/src/year_2016.rs @@ -10,6 +10,7 @@ pub mod day_05; pub mod day_06; pub mod day_07; pub mod day_08; +pub mod day_09; pub fn solve(day: u8, part: u8, input: impl Into) -> Option { if part != 1 && part != 2 { @@ -24,6 +25,7 @@ pub fn solve(day: u8, part: u8, input: impl Into) -> Option { 6 => Some(format!("{}", day_06::day_06(part, input))), 7 => Some(format!("{}", day_07::day_07(part, input))), 8 => Some(format!("{}", day_08::day_08(part, input))), + 9 => Some(format!("{}", day_09::day_09(part, input))), _ => None, } } @@ -31,6 +33,7 @@ pub fn solve(day: u8, part: u8, input: impl Into) -> Option { #[cfg(test)] mod tests { use super::*; + use std::env; #[test] fn day_01() { @@ -64,7 +67,9 @@ mod tests { fn day_05() { let input = include_str!("../inputs/year_2016/day_05_input"); assert_eq!(day_05::day_05_v1(input), "4543c154"); - assert_eq!(day_05::day_05_v2(input), "1050cbbd"); + if env::var("CI").is_err() { + assert_eq!(day_05::day_05_v2(input), "1050cbbd"); + } } #[test] @@ -93,4 +98,11 @@ mod tests { .##..#....####.####.####..##....#..#.....##..###.."; assert_eq!(day_08::day_08_v2(input), CFLELOYFCS); } + + #[test] + fn day_09() { + let input = include_str!("../inputs/year_2016/day_09_input"); + assert_eq!(day_09::day_09_v1(input), 183_269); + assert_eq!(day_09::day_09_v2(input), 11_317_278_863); + } } diff --git a/src/year_2016/day_09.rs b/src/year_2016/day_09.rs new file mode 100644 index 0000000..2045ab7 --- /dev/null +++ b/src/year_2016/day_09.rs @@ -0,0 +1,73 @@ +fn decompressed_size(mut input: &str, deep_decompress: bool) -> usize { + let mut result: usize = 0; + while !input.is_empty() { + if let Some(next_paren_l) = input.find("(") { + let next_paren_r = input.find(")").unwrap(); + let nums: Vec<_> = input[next_paren_l + 1..next_paren_r].split("x").collect(); + let (duration, repeat) = ( + nums[0].parse::().unwrap(), + nums[1].parse::().unwrap(), + ); + result += next_paren_l; + input = &input[next_paren_r + 1..]; + if deep_decompress { + let dup_elt = &input[..duration]; + result += decompressed_size(dup_elt, true) * repeat; + } else { + result += duration * repeat; + } + input = &input[duration..]; + } else { + result += input.len(); + input = ""; + } + } + + result +} + +pub fn day_09_v1(input: impl Into) -> usize { + decompressed_size(&mut input.into(), false) +} + +pub fn day_09_v2(input: impl Into) -> usize { + decompressed_size(&mut input.into(), true) +} + +solvable!(day_09, day_09_v1, day_09_v2, usize); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn works_with_samples_v1() { + let sample_one: [(&str, usize); 6] = [ + ("ADVENT", 6), + ("A(1x5)BC", 7), + ("(3x3)XYZ", 9), + ("A(2x2)BCD(2x2)EFG", 11), + ("(6x1)(1x3)A", 6), + ("X(8x2)(3x3)ABCY", 18), + ]; + for (sample, result) in sample_one { + assert_eq!(day_09_v1(sample), result); + } + } + + #[test] + fn works_with_samples_v2() { + let sample_two: [(&str, usize); 4] = [ + ("(3x3)XYZ", 9), + ("X(8x2)(3x3)ABCY", 20), + ("(27x12)(20x12)(13x14)(7x10)(1x12)A", 241_920), + ( + "(25x3)(3x3)ABC(2x3)XY(5x2)PQRSTX(18x9)(3x2)TWO(5x7)SEVEN", + 445, + ), + ]; + for (sample, result) in sample_two { + assert_eq!(day_09_v2(sample), result); + } + } +}