From 33d96510d31789703389bde7cbff0b0672b74f75 Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Fri, 6 Dec 2024 15:13:27 +0100 Subject: [PATCH] Off the rails with a proc macro --- Cargo.lock | 145 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 ++ advent_derive/.gitignore | 1 + advent_derive/Cargo.lock | 100 +++++++++++++++++++++++++++ advent_derive/Cargo.toml | 13 ++++ advent_derive/src/lib.rs | 57 +++++++++++++++ resources/input3.txt | 6 ++ src/days/day2.rs | 1 - src/days/day3.rs | 100 +++++++++++++++++++++++++++ src/days/day4.rs | 49 +++++++++++++ src/days/mod.rs | 4 +- src/input/mod.rs | 12 +++- src/main.rs | 7 +- 13 files changed, 494 insertions(+), 5 deletions(-) create mode 100644 advent_derive/.gitignore create mode 100644 advent_derive/Cargo.lock create mode 100644 advent_derive/Cargo.toml create mode 100644 advent_derive/src/lib.rs create mode 100644 resources/input3.txt create mode 100644 src/days/day3.rs create mode 100644 src/days/day4.rs diff --git a/Cargo.lock b/Cargo.lock index 2227130..5743cb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,11 +2,68 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "advent_derive" +version = "0.1.0" +dependencies = [ + "darling", + "quote", + "syn", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "aoc-2024" version = "0.1.0" dependencies = [ + "advent_derive", "itertools", + "quote", + "regex", + "syn", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn", ] [[package]] @@ -15,6 +72,18 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "itertools" version = "0.13.0" @@ -23,3 +92,79 @@ checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" diff --git a/Cargo.toml b/Cargo.toml index 7271d85..d6151b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,3 +5,7 @@ edition = "2021" [dependencies] itertools = "0.13" +regex = "1.11" +syn = "2.0" +quote = "1.0" +advent_derive = { path = "advent_derive/"} diff --git a/advent_derive/.gitignore b/advent_derive/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/advent_derive/.gitignore @@ -0,0 +1 @@ +/target diff --git a/advent_derive/Cargo.lock b/advent_derive/Cargo.lock new file mode 100644 index 0000000..fb5334c --- /dev/null +++ b/advent_derive/Cargo.lock @@ -0,0 +1,100 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "advent_derive" +version = "0.1.0" +dependencies = [ + "darling", + "quote", + "syn", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" diff --git a/advent_derive/Cargo.toml b/advent_derive/Cargo.toml new file mode 100644 index 0000000..b43be4e --- /dev/null +++ b/advent_derive/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "advent_derive" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +syn = "2.0" +quote = "1.0" +darling = "0.20" + diff --git a/advent_derive/src/lib.rs b/advent_derive/src/lib.rs new file mode 100644 index 0000000..b9ea932 --- /dev/null +++ b/advent_derive/src/lib.rs @@ -0,0 +1,57 @@ + +extern crate proc_macro; + +use proc_macro::{TokenStream, TokenTree}; +use quote::quote; +use syn::{parse_macro_input, parse_quote, Expr, ItemStruct}; + +#[proc_macro_attribute] +pub fn advent_day(attrs: TokenStream, item: TokenStream, ) -> TokenStream { + let input = parse_macro_input!(item as ItemStruct); + let ident = &input.ident; + + let mut parts = vec![]; + for token in attrs.into_iter() { + match token { + TokenTree::Ident(ident) => parts.push(ident.to_string()), + _ => continue + } + } + + let call1 = format!("{}::new()", parts[0]); + let call2 = format!("{}::new()", parts[1]); + let part1: Expr = parse_quote!(#call1); + let part2: Expr = parse_quote!(#call2); + + println!("{:?} {:?}", part1, part2); + + let output = quote! { + pub struct #ident { + part1: Box::, + part2: Box:: + } + + impl Day4 { + pub fn new() -> Self { + Day4 { + part1: Box::new(#part1), + part2: Box::new(#part2) + } + } + } + + impl AdventDay for #ident { + fn puzzle1(&mut self) -> Result { + self.part1.read_input()?; + self.part1.solve() + } + + fn puzzle2(&mut self) -> Result { + self.part2.read_input()?; + self.part2.solve() + } + } + }; + output.into() + +} diff --git a/resources/input3.txt b/resources/input3.txt new file mode 100644 index 0000000..ade28dc --- /dev/null +++ b/resources/input3.txt @@ -0,0 +1,6 @@ +-~who()?!-{ where()mul(764,406)?^why()%[how(420,460)mul(69,497)where();'&>-!when()<^mul(629,650)mul(658,217))mul(553,521)][][*}>when()>]mul(927,175)]mul(364,814) &?what()/don't()#where(705,65)%@/}'#select()(mul(333,471)who()! @!,when()${mul(754,711)/don't()mul(148,921)*$&from()don't()where())mul(455,877)(from(519,591)/who()&when()select(401,718)['mul(870,745)who()@who()mul(92,899),# /<${what()mul(301,362)-mul(408,781)why()%(how()<}^/~mul(318,503);{(*,)when()mul(814,611),how()[ why(){,,mul(525,151)#):^?,~who()do()mul(306,819)!'>$(!mul(294,958)^&how()who()[mul(194,339)((mul(84,363)why()who()mul(711,25)]why()(}mul(31,323);select()!select()mul(85,830)>&where(),({what()<,mul(404,568));$select()where()mul(238,707)what(797,319)'[?mul(603,3)where()>mul(827,90)[mul(288,639)![ what()how();why()mul(278,751)~select()@mul(970,757)select()?how()mul(36,900)-@mul(835,851)+,!mul(908,82)~&?mul(452,524)?[{)what()mul(491,590)who()-[from()]~{mul(333,397)mul(615,16)/mul(132,775)why()'!@* mul(203,604)'how(258,168)[when() ?$mul(731,849)>,+-#why()>when(19,498)]mul(329,904)*/#'']mul(644,691)&+~what():why()/from()}$do():'+,, mul(942,653)what() mul(676,56)/''):[>@<~mul(6,697)'mul(369,485)+;select()-'/mul(102,637))who()$,!^do();&+^}why(483,625)select();-+]+@mul(558,499)+,]$$what()mul(73,35)where()how()+!mul(800,842)<:when()where()^who()<;/]mul(621,718)&select()^{:]mul(353,215):)#[mul(299,721),how()?,mul(911,921)&from()from()%+mul(19,957)when();!),++mul(441,742),$(^}(]]mul(622,972{]]where()<:how()$;who()mul(918,303)who()!mul(504,662)}how()when()(-+?do()~where())?-'select() [mul(533,672)@select(748,65)+where()'{'>don't():$#@:(select()mul(473,262)[how())mul(569,348)&$+*;;mul(919,482)>#mul(275,890)who()%mul(689,521)what()+[-mul(116,646):select()@'^select()when()<>-mul(184select()from(),+)where()who(312,610);mul(473,864)>mul(943,380)}[,&[)?mul(352,764)where()#mul(939,747)when()how(16,861)/select():why()mul(770,687)when()[how(),mul(289,328)mul(52,913)~+?who()mul(324,290):why()#from()mul(711,194)~~when() >[why();mul(635,124)&!from()@mul(71,301)where()&who()how()[mul(817,468)#{?,from()%}?where()(mul(991,655)?what()-why()don't():mul(324,148)mul(13,538)+[(~&/select()mul(887,419)what()<*!]:why()%$]do()@]#what()mul(864,345)<-(how()~^)where()what()&mul(991,25)how()^+-?mul(339,86)?select();@who()*)!}-mul(155,613)~$~{ }how()mul(812,654)~-#when()how()$[mul(386,847) ': -!'don't()from()from()[>mul(635,220)+<-!'&[{;when()mul(204,503)*@don't()~mul(913,575)when()!;^()%mul(313,960)from()from():/}mul(828,212):#;&($<<<-don't()?<(~who()'what()why()mul(454,310)($what();,&+~from()mul(51,471))who():mul(218,841)& mul(310,68from()mul(397,198),&] mul(107,89):mul(391,75)):?%where(),from()[mul(24,801)]}[:who()^from(){![mul(875,162)from()mul(127,591)[don't())#who(),>@>who()[mul(732,249)when()^where()@!+';)-mul(407,186)>from(675,101)what()]%#mul(461,214)$:^/%}mul(650,791)select()(where()'[:;^^~mul(200,463)[?(>$->when(){mul(970,444),when(96,186)%:(who()]/)mul(236,599)[from()-select();',why()mul(259,290)mul(698,621)select()select()!what()[where()%*$where(467,148)mul(458,533when()- #@mul(810,353) +what()/(>-when()%-do() :;how()'when()mul(928,260)*'/+what()where()mul(803,627)?#/$when()))mul(58%&!}^mul(784,330)who():'?]-[mul(480,39)/}#&do();*from()^mul(423,817)who():mul(758,858):)when()how(){-who()^ mul(986,262)<@~ *^what())mul(326,89)mul(863,330)'mul(797,517)+*&]from() }mul(681,55){*}why()who()mul(869,410)}#mul+/ mul(153,766)&^}@select()why()mul(30,619)how()who()?]mul(459,584)mul(119,326)&mul(627,843)'when()'!!@who()!!mul(211,446)(,{;>who(780,178)mul(483,646)$*how()select()%what()mul(113,924)@:mul(325,209)^[ @/%when()'{!mul(674,229)who()>]!?mul(306,16)]: mul(551,752)/@>where()'*mul(942,567)from()-from()mul(689,888)why()<*$select()how()[^[@mul(316,35)>*{+:when()mul(661,456)^$(,where()why()mul(972,157how()from()>+^!(>-mul(156,234)why()[mul^>&+what()?from()do()?#%why(){from(990,121)]how()/mul(201,545)from()<$where()>do()[when()when()'+when()~;&-mul(824,870))$-'where()when(547,415)]+/do()select()+what();#where()mul(442,767)'{%{!select()mul(131,742)mul(385,206)%&#~#@when(141,608)$/-do(){-:who()mul(241,754);}-&who(409,213)*{[mul(858,533{ $don't()from();who()]?select(459,962)who()where()when()mul(847,612why()[<]+*mul(89,985)~#&what(882,874)!!?why()mul(256,284),@}what() mul(845,617)what()from()mul(814,769)'!from()mul(685,850);>(who()who())what()%mul(142,506)what()/':?)(select()mul(159~;%}$^}what())mul(143,52)mul(2,339(>~'$(/~mul(208,220)$why()where()#][mul(622,831)~&@who()mul(841,258)select()/,@{-mul(943,197)what()mul(93,185)]]^^(select()from()*from() mul(233,470)-#@]who()#!what(721,647)mul(839,164)who(){mul(651,869)@^{&mul(28,23)> -'mul(593,606)]why() how()(mul(830,421)]mul(880!$who()/what()when()mul(299,889)mul(697,774)mul(7,535),where() }how(624,328)<%mul(670,193)}(when()[]mul(625,519)]@what()where()[what()*mul(703,883)^>(from()select()where(468,413)]]?don't()what()why() +how()#!/usr/bin/perl*mul(358,599)}>~where()what()?: mul(802,575)<;when()do(),mul(198,240) +!@%^mul(412,618)+# :mul(566,368)when()@%[!+from()&mul:when()^:*mul(139,569)where() @don't()#< (:,!mul(787,971)how()select()where()?-from() mul(609,411)/$what()#what()%mul(452,921)/how(221,30)~what()mul(673,185)%what()mul(205,923)::)^]mul(625,543):~[why()?-$mul(476,415)[why()%when()why():mul(223,252)!~what():{from()}do()how()~;%mul(41,365)'*):who() ,$?&mul(905,180):#,%}mul(882( (&[+$mul(927,165)who()(don't()@(mul(246,147),why()#@%mul(381,509)what()who()]*]-mul(593,225) {*;]mul(771,843);-mul(764,968)#[,}select()-%#)mul(696,330) what()how(),:?;when();%mul(154,412)mul(426,382)/&'who()&~>);mul(990,3);>how(552,609)from()&)# mul> {[/;:/+{mul(290,926)from()'mul(900,408)from()do()select()?%]&[-~mul(932,523)mul(477,866) ($#%mul(14,199)]mul(637,958)'where()what()$mul(777,762)$)what()mul(194,474),>what()$}[mul(521,703)$~- ]mul(897,954)+who()$mul(660,652)where()don't()where(779,173),how(753,110))]mul(488,877)+:(&from()where()~$%:mul(899,223)/why()mul(799,584)~]-(~mul(569:from())@]-(mul(247,152)?+)(from()mul(381,120)~mul(97,101)mul(448,487)when()from()mul(36,815)^}&:~!mul(35,211)*@#%/+)(,mul(288,994)why(546,78)^~)]?$from()who()mul(291,734)why()who() '@~ [mul(80,663)select()who()when()mul(288,196) &!where(212,346)<}mul(153,200)!([>mul(463,573when()%-mul(913,818);!!mul(842,31)'#%who()#-/mul(999,821),+/) -!what()why()mul(649,638)+{,/@why()]>from()mul(192,602))mul(623,469)-who()-*where()~)mul(753,337){[)mul(564,627))>how()('what()$]what()mul(422,110)*where()#]~mul(858,249) where(),+how()'*!mul(128,847){?^**@mul(424,825)mul(942,632);}when()mul(149,807)[?what(774,791)*[@mul(258,576)/~mul(13,896)where()}where(215,694)when():#/#select()#mul(528,826)#[/mul(190,170)~:)'who()'@?why()(mul(694,887)mul(873,610)where()'mul(704,477)%mul(964,286where()&what()do())mul(693,665)[<#(}?~mul(809,641)%>&<>@&mul(659,189)how()])}/-when()<&mul(278,575)?mul(383,999)(mul(321,263)who()mul(754,740) when():@*mul(720,146)?[how()*why()),~mul(836,890):#from() ~from(637,962)when()mul(922,625)&>where();mul(149,748)when()]%,?mul(429,943),&how()select()!}!&$mul(399,831)! @::mul!@how()#'(mul(516,281){mul(540,282)^/what()[&(mul(235,845)mul(858<}why()-mul(541,246)when()mul(916@+select(118,658)mul(924,828) (why()'?:mul'from(){<~$how(784,54){what()~!do()~select() mul(659,852)mul(44,508)]*-~/when()from()what()!>mul(627,533)**don't()who(251,250)};select()from()?#>**mul(169,149),mul(31,376)&why();#when()select()/mul(689,237)'{}how()^how()~!select()mul(832,456)%,*,>mul(285,352)!%,from()@mul(446,359)where()mul(619,895) +;{;]>)mul(41,286)who();mul(56,856)~]how()-mul(726,284)^mul(945,882)&+from(126,120))>){mul(797,922)mul(68,507)#-((mul(369,333)}what()>[:#^how()}+mul(185,65!!))mul(658,63))when()from()don't()' }-#mul(171,755)who()]mul(739,369)how()*when()mul(345,305)why()why()where()mul(418,411)when()mul(126,287)@, why(55,552)};mul>~mul(291,290)why()mul(578?^*#(mul(182,165)&~ !mul*from()mul(101,921)!$:when()from()%mul(387,265)[@how()don't()^)%when()+:*/mul(44,589'<{from()&select()/mul(793,478);from()mul(271,291)&:>where()where()mul(229,293)][>{where()mul(928,6)+where()>)$^?mul(459,607))from(){how()>select()>:where(264,447)mul(684,815):[mul(347,990)>from()'~ ^mul(745,814)from(964,621)@<}@select()[@~mul(107,883)where()where(393,153)mul(963,967)) 'where():^&do()]from()why()what(),^mul(385,705)how()*>mul:?who(36,654)?mul(62,39): [mul(726,597)mul(763,90)[when());%mul(100,244)who()'(mul(55,288)%,)from()}'mul(346,82)mul(931,134)@when()@where()when(426,348){what()}mul)from()]mul(876,854)when()mul(223,775)who()-'why()) mul(898,755)(mul(777,419):;#~?:- 'mul(582,230)what()-&[mul(334,496)-$'+mul(674,926)^ @%don't()what(637,807)~from()mul(40,279))^mul(269,29)why()@(%why(537,715)~[-mul(670,805)select()>!<>mul(836,684)!{)mul(152,117)who()&mul(896,602)'why()])~{mul(766,101)where()when()how()>mul(766,84)when()what()@+;?mul(550,934)~mul(6,106)when()mul(637,11)&-mul(724,305)from()!--/#mul(62,495))why()!;#?mul(906,583)(':+ from())^mul(712,122)don't()!/mul(719,98)mul(504,23)->mul(912,622)&]when()@%why()(!mul(479%@when()>^# ~[#do()#who()what()who()( >^mul(110,206)!'don't()]*[how()@)mul(323,394)select()/mul(377,958)mul(143,494)]:what() ~;how()]mul(630,173)mul(973,759who()]select(104,775)when()how()mul(776,616)when(962,62)where()>~>/&*$mul(177,110)+)*mul(477,656)*%>where()where()](mul(190,616)from());,from()mul(936,105)[> mul(809,538)}mul(563,601)*how()(select() 'mul,&'-&{?[>what()mul(380,965)(what(778,700)mul(669,732)mul(966,367)(:#mul(321,737)how(912,962)?$'where()mul(860,148)&{/when(){*&*mul(742,21)%:&/mul(114,64)&mul(706,893)[*select()how()#^]{mul(339,536)?+how()}+mul(28,905)}#why()>why()%(mul(211,426)why()!~~-]mul(958,999)mul(635,537)'what()#mul(350,45)*?>mul(392,743)mul(639,758)who()mul(342,243) (how()select()-^what()[mul(107,290)[mul(76,140)%):~{/what()what(515,174)do()^#':/?mul[/+]@mul(207,882)what()mul(448,652'?;why()when();mul(509,549)',from(343,613)select()mul(657,688)]:*&>+mul(678]) ^<]mul(809,417)mul(172,314)$[how()mul(666,262))^select()-mul(215,760)#why()from()*mul(301,529)who(86,180))*[#,select()*don't()*@who()from()+where()$mul(944,345)who(),where(631,143)@}<]mul(82,32)!where()]where(324,391)who()~?where(), mul(13,167)when()why()[]>%<'mul(24,374)?mul(932,568)who()([@?}how();$]don't()^*%:@>from()how()mul(100,246)who(147,869)-mul(743,461)>/%who()mul(733,280)-how()where()$[mul(397,950) +>,)>mul(921,777)where()/:-%what()- [do() what(655,775)from()when();}mul(513,785)?>~+~mul(656,887)?+select()<^mul(589,966)&why()mul(287,686)(who())$!<{((mul(4,157)from()}!?,what()'where()mul(617,343)<:why()]why()'&do()%@%what(5,890)what()mul(271,55)what()(where()}'-?)mul(582,649)%)/mul(176select()when()what(),mul(659,68)>>$@select()select()mul(373,308);^when()?]from()~}who()do()?[#mul(572,701)&mul(30,709)[[;why()mul(353,243)-how())>what()~~select()mul(63,496)mul(137,334)< mul(991,76)##how(),'~~?}#mul(485,797)mul(636,71)select(149,192)${{mul(774,387){where(){}~where()mul(418,125)+who()+from()where()$)$/what(368,73)mul(256,560)>when()]mul(631,272)mul(713,265))*{^where()[%select()mul(792,576)?mul(146,670)mul(73,111)<{)*[/]who(130,798)>:mul(820,581)^: (mul(899,649)(#?]mul(230,883)~/what(),%$;^>mul(145,724)*@]!>where())when()don't()what()*@{select()mul(424,670)*$mul(514,265who(),<@/#why()why();{mul(804,700),)why()#} *]]/mul(28,284)where() !:{*+when()mul(930,21)from()+who()what():?who()>mul(119,587)#mul(366,632)mul(710,996)why()select(676,739)}:@mul(427,253)[>#>mul(486,35)where()>#[%when();'* mul(368,692) '}!%+&(/?mul(233,760)+what(),:#':what()+what()mul(489,225)+{mul(977,940)%/^mul(124,752):when(577,707)%when()[mul(483,254)#:?^when()*^mul(23,268)mul(48,566)}'#mul(879,408)&from()what())[}$$why()mul(633,365)(mul(135,837)@'()&@&~mul(347,314)^<;mul(301,516) ^$((?what()(&what()do()[mul(883,466)##,*$mul(273,756)}[how() what()*~where()>mul(89,229)from()??why()~mul(622,308)%!$how()>do()](<~what() ^^!mul(941,422)[]how()don't(),>:where()>when() why(417,45)%why()mul(815,766)!]( $mul(409,145)!'?)mul(81,823)*mul(443,168)?when()?mul(475,220)/),+where():do())}when()**+{mul(651,45);#how()]%mul(837,911) >^}}!how()mul(699,375)^why(905,878)how()(}mul(936,779)[don't()mul(928,258)how()~/->mul(65,102)@*from()^]&(+mul(517,48)how() #'< >mul(846,43){from():what()why()(where()})mul(77,705)when()mul(885,675)mul(180,761)^>^(:&do()from()[#<-when()%~mul(743,829):when();$mul(99,676)who()!:&+;}mul(412,553) -]}^mul(824,352)from()+mul(282,920)who()how(){%where()~^mul(252,21)what()/{-mul(958,613)(-:mul(696,876)/why()#mul(761,290)#,mul(971,166)mul(761,359)mul(349,153):}select()where()mul(640,511)@;%where()-'mul(472,839)why()#'from()where()#--mul(823,302)! select()?;+},(>mul(255,432)mul(30,380)*/how()mul(852,651)who()$ where()<#how(),mul(683,385)mul(988,590)how()who()'>-mul(608,251)what()@*?who()!/mul(992,768)#' \ No newline at end of file diff --git a/src/days/day2.rs b/src/days/day2.rs index abfc897..a63c3c0 100644 --- a/src/days/day2.rs +++ b/src/days/day2.rs @@ -33,7 +33,6 @@ impl Report { let mut new_vec = self.0.clone(); new_vec.remove(i); let new_diff_vec : Vec = new_vec.iter().zip(new_vec.iter().skip(1)).map(|(l, r)| l - r).collect(); - println!("{:?}", new_vec); if new_diff_vec.iter().all(|x| {*x >= -3 && *x <= -1}) || new_diff_vec.iter().all(|x| *x >= 1 && *x <= 3) { return true; } diff --git a/src/days/day3.rs b/src/days/day3.rs new file mode 100644 index 0000000..43b66d5 --- /dev/null +++ b/src/days/day3.rs @@ -0,0 +1,100 @@ +use std::path::Path; + +use regex::Regex; + +use crate::input::get_input; + +use super::*; + +struct Mul { + l: i32, + r: i32, +} + +struct Day3Part1(Vec); + +impl Day3Part1 { + fn new() -> Self { + Day3Part1(vec![]) + } +} + +impl AdventDayPart1 for Day3Part1 { + fn read_input(&mut self) -> Result<(),AdventError> { + let hay = get_input(Path::new("resources/input3.txt")); + let re = Regex::new(r"mul\((\d+),(\d+)\)").unwrap(); + for (_, [l, r]) in re.captures_iter(&hay).map(|c| c.extract()) + { + self.0.push(Mul {l: l.parse::()?, r: r.parse::()?}) + } + Ok(()) + } + + fn solve(&mut self) -> Result { + Ok(self.0.iter().fold(Ok(0), |acc, mul| -> Result {Ok(acc? + TryInto::::try_into(mul.l * mul.r)?)})?) + } +} + +struct Day3Part2(Vec); + +impl Day3Part2 { + fn new() -> Self { + Day3Part2(vec![]) + } +} + +impl AdventDayPart2 for Day3Part2 { + fn read_input(&mut self) -> Result<(),AdventError> { + let hay = get_input(Path::new("resources/input3.txt")); + let re = Regex::new(r"mul\((\d+),(\d+)\)|don\'t\(\)|do\(\)").unwrap(); + let mut state = 1; + for capture in re.captures_iter(&hay) + { + let str = capture.get(0).unwrap().as_str(); + if str == "do()" { + state = 1; + continue; + } + if str == "don't()" { + state = 0; + continue; + } + if state == 1 { + let l = capture.get(1).unwrap().as_str(); + let r = capture.get(2).unwrap().as_str(); + self.0.push(Mul {l: l.parse::()?, r: r.parse::()?}) + } + } + Ok(()) + } + + fn solve(&mut self) -> Result { + Ok(self.0.iter().fold(Ok(0), |acc, mul| -> Result {Ok(acc? + TryInto::::try_into(mul.l * mul.r)?)})?) + } +} + +pub struct Day3 { + part1: Day3Part1, + part2: Day3Part2 +} + +impl Day3 { + pub fn new() -> Self { + Day3 { + part1: Day3Part1::new(), + part2: Day3Part2::new() + } + } +} + +impl AdventDay for Day3 { + fn puzzle1(&mut self) -> Result { + self.part1.read_input()?; + self.part1.solve() + } + + fn puzzle2(&mut self) -> Result { + self.part2.read_input()?; + self.part2.solve() + } +} \ No newline at end of file diff --git a/src/days/day4.rs b/src/days/day4.rs new file mode 100644 index 0000000..4b33390 --- /dev/null +++ b/src/days/day4.rs @@ -0,0 +1,49 @@ +use super::*; + +use advent_derive::advent_day; + +struct Day4Part1 { + +} + +impl Day4Part1 { + fn new() -> Self { + Day4Part1{} + } +} + +struct Day4Part2 { + +} + +impl Day4Part2 { + fn new() -> Self { + Day4Part2{} + } +} + +impl AdventDayPart1 for Day4Part1 { + fn read_input(&mut self) -> Result<(),AdventError> { + todo!() + } + + fn solve(&mut self) -> Result { + todo!() + } +} + +impl AdventDayPart2 for Day4Part2 { + fn read_input(&mut self) -> Result<(),AdventError> { + todo!() + } + + fn solve(&mut self) -> Result { + todo!() + } +} + +#[advent_day(Day4Part1, Day4Part2)] +struct Day4; + + + diff --git a/src/days/mod.rs b/src/days/mod.rs index 803a592..75d238b 100644 --- a/src/days/mod.rs +++ b/src/days/mod.rs @@ -16,4 +16,6 @@ pub trait AdventDay { } pub mod day1; -pub mod day2; \ No newline at end of file +pub mod day2; +pub mod day3; +pub mod day4; \ No newline at end of file diff --git a/src/input/mod.rs b/src/input/mod.rs index 56dc970..ef78c57 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -26,4 +26,14 @@ pub fn get_lines(file_path: &Path) -> Lines> { let buf = BufReader::new(file); let lines = buf.lines(); lines -} \ No newline at end of file +} + +pub fn get_input(file_path: &Path) -> String { + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push(file_path); + let file = File::open(path).expect("no such file"); + let mut buf = BufReader::new(file); + let mut s: String = Default::default(); + buf.read_to_string(&mut s).unwrap(); + s +} diff --git a/src/main.rs b/src/main.rs index 7c3bce4..32b1164 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,9 +4,10 @@ pub mod days; mod input; use std::env; - use day1::Day1; use day2::Day2; +use day3::Day3; +use day4::Day4; use crate::error::AdventError; use crate::days::*; @@ -15,7 +16,9 @@ fn main() -> Result<(), AdventError> { let mut advent_days: Vec> = vec!( Box::new(Day1::new()), - Box::new(Day2::new()) + Box::new(Day2::new()), + Box::new(Day3::new()), + Box::new(Day4::new()), ); if env::args().len() == 1 {