diff --git a/2024/3.txt b/2024/3.txt new file mode 100644 index 0000000..b004787 --- /dev/null +++ b/2024/3.txt @@ -0,0 +1,6 @@ +]select(23,564)/$!where()>%mul(747,16)*why()mul(354,748)how()$(when()<:mul(428,793) where()from()how()/how()]*?mul(156,996))what()!,what()~@((mul(976,569)]-,>$-~%;mul(426,703)/mul(948,128)>+?+>?%select()*mul(477,567)why()%select()?!(@~how(){mul(182,79),mul(203,707)?[mul(186,170)select(283,626)*/*when()mul(130,392)')^&when(),[;mul(563,902)where()}*}<$/)how()mul(953,129)!!what()#what()!who()mul(852,652)~)+mul(973,163)$?why()]where()mul(158,596)when()@}what(29,454)mul(968,252)<'^'how()when()<*^mul(617,885)when()) +&;'mul(264,456)/mul(713,804),-mul(803,862)mul(575,310)[ why(527,60) )from()mul(475,876)from()when()*^$@:do()mul(557,2)'{^:-*what()mul(611,157) >- when()mul(894,415)!mul(856,397)from(),where()mul(13,373),!where(),do() {how()select()^:(#select(622,699)[mul(395,375)-##>+[what()?mul(535,15)/(];)mul(115,296)mul(201,604)^+[>+do()&:}how()/:mul(34,586)?where(375,645)?:-who()select()'why()>mul(389,101)don't()<^}who()mul(501,691)'select()mul(551,120),]?from(545,381)?*%~mul(492,926),:(who() {$ when()mul(348,721)'?/)?!what(784,670)mul(811,483): where()why()why()>$[when()do(),~*# {/mul(312,382),}*what(944,486)?^{+%mul(224,412)~why();?<]who()*^mul(199,783)what()from()@why()where()what()?select()(}mul(267,247) mul(126,337)select()mul(534,156)($%%}+*@mul(103,848):;'%mul(237,35)<&-where()mul(423,484),!]where()#!mul(281,866)select(750,996)(( *{<^%who()mul(437,982)}:mul(357,682)@< mul(124,834)}~mul(668,671)mul(787,282)from():where()'[mul(985,702)*{: -&where()how()mul(180,738)(from()@mul(240,76),[:'#!:select() mul(822,179)*#how()~!%!who()who()how()where(184,532)#from() [mul(771,388)how()'~!^!@+mul(646,938)+,(({-mul(486,708)^%^from()-(;what()]mul(144,833)~why()%select()&<~how())mul(439,873)mul(677[[;{:?{>[ (mul(25,577))@:mul(727,412)why();?select()?what()};from()*mul(826,116)#*)/where()who();<@!where()~when()where(597,883)-mul(835,616)'((where(808,96)',mul(649,224)&/ mul(35,958)who(871,394) :!-who()where()where()(mul(322,104^what()%,}[why()what()**who()mul(983,838)mul(614,657)what()&,mul(238,871)-{},select()>who()#>mul(943,599)select()select(558,572)?^who() <:mul(572,265))who()[why()!$,-mul(454,326)mul(300,416)what()who()what()[;when()mul(786,381!&who()when()where(381,479) from()!?$,what(),who()mul(429,727)}from(401,661)>{?%mul(518,766)-@who()!mul(276,326),select()%{mul(211,710)/mul(414,532)@!-,>mul(494,611)?%((@)[&who()mul(547/why()]who()*% $'who(675,908)mul(90,974)}mul(427,683)how()[:;mul(443,135)*^+~^{when()who()}[mul(579,135)@:who()mul(267,452)[&!;;where()$}who()mul(662,85)~>what()mul(724,771)$!mul(206,909)@^%mul)when()select(567,468)mul(260,632)who()what()<}what()}@do()mul(866,137why()~)mul(13,816)^!*(mul(351,795)from()(?^ ;;,~'mul(313,157)?mul(222,186)!> &how()$mul(558,129)how()[select()from()'/&when()[^mul(927,606)@?<+how()-}(mul(749,285)!![%~>mul(919,804)+&-->where()!&$/mul(889,472):why() <]++from():)mul(597,828)!*~@mul(61,536)(why()what(): >why()*mul(50,308)mul(980,618){-! ?*why() *mul(506,77)#/where()^~';who()%who():mul(11,806)mul(226,600)?how()% /{//mul(601[><<&mul(70,238)select(176,735)mul(447,978)(^#mul(583,880)@[mul(722,873)>mul(110,728)/+mul(948,566)where(760,139)[ -*why()-mul(92*,:-$how(),where()select(),+mul(954,569)&?#+(mul(482,680)]mul how()&what()%-mul(455,447)-from()+>?[/where()!:mul(502,951)?~mul(953,617)[/]&>^when()mul(234,738who(134,419))&$-${)when()#why()/mul(266,78)&- ;mul(336,100)?$'#{'~:^mul(963,726)/&@mul(738,99){where(903,414)how()>)mul(249,770)$&@ ]from()$how()!select(521,465)mul(617,783)}<>):[,select(333,996)mul(416,179)[[don't()$]>why()@:mul(148,463)from()-do()when()-/how()when()&from(930,269)[mul(10,173)#mul(613,997)(>when(); *'@mul(724,407)don't()-when()why(533,992),')(:mul(472,652)?mul(350,214)!>where(401,417)/from()$where()mul(108,897)*where()<%select();,$mul(177,623)mul(674,586);mul(188,601)where()&/]mul(892,181)$from()?mul(904,15)why()(from()select()?@{?mul(832,651)<)mul(485,621)?%from()^);from();-who()mul(964,655);((select()mul(950,896)mul(103,475)when())/mul(165,476)(*},)where()!(@mul(417,206)&]?why()%-{[select(),mul(162,447)don't()why()!(/# from()~!mul(794,412)':&?why()mul(419,168);&who()%]who()mul(689,382)who(754,484)select())@)#[('mul/#/,select() why()??&mul(868,352)!from()!who(201,267)what(971,755)mul(245,790):!(^~&^where()--mul(334,775),why()why() when()'@?mulwhen()$?!]- '~@)mul(874,152)when()mul(771,202)(>@~;who()/]@mul(331,997)] select()%&mul(230,638)<%/mul(729,194)when()why()-@-select()select()'!&mul(669,652)/@%where()*;mul(799,156)from(){%why()mul(666,169)-#mul(381,557)&'??>+/>[what()mul(534,338)(mul(631,275),#[{when()~select()mul(847,310)when()]~}where()what(661,551)from()!mul(321,129);$where()@ why()where(616,873)-~(mul(888,479)who(),mul(229,502)])when()don't() mul(246,553)why()?select()',*?mul(242,385)}}where()mul(522/why();mul(445,61)mul(746)$why()from()don't()+mulfrom()#mul(521,245)]%?]}mul),[who()where()mul(784,56)!why(): when(893,294)&[mul(373,342)<$ *! {[why()mul(513,340)how()}where()'[^)^mul(967,981)^from(740,8)^{what()')mul(244,532)+ who()/*mul(686,40)>mul(178,177),][)-<([mul(595,777)<-how()>(,)}mul(210,328)?why() )$why()where()/['*%mul(654,641)select()$[select()mul(620,43)$from()!mul(573,638)<,#/>why(451,392)/how()mul(450,634) ,%@&,don't()select()~~}%select()when()@%@+!^%mul(621,328){@{)when()#)who(685,504)mul(179,100)select(){from()why()]>-mul(94,187);mul(509,291)-how()when()do()why()@) how()select()+mul(379,538)mul(830,641), /&+-@mul(180,491)how():why()!!'%%where()mul(266,732)when();select():+how()(;%mul+who()}{+do()mul(575,752))how()mul:&from()>who(854,820)mul(850,918)&select()(}+}mul(782,495))<'?(>){where(),mul(957,190)/when()what()who()mul(352,79)why()'mul(652,626)mul(973,815)>[)-];@'mul(327,736)$@mul(221,196)~;>,[what()mul(170,288)what()~:$what()'from(468,557)%&>~who()how()mul(847,27){where()?'mul(736,195)mul(663,417)%mul(301,538)don't()what()select();+[how()?+}/mul(271,885)[when()] select()mul(251,286)],{-why()how()-% what()mul(664,742)from()>^!&mul(583,557)%#{}where()why()))don't()[^[mul(636,736)mul(733,889)mul(415,907)#what()what()from()where()mul(746,170)what()how()%who()/mulhow()don't()*'why()[select(769,463)$'/from()mul(520,584)*who()from()~]>who(862,907)why()mul(423,117)why();mul(100,371)!@<{from()mul(434,31) +*why(816,889)& &:!#!/usr/bin/perl/<$!{ (mul(142,115)where()[}/'when()mul(444,725 ~*:why()& from()when(493,415)&mul(863,234)<@?$/when()'+,mul(722,893),%'don't()~where()why()^,;%;%mul(823,490})$<*$#mul(101,716)&from()%@who() what()mul(881,570)who()@+(/@mul(676select()when()*;@@]why()#mul(315,278)[%'select()[{[mul(237,596)mul(782%^<^+:/:~how()when()mul(565,260))~where()??mul(4,427)'where()(when()?-}select(314,151)mul(361,206)-what()!!mul(575,211)!@}select()% ;mul(996,776) how()!#'+)what(861,201)who()]when()how()what()#mul(862,926)when()*;#:['mul(189,238) :[how()who(971,4)~+<(mul(481,269)%mul(632,943)from(){{}'why()who(); select()mul(364,748){;,mul(214,990)from(){>$?:why())mul(206,633)where()what()]*@<$who()}+mul(14,141))mul(822,373)]? how()[from(){mul(978,657{,%]{^mul(688,489)##![why(){}do()#why(),];)when()who()mul(305,206)<]<~ ]don't()?mul(304,632) [mul(291,282)+}{when(),from()#mul(662,53)}mul(5,779)#mul(111,303)where()+!<*'%how(960,285);>mul>mul(852,693)%;)*$':;]who()mul(249,548)@)select()]mul(387,459):/'when()$-[>!mul(112,988)from()@~> $mul(191,655);mul(79,498)~)<@/$@;when()#mul(513,202)][*how()$[from()mul(224,73)&'-&,why()@#from()mul(737,275)who()-[from()mul(816,564)mul(66,866)'from(239,497)how()>>%/<%who()mul(846,687)how()how(854,968)don't()@@[*>where()!mul(268,28)+[#(? -mul(398,631)&?}}^-$&~mul(283,82)@what()don't() what()mul(720,734),? who()mul(380,889)%+select())*how()how();%[mul(48,988)$;mul(968,247)* mul(884,462)*#from()>mul(366}what()]((<+mul(133,244)*'{-where()mul(729,105)how(619,497);from()+from()when()when()when()from()mul(900,829)$mul(83,600)*how()why()mul(434,610)don't())(?@^,mul(691,992)}^:why(784,454)don't()$&#mul(892,279);':what(){~when()what(361,846)']mul(720,864),why()where()mul(303,491)&;[what()mul(720,732)$~,who();/!mul(407,549)-select()!mul(127,272)-%['???select()what(412,125)]don't()&where()]mul(322,71)@/+select()why()$?mul(650,186)&@>@[:![mul(887,229)why()]select(298,963)where()when()?where(992,533):mul(753,118)[what()what()$@(what()]mul(683,687)@[mul(471,355)why()who()$>^?how()mul(271,372)mul(68,707)#when(358,219)'&who()mul(811,52)who()<-:#(from()~mul(160,946)!'@>?[;what()mul(206,444)[$why();why()&:mul(299,200)?what()[what() (+mul(298,431)<$^'(mul(822,566)why()when()+how()-#]]?mul(401,194),mul(320,99)when()*$where()!+]mul(635,430)mul(474,531)%' }mul(896,524) +@who()$don't()who()#&##mul(245,843)mul(707,597):!,mul(864,931);$mul(605,621)&@mul(700,646)>%what(225,888)!%who()[:select()mul(297,15)]^%~]who()mul(87,793)?+{<-where()%mul(518,305)why()+,(~ /!mul(588,968)mul(295,237):-,}%:{+:who()mulwhat(){~*~/'<>mul(590,124)/mul(719,423)))?:+select()mul(902,901)when(){>mul(455,460)$,what()(&{}how()*{mul(24,765)/]mul(529){[#+>/select()?(+mul(19,771)where()+/+mul(380,138)who()when(){from()@mul~$/don't()))select()mul(333,659)< select(213,174)*!select()mul(310,90)mul(494,223)!$when()~how()@mul(656,481)!*!$mul(705,700)mul(7,569)!#;%}> '?mul(324,975) ^/who()$~^ from();do()~!mul(883,226)]mul(660,990)*select()select()[#}!^mul(426,750)when()')#(when()$select()#mul(790,641)what(196,61)&?where()what()mul(751,795)why()#what()/((*who()select(465,475)'mul(633,76)~%&don't()}/why()where()mul(320,249)who()^{how();?'mul(239;;[}]*(;//mul(51,601)%/~%+!'!how(665,519)mul(611,916)what();mul(174,972)when()-where()-how()('do()mul(108,242)?+mul(870,660)]when()%what()?<:mul(635,416)why(924,420)[<$from()>how(260,907)#where()mul(236,788),,@?from())>mul(97,620):select()!+mul(899,189):!}mul(566,974)'why()select()*where()what())why()~why()mul(908,528):)}^mul(71,100)from(296,15)when()from())&from()#how(869,278)mul(628,153)how()mul(765,691)*mul(186,21)how()/mul(487,725)do()##/::from(){what()%)mul(110,152)*&**,$ from()*mul(992,213)[*/!~mul(797,726)-from()mul(969,578)when(112,655)*how()when(),where()'(mul(440,56))*{'(from()-&mul(113,81)^^what()#!))')[mul;~mul(147,629)!@<#&^]@select()mul(993,659),{ mul(254,347<<>}why()(who()>!)how()mul(518,738)what(29,303)from()mul(160,896)do(){/;?what()where()where()how()mul(173,649)mul(969,370$~>mul(679,266)how()>@):@where()mul(206,774))[from()what()where()mul(950,797-) ,^%%mul(996,344)what();select()#mul(332,248)*!'<&~mul(408+how()mul(114,169)$@~select()@~who()mul(901,342)*mul(499,634)%!mul(996,710)~/$}select()mul(8,949)$;(!};from(): mul(860,166)(@-from()'',mul(739,160)$%who(265,676) mul(988,26) ,+/mul(293,416)where()+#}-from(){(@(mul(215,463)mul(152,776)+*]'#'mul(447,726)how()-#}select()what()select(892,487)% mul(182,115)^$<(why()mul(335,275)when(801,993)];select()}'>^how()>do()mul(704,863)+why()'*&mul(709,745)who(){select()mul(17,822)}from()!+;!+,where()]mul(280,107)~?}how()/'(?who()mul(288,599)%what() ]$)mul(463,772)@mul(992,279)what()!:why()>>who() (mul(348,687)*]mul(477,896)when(47,10)&where()?what()%[mul(804,970)from()from()select()+what()[who()-?mul(166,890)&-^mul(892,532)mul(905,17)*)/]>@ {*:mul(361,902)[$]~*mul(629{*<)how()$from()#({mul(924,910)'who()why()'&)}mul(322,152) &mul(503,282)^ )/what()what()%mul(678,160)when()!?&#<%^*mul(661,59)(*mul(936]';)];)who()&&mul(437,929)who()mul(298,239)<(%:>}do()mul(727,688)~(<)who(846,894)mul(720,201)!$@)}mul(139,406)~!$mul(123,17)&select(564,607)(]:who()where();^//mul(905,342)&%)mul(185,967)--~+$ when()@mul(594,891)#:[%,;mul(641,786),@>'how()don't(),mul(185,960)(mul(702,204)]]!(%$++# mul(24,904)!mul(109,193)+[{when()mul(579,493)%where():!mul(473,16)$from()]mul(33,997)mul(104,325)'mul(486,457)select()who()<-who()]&mul(720,711)&do()how()!/!%*^^mul(239,525),from()select()mul(77,963)how()]where(){what()+mul(452,303);/~mul(55,517)&>^~when()-mul(949,308)(@~@what()@**how()mul(185,245)+}how() select()mul(89,379)~&!@ where()-) diff --git a/2024/aoc b/2024/aoc index 7e07e3a..dd39998 100755 Binary files a/2024/aoc and b/2024/aoc differ diff --git a/2024/aoc.cpp b/2024/aoc.cpp index 37643ad..f2206f5 100644 --- a/2024/aoc.cpp +++ b/2024/aoc.cpp @@ -3,6 +3,7 @@ #include "aoc.hpp" #include "day1.hpp" #include "day2.hpp" +#include "day3.hpp" int main(int argc, char** argv) { diff --git a/2024/day3.hpp b/2024/day3.hpp new file mode 100644 index 0000000..ef5def0 --- /dev/null +++ b/2024/day3.hpp @@ -0,0 +1,104 @@ +#include "aoc.hpp" + +#include + +class Day03 : public AOCDay +{ +public: + Day03() {} + ~Day03() {} + int Day() override {return 3;} + + int PartOne(File& f) override + { + int result = 0; + for (std::string input : f.Lines()) + { + // for each char + bool searchingParams = false; + bool firstComma = false; + bool closeBrace = false; + std::string leftS; + int left = -1; + std::string rightS; + int right = -1; + + for (int i = 0; i < input.length(); i++) + { + if (closeBrace) + { + std::cout << "mul(" << left << "," << right << ")=" << left*right << std::endl; + if (left != -1 && right != -1) + { + result += left * right; + } else + { + std::cout << "Failed to parse" << std::endl; + } + searchingParams = false; + firstComma = false; + closeBrace = false; + leftS = ""; + left = 0; + rightS = ""; + right = 0; + i -= 2; + continue; + } + + if (searchingParams) + { + if (!firstComma) + { + if (input[i] == ',') + { + left = std::atoi(leftS.c_str()); + firstComma = true; + continue; + } + leftS += input[i]; + } + + if (!closeBrace && firstComma) + { + if (input[i] == ')') + { + right = std::atoi(rightS.c_str()); + closeBrace = true; + continue; + } + rightS += input[i]; + } + if (std::isdigit(input[i]) == 0) + { + searchingParams = false; + firstComma = false; + closeBrace = false; + leftS = ""; + left = 0; + rightS = ""; + right = 0; + std::cout << "found bad char : " << input[i] << " IsDigit? : " << std::isdigit(input[i]) << std::endl; + continue; + } + } + + if (input[i] == 'm' && input[i + 1] == 'u' && input[i + 2] == 'l' && input[i + 3] == '(') + { + i = i + 3; + continue; + searchingParams = true; + } + } + } + + return result; + } + + int PartTwo(File& f) override + { + } +}; + +ADD_AOC_DAY(Day03); + diff --git a/2025/1.txt b/2025/1.txt new file mode 100644 index 0000000..95c8342 --- /dev/null +++ b/2025/1.txt @@ -0,0 +1,4392 @@ +L32 +L15 +R38 +R47 +L40 +L9 +R27 +L7 +R27 +R37 +L26 +R49 +R29 +L24 +L42 +R29 +R2 +R47 +R19 +L46 +R1 +L30 +R34 +L16 +R41 +L32 +R46 +L17 +R34 +R9 +L22 +L42 +R22 +L15 +L15 +L42 +R42 +L6 +R42 +R34 +R13 +L2 +L9 +L45 +R3 +R30 +L5 +R11 +R18 +L42 +R68 +L94 +R7 +L15 +R34 +L26 +R23 +L97 +L18 +R61 +L96 +R88 +L16 +L19 +L7 +L93 +R50 +R67 +L17 +L38 +L62 +R91 +L14 +R89 +R15 +R42 +L46 +L93 +R16 +R24 +R76 +R50 +R30 +R20 +L57 +L43 +L97 +L1 +L54 +R52 +L95 +R95 +L94 +L24 +L64 +R60 +R68 +R32 +L50 +R58 +R6 +L92 +L121 +R33 +R288 +L20 +L4 +L1 +R25 +R86 +R49 +R65 +L48 +R948 +L48 +L1 +R77 +R42 +L70 +L98 +L7 +L30 +L758 +R293 +R94 +L510 +R14 +R5 +R14 +R37 +L55 +R185 +R16 +R870 +L40 +L18 +L152 +R10 +R914 +L84 +L51 +L447 +L2 +R57 +R43 +L448 +L80 +R83 +R45 +L94 +L10 +R88 +R57 +L31 +L10 +L187 +L86 +R73 +R54 +R32 +L8 +R117 +L4 +R9 +L56 +R56 +L13 +L265 +L22 +L335 +R35 +R30 +L60 +L70 +R28 +L428 +L516 +L4 +R462 +R675 +R6 +L22 +L58 +L43 +R60 +L60 +L11 +R94 +R66 +L49 +L73 +L83 +L7 +L95 +L84 +L64 +R28 +R33 +R45 +L17 +R94 +L887 +L390 +L81 +L38 +L95 +L13 +R38 +L11 +L917 +R17 +R61 +R47 +L659 +L50 +R59 +R80 +R44 +L35 +L47 +L191 +L79 +L30 +R79 +L79 +R88 +R97 +R27 +R6 +R37 +L8 +R139 +L552 +L71 +R48 +R19 +L246 +L95 +L56 +R397 +L14 +L93 +R80 +R86 +R11 +R585 +L85 +L91 +L909 +R92 +R8 +L82 +L50 +R45 +L24 +L51 +R59 +L15 +L82 +R58 +L31 +L27 +L727 +R55 +L24 +R47 +L74 +L98 +R29 +R92 +R17 +R83 +L29 +L35 +R52 +R312 +R54 +L20 +R27 +R60 +L91 +L96 +R95 +L29 +R47 +L14 +R64 +L52 +L445 +L23 +L84 +L93 +R63 +R89 +L52 +L78 +R78 +L37 +L11 +L111 +L40 +L901 +R26 +R50 +L676 +L57 +R343 +L5 +L81 +R491 +L12 +R21 +L21 +R592 +R99 +L870 +R83 +L112 +R84 +L55 +R72 +R41 +L13 +L67 +L233 +L62 +R62 +R75 +R25 +L85 +R6 +L21 +R92 +R61 +L71 +R10 +R42 +R66 +R99 +L28 +L71 +R616 +R96 +R65 +L37 +L22 +R49 +L44 +R77 +R95 +L97 +R5 +L3 +L584 +R51 +L67 +L7 +R7 +L153 +R76 +R77 +R6 +L13 +L93 +R23 +R977 +L10 +L21 +R31 +R55 +R31 +L36 +L67 +R938 +R99 +L20 +R43 +L43 +R26 +L51 +R37 +R88 +L36 +R648 +R288 +R84 +R67 +R55 +R72 +L309 +R31 +L45 +L55 +L1 +L68 +L71 +R32 +R26 +R982 +L729 +L954 +L98 +R10 +L8 +L4 +L87 +L84 +L84 +R63 +R86 +L97 +R386 +R14 +R86 +R26 +R29 +L17 +R33 +L963 +R26 +R603 +L66 +L71 +R14 +R86 +L60 +R14 +L54 +R92 +L37 +R301 +L56 +R787 +L87 +L49 +R52 +L596 +R8 +R51 +R49 +L29 +L41 +L45 +L36 +L16 +R16 +L945 +L19 +R52 +L52 +L55 +L17 +R72 +R72 +L39 +R72 +R95 +R26 +L11 +R39 +R46 +L1 +R1 +R10 +L55 +R74 +L29 +R85 +R9 +R43 +L37 +R48 +L48 +R35 +R80 +L47 +L319 +L103 +L98 +L21 +L27 +R63 +L563 +L86 +L14 +L752 +L96 +L46 +L6 +L65 +L35 +L86 +L39 +L869 +R51 +R49 +R24 +L830 +L99 +R99 +R14 +R67 +R70 +R34 +L98 +R13 +L17 +L849 +R66 +R60 +R859 +R82 +R799 +L34 +L47 +L48 +R61 +L9 +R31 +L54 +R77 +R38 +R485 +R66 +R43 +L9 +L80 +R76 +L21 +R555 +R70 +L67 +R69 +R24 +R74 +L27 +L63 +R954 +R97 +L61 +L61 +L31 +R46 +L943 +L97 +R48 +L23 +R661 +R57 +L57 +R87 +L87 +L98 +L346 +L62 +R62 +L41 +L85 +L30 +R2 +L26 +R477 +L53 +R83 +L902 +R85 +R34 +R64 +L690 +L72 +L286 +R66 +L96 +R1 +L44 +R246 +R11 +R390 +L290 +L94 +L6 +R143 +R57 +L26 +L18 +R536 +L92 +L136 +L18 +L54 +R8 +L3 +L59 +R16 +L26 +R96 +R76 +L15 +R15 +R10 +L86 +L586 +R28 +R34 +R58 +L603 +L53 +R36 +L38 +R370 +L70 +R1 +R75 +R49 +L89 +R57 +R43 +R16 +R493 +L87 +R73 +L11 +L387 +R67 +L74 +R34 +L967 +R7 +L84 +L70 +R4 +R50 +R39 +L82 +L57 +R289 +L31 +L46 +R66 +L78 +L53 +R53 +R96 +R599 +L98 +L97 +L46 +L54 +L86 +L62 +L58 +R22 +L953 +L63 +R308 +L39 +R3 +R512 +R16 +R98 +L98 +R17 +R83 +R2 +R33 +R87 +L96 +R174 +R270 +L51 +R81 +L571 +R71 +L90 +L41 +L314 +R45 +L55 +L45 +L815 +L23 +L34 +L978 +L50 +R955 +R87 +R58 +L65 +R77 +L99 +L90 +R71 +R193 +L71 +L16 +R64 +L64 +L28 +R885 +R13 +R63 +R446 +L91 +L688 +L61 +R61 +R10 +L92 +L88 +L40 +R99 +L489 +R41 +L80 +L526 +R1 +R152 +L36 +R15 +R33 +L229 +L71 +L43 +R243 +L40 +R40 +L554 +R54 +L20 +L80 +L10 +R89 +R121 +L632 +R46 +R54 +L24 +L44 +L33 +L877 +L88 +L4 +L98 +L258 +L57 +R15 +L9 +L58 +R51 +R217 +R47 +R21 +L69 +R45 +R84 +R65 +L94 +R20 +R80 +R805 +L5 +R48 +R52 +R835 +L35 +L71 +L12 +L17 +R18 +L61 +L22 +L612 +L75 +L48 +R844 +R59 +L13 +L604 +L86 +L41 +L59 +R241 +L41 +L9 +L28 +L427 +R83 +L19 +R59 +R65 +L36 +L88 +R935 +R984 +L19 +L14 +L956 +R70 +R960 +L19 +R813 +R31 +L5 +R61 +L695 +L846 +L23 +R23 +R61 +R39 +L61 +R43 +L17 +R835 +R52 +L52 +L36 +L759 +L86 +R44 +L8 +R45 +R17 +L17 +R69 +L969 +R55 +L55 +L39 +L61 +R13 +L28 +R28 +R87 +R331 +L31 +R461 +R14 +R37 +L12 +R59 +L227 +L33 +L668 +R92 +L3 +R57 +R30 +R93 +L88 +R43 +R94 +L49 +R25 +L75 +R50 +L54 +L46 +R994 +R48 +L42 +R63 +L63 +R7 +R24 +L651 +R73 +L53 +L91 +R91 +R11 +R89 +R44 +R93 +L2 +R65 +L277 +L60 +L42 +R88 +R13 +L922 +R34 +L34 +R87 +L82 +L55 +L78 +L35 +R7 +R125 +L41 +L28 +L711 +L678 +R589 +R3 +L3 +L494 +R89 +R36 +R69 +R51 +R483 +L334 +R95 +L95 +R24 +R68 +R769 +R39 +R44 +R77 +R24 +R87 +R69 +R94 +R23 +L41 +R51 +R72 +L71 +L81 +L4 +L44 +L23 +R49 +L26 +L10 +L90 +L98 +L63 +R60 +L92 +L999 +L69 +L39 +L424 +L76 +R68 +L68 +L23 +L74 +L878 +R8 +L233 +R17 +L17 +R13 +R94 +L85 +R92 +L14 +L25 +R305 +R24 +R236 +R32 +R23 +R22 +L292 +L44 +R819 +R7 +L47 +L860 +L20 +L80 +L10 +L38 +L66 +R14 +R20 +L20 +R8 +L628 +R21 +R59 +L924 +R29 +L665 +L31 +R13 +L335 +L518 +R90 +L81 +R81 +L19 +R28 +R86 +R86 +R23 +R75 +L75 +L91 +L77 +R26 +R19 +L7 +L60 +L33 +R404 +R96 +L719 +R619 +L42 +R42 +R281 +L16 +R77 +R58 +L57 +L63 +L24 +R50 +L6 +R87 +L39 +R752 +R208 +L37 +R25 +R56 +L69 +R517 +L387 +L543 +R89 +R604 +L27 +L36 +L82 +R57 +L120 +R775 +R70 +R814 +L70 +R47 +L71 +L57 +R37 +L81 +R81 +L389 +L11 +R47 +L847 +R83 +R25 +L59 +L220 +R306 +R65 +R39 +L89 +R65 +R85 +R88 +L88 +R816 +R14 +R770 +R58 +L58 +R151 +L251 +R25 +R282 +L7 +L97 +L3 +R88 +L6 +R18 +R29 +R72 +L162 +L51 +R12 +R25 +R975 +L91 +L109 +L314 +L86 +R85 +R85 +L47 +R86 +R93 +R98 +R12 +L83 +R571 +R2 +R8 +L410 +R25 +L18 +R440 +R53 +R81 +L81 +R55 +L34 +L26 +L164 +R7 +R62 +R57 +L57 +L44 +R25 +L50 +R69 +L92 +R640 +R1 +L49 +L19 +L181 +L38 +L446 +R784 +R33 +L1 +L41 +R784 +L90 +L85 +L50 +L50 +R39 +L93 +R78 +L50 +L19 +L29 +L63 +R10 +R985 +L83 +R565 +L57 +L83 +L99 +R99 +R35 +R65 +L15 +L88 +L14 +L86 +R13 +R90 +L84 +L16 +L86 +L14 +L79 +R36 +R43 +L66 +L66 +R532 +L86 +L861 +R47 +R1 +R67 +L12 +R144 +R89 +R8 +L43 +L46 +R892 +L94 +R94 +L80 +R80 +L776 +R76 +L1 +R25 +L56 +R27 +L91 +R91 +R40 +R235 +L93 +L50 +R465 +L50 +L42 +L91 +R35 +L366 +R22 +R88 +L97 +R229 +R8 +R72 +L586 +R86 +L61 +R47 +R14 +L17 +L90 +L4 +L73 +L56 +L460 +L67 +R81 +L15 +L74 +R789 +R39 +R73 +R11 +L74 +L63 +L82 +L39 +L35 +L44 +L57 +R57 +R408 +L10 +L77 +R97 +L18 +L15 +R6 +R89 +R48 +R26 +R284 +R62 +R657 +L641 +R860 +R9 +L27 +R742 +L930 +L29 +L41 +R57 +R43 +R77 +R17 +R6 +R68 +L7 +R14 +R80 +L55 +L75 +L26 +L24 +L775 +R50 +R59 +R91 +L42 +R62 +R280 +R92 +L92 +R51 +R3 +R46 +L22 +L78 +L32 +L220 +L34 +R501 +L44 +L571 +R76 +L20 +L91 +L94 +R72 +L562 +R272 +L34 +L63 +L8 +R13 +L79 +L79 +R424 +L810 +R93 +R90 +R72 +L72 +L219 +L32 +R15 +R55 +L32 +L887 +R59 +L79 +L1 +R212 +L730 +R39 +R90 +R510 +L15 +L30 +R91 +R21 +L67 +L2 +L98 +L630 +L681 +R27 +L16 +L430 +L23 +R53 +R84 +R88 +R91 +R95 +L58 +L38 +R86 +L48 +R81 +L39 +L42 +L35 +L65 +R26 +R4 +L30 +R92 +R346 +R574 +L12 +R64 +R36 +L621 +L89 +R76 +R39 +R887 +R64 +L56 +R268 +L96 +L1 +L402 +L269 +R46 +L64 +L533 +L49 +R42 +R158 +L255 +R80 +R240 +R5 +L88 +L82 +L550 +L683 +R49 +R86 +L2 +L12 +L36 +L152 +L78 +R41 +R85 +L16 +R68 +L369 +L1 +L4 +L1 +R75 +R651 +R32 +R20 +L93 +L188 +R78 +L32 +L91 +R48 +R90 +R85 +L11 +L40 +L11 +R62 +R42 +L369 +L673 +L893 +R762 +R15 +R416 +L33 +R27 +L894 +R4 +L76 +L12 +R29 +R59 +R596 +R67 +R126 +R953 +R142 +L88 +L80 +L40 +L280 +L77 +L23 +L61 +R1 +R54 +R8 +R98 +R26 +L27 +R706 +R348 +R48 +R33 +L64 +L68 +L2 +L26 +R74 +R26 +L74 +L36 +L64 +L3 +R3 +R388 +L29 +L837 +L95 +L27 +R506 +L137 +L369 +R49 +R319 +R32 +R69 +L299 +L8 +R38 +R40 +R60 +R62 +R36 +L98 +L4 +R4 +L74 +L3 +R77 +R24 +L79 +R55 +L512 +L61 +L95 +L33 +L92 +R79 +L53 +R54 +R72 +L2 +L55 +R98 +L204 +R98 +L98 +L96 +L18 +L82 +L22 +R15 +R88 +R19 +R6 +R892 +R2 +R615 +L15 +R984 +R16 +L28 +R804 +R72 +R52 +R48 +R41 +L789 +L72 +L82 +R54 +L42 +R542 +R43 +L84 +R141 +L12 +R782 +R92 +L68 +L92 +R80 +L53 +R71 +L98 +L2 +R97 +L343 +L55 +L99 +L726 +L64 +L10 +R66 +R56 +R20 +R58 +L78 +R78 +R22 +R35 +L195 +R38 +R94 +L837 +L61 +R25 +R86 +L27 +R20 +R89 +R62 +R91 +R14 +L68 +L88 +L79 +L21 +R28 +L328 +L89 +L877 +L789 +R55 +R29 +R30 +L290 +L73 +L13 +R726 +L303 +L78 +R81 +L33 +L96 +L88 +L992 +R30 +R55 +L985 +R16 +R84 +R90 +R70 +L260 +L40 +R4 +L95 +R939 +L34 +L4 +R97 +R14 +R30 +R84 +R5 +L47 +R47 +L445 +L55 +L69 +L90 +R79 +R36 +R579 +L60 +R725 +L52 +L203 +R883 +R91 +R40 +L38 +R3 +L24 +R53 +L53 +R98 +R2 +R78 +R68 +R54 +R31 +L6 +L25 +R78 +R46 +R83 +R58 +L29 +R54 +L90 +L442 +L206 +L450 +R35 +R63 +R95 +R818 +R31 +R253 +L19 +L812 +R63 +L5 +R478 +R42 +R56 +R429 +L26 +R3 +R36 +L42 +R40 +L64 +L76 +R39 +R61 +L147 +R43 +R4 +L4 +L94 +L84 +L27 +L260 +R32 +L76 +L887 +R30 +L30 +L99 +L78 +R72 +R205 +R16 +R977 +R92 +R95 +R824 +R96 +R80 +L98 +L582 +L31 +L605 +R99 +L83 +L70 +R86 +L33 +R66 +R19 +L85 +L68 +L56 +R93 +R61 +R7 +L82 +L68 +R50 +L6 +L110 +L484 +L29 +L14 +L57 +R72 +R10 +L382 +L39 +L71 +L84 +L79 +R73 +L955 +R55 +R63 +L13 +R508 +R29 +L371 +L15 +L38 +L7 +R688 +R46 +L90 +L38 +L6 +L56 +L51 +R94 +L25 +R82 +L87 +R121 +L34 +L23 +R923 +R71 +R47 +L96 +L569 +L56 +L99 +R76 +L95 +R21 +L31 +L69 +L56 +R46 +R16 +R5 +L14 +R77 +L74 +R495 +L470 +L79 +L80 +R928 +L96 +L57 +R39 +R20 +L80 +R80 +R85 +R15 +L403 +R607 +R96 +L63 +R63 +L395 +L5 +L204 +R4 +L93 +R10 +R439 +L95 +R39 +L36 +R936 +L224 +L76 +L761 +R61 +R21 +L421 +L32 +L46 +L67 +R45 +R75 +R25 +L826 +L98 +L544 +L8 +L67 +R753 +R61 +R29 +L11 +R92 +L81 +L73 +L27 +L96 +L4 +R1 +L12 +L628 +R94 +R1 +L56 +R3 +R97 +R889 +L89 +R146 +L46 +R72 +L53 +R381 +R59 +R13 +R365 +R96 +R346 +L857 +R83 +R89 +L86 +R95 +R97 +R567 +L2 +L65 +L44 +R957 +R548 +R60 +R79 +L85 +L57 +L49 +L47 +R38 +L59 +R36 +L477 +R80 +L12 +L71 +R26 +R81 +R75 +L68 +L11 +L46 +L354 +L37 +L14 +L95 +L752 +R376 +L34 +R40 +L30 +R46 +R645 +L22 +R64 +R13 +R93 +R207 +L961 +L39 +L389 +L11 +L91 +L9 +L89 +L311 +R218 +L18 +L33 +L13 +R81 +L40 +L70 +L71 +R68 +L22 +L88 +R89 +R221 +R721 +L43 +R30 +L54 +L78 +R268 +R74 +R60 +R91 +R92 +L40 +L999 +R56 +R368 +R32 +L33 +R76 +L33 +L10 +R93 +L47 +L47 +R23 +L320 +R72 +R326 +L567 +R729 +L57 +R95 +L309 +L69 +R6 +R72 +L557 +L25 +R61 +R21 +L3 +R3 +R17 +L32 +R52 +R63 +R736 +R64 +R3 +R491 +R6 +R77 +R52 +R71 +L99 +L7 +L64 +L299 +R269 +L91 +R79 +R37 +R32 +R12 +R86 +R671 +R452 +R522 +L41 +L844 +L50 +L65 +L17 +R6 +R39 +L579 +R44 +R64 +R885 +R306 +R920 +L68 +R63 +R737 +R12 +R27 +R20 +R72 +R87 +L22 +L96 +L432 +L48 +R70 +L35 +R45 +L97 +R6 +L41 +R9 +L38 +R61 +R58 +L97 +L49 +L54 +L23 +R8 +L976 +L70 +L513 +L55 +L660 +R31 +R35 +L85 +L42 +L35 +L78 +L73 +L31 +R66 +R93 +R93 +L794 +L98 +R87 +R50 +L40 +L48 +L482 +R108 +L26 +L81 +R94 +R9 +L355 +L606 +L91 +R30 +R10 +R59 +R31 +R31 +R69 +R254 +R11 +L793 +R528 +L22 +R60 +R50 +L88 +L79 +R69 +L40 +L50 +R42 +R93 +R23 +R29 +R13 +R552 +L50 +L774 +L70 +R42 +L85 +R322 +R15 +R71 +R80 +L3 +L12 +L50 +L38 +L579 +L14 +L94 +L127 +L568 +L224 +L242 +R48 +R43 +L873 +L270 +R11 +L11 +R57 +R36 +L73 +L20 +L652 +R19 +R33 +L59 +L51 +R112 +L802 +L61 +L739 +L84 +R84 +L11 +R11 +L25 +L75 +R24 +L32 +L92 +R4 +L26 +L78 +L362 +L38 +R64 +L683 +R333 +R86 +L30 +R30 +L42 +L16 +R58 +R60 +L86 +L64 +L29 +L36 +R55 +L9 +R9 +R97 +R45 +R78 +R40 +R82 +R858 +R69 +L92 +R28 +L105 +L306 +L94 +R41 +L463 +R22 +L18 +R22 +L603 +R108 +L9 +L814 +R55 +L58 +R17 +R50 +L44 +L47 +R41 +R49 +L55 +R75 +R42 +R89 +L68 +L663 +L69 +L11 +R11 +R40 +R666 +L49 +L57 +R9 +R87 +L96 +L58 +R58 +L25 +L75 +L35 +L60 +R62 +L67 +L132 +R32 +R606 +L306 +L265 +L35 +R32 +R70 +L20 +L44 +L98 +R31 +L71 +R995 +L95 +R57 +L78 +L79 +R92 +R8 +R42 +R15 +R43 +L8 +R32 +L509 +L4 +L11 +L16 +R24 +L58 +L50 +R32 +L84 +R69 +L17 +R578 +R33 +L313 +L225 +R66 +L901 +L889 +L76 +L81 +L92 +L75 +L25 +R9 +L321 +L34 +L90 +R36 +R72 +R28 +L25 +L72 +L3 +R21 +R88 +L809 +R96 +R397 +L93 +R185 +R33 +R93 +L11 +R29 +L29 +R46 +R46 +R8 +R1 +L1 +R1 +L70 +L11 +R89 +R76 +L86 +L99 +L25 +L75 +L68 +R63 +R5 +R88 +R16 +R96 +R37 +R63 +R9 +R265 +R96 +L70 +R68 +R83 +L3 +R52 +R632 +L63 +L83 +L86 +R55 +R22 +R34 +L11 +L3 +L97 +R42 +L26 +R167 +L78 +L921 +L87 +L97 +L60 +R24 +L64 +L15 +R85 +L54 +L16 +L78 +R178 +R41 +R10 +L75 +L90 +R255 +L41 +L50 +L76 +R26 +R155 +L41 +L6 +L30 +L16 +R6 +L68 +L91 +L11 +L21 +R46 +L68 +R43 +R2 +R48 +R59 +L59 +R66 +L75 +L13 +R174 +R31 +R89 +L3 +L70 +R53 +R79 +R40 +R981 +L57 +R22 +R14 +R33 +R10 +R299 +R79 +R671 +L71 +L61 +L639 +R41 +L41 +R52 +R48 +R209 +R91 +R84 +R96 +L80 +R89 +R17 +R94 +L26 +R26 +R87 +L87 +R807 +L7 +R818 +R92 +R90 +R63 +R37 +L290 +L736 +L36 +R897 +L82 +L675 +R891 +R479 +L60 +R94 +R18 +L565 +L57 +L78 +L50 +R950 +R39 +R77 +L16 +L27 +L81 +R32 +L89 +L66 +R323 +L63 +R1 +R419 +L19 +R70 +L45 +R45 +L22 +L441 +R9 +L46 +R34 +R68 +R98 +L435 +L64 +L86 +L546 +R73 +R83 +R18 +L47 +R87 +L8 +L34 +R59 +R22 +R78 +R60 +L57 +L55 +R86 +R26 +L60 +R71 +R71 +R32 +L74 +R796 +R950 +L382 +L42 +R68 +R96 +L91 +R30 +R52 +L77 +R5 +L660 +R955 +R77 +R644 +L21 +R99 +L99 +L287 +R26 +L39 +L2 +R53 +L769 +R29 +R93 +L72 +R24 +L56 +L25 +L91 +R16 +L10 +L649 +L546 +R5 +L95 +R95 +R81 +L21 +L60 +R63 +R137 +L9 +R283 +L44 +L39 +L11 +L880 +R19 +L19 +R3 +R97 +L79 +L9 +L21 +R804 +R89 +L27 +R43 +R71 +L93 +R46 +L54 +R377 +R954 +L1 +R285 +R182 +L67 +L83 +R30 +R861 +R592 +L27 +L46 +L539 +L188 +L422 +R22 +R82 +R58 +L40 +R43 +L26 +R83 +L555 +L75 +L338 +L78 +R58 +R88 +L734 +L66 +R1 +L501 +L4 +R83 +L54 +R2 +L63 +L97 +R32 +L43 +L95 +R46 +R428 +R36 +R29 +R76 +R41 +R45 +L42 +L49 +L71 +R79 +L79 +R33 +L203 +L88 +L42 +L45 +R91 +R28 +L55 +R381 +L606 +R46 +R13 +R47 +R81 +L58 +R892 +R54 +R31 +L7 +R880 +L31 +L67 +R25 +L15 +L46 +L51 +L31 +R76 +R938 +R84 +L26 +L29 +L775 +L892 +L40 +R34 +R73 +L978 +L222 +R99 +L99 +L862 +R32 +L70 +L80 +R65 +R15 +R869 +R853 +L84 +L552 +L104 +R18 +R93 +R7 +L68 +L32 +L13 +R70 +L1 +R806 +R37 +L35 +L44 +R50 +R449 +R81 +L57 +L73 +R30 +R99 +R802 +R550 +R49 +L49 +R309 +L60 +L28 +R928 +R26 +L40 +R14 +L46 +R722 +R24 +L93 +R85 +L904 +L72 +L916 +R36 +R1 +R77 +L7 +R93 +R84 +R16 +L33 +L86 +R52 +R867 +L585 +L441 +L74 +R53 +R47 +L520 +L87 +L92 +L47 +R80 +L48 +L986 +L76 +L24 +R453 +R66 +L19 +R18 +L18 +L33 +R78 +R235 +L97 +L983 +R801 +L601 +L35 +L23 +R12 +R746 +L73 +R73 +L82 +L65 +L53 +L46 +L655 +L9 +L90 +R2 +R698 +L40 +L63 +L228 +R31 +L99 +L1 +R811 +R2 +R35 +R52 +R39 +L33 +R27 +R2 +R968 +L98 +L14 +L21 +R20 +R537 +L83 +R369 +R59 +R135 +L211 +L96 +R63 +R3 +R634 +R38 +R64 +R80 +R708 +R34 +L23 +R952 +L53 +L86 +L67 +R53 +R9 +L9 +L65 +R8 +L434 +L9 +L373 +L294 +L96 +L30 +R93 +R76 +R734 +R90 +L25 +L961 +L81 +L33 +R52 +L852 +L2 +R2 +L826 +L74 +R5 +R660 +R35 +L27 +L73 +R40 +R11 +L51 +R930 +R599 +R637 +R733 +R101 +L97 +R97 +R22 +L87 +L35 +R43 +R14 +R13 +R68 +R46 +R235 +L19 +R64 +R36 +R559 +L32 +R65 +R637 +L5 +R32 +R44 +L74 +L158 +R32 +R64 +L94 +R60 +L69 +R40 +R39 +L82 +R42 +L84 +R84 +L597 +R20 +L68 +L55 +R83 +L83 +L60 +R60 +R52 +L30 +L94 +R37 +L98 +R33 +R47 +L49 +R1 +L799 +L3 +R732 +L24 +R74 +L958 +R64 +R15 +R64 +R36 +L21 +L997 +R21 +R79 +L92 +R5 +R73 +L79 +L37 +R40 +R454 +L46 +L58 +L61 +L81 +L74 +L91 +L35 +R430 +R70 +L59 +R27 +R932 +L670 +R70 +L71 +L48 +L3 +R22 +R73 +L73 +R887 +L28 +R41 +R11 +L911 +R60 +L476 +R415 +R8 +R96 +L95 +L82 +R374 +R86 +R14 +L6 +L23 +R707 +R333 +R61 +R828 +R17 +L17 +L35 +L39 +L826 +R9 +L9 +L52 +L54 +R98 +R8 +R30 +L60 +L69 +R99 +L65 +L391 +R56 +L618 +R143 +L95 +L96 +R66 +R48 +R52 +R171 +R52 +L17 +L52 +L54 +L13 +L48 +R53 +L117 +R25 +L689 +L11 +L17 +R17 +R3 +L36 +L42 +L48 +R23 +R2 +R98 +R30 +R12 +L942 +L5 +R29 +R76 +L31 +L369 +R10 +R90 +L558 +L42 +R3 +R97 +R858 +L58 +L77 +R84 +R95 +L13 +L89 +L93 +R37 +L521 +R27 +L24 +R2 +R58 +R92 +L78 +L63 +R963 +L985 +L88 +R73 +R96 +L186 +R48 +R45 +R89 +R19 +R89 +L18 +R691 +R27 +L40 +R40 +R12 +R49 +R39 +R30 +L30 +R39 +L98 +R59 +R89 +L89 +R1 +R22 +L23 +R676 +R24 +L55 +R23 +R92 +L360 +L18 +L82 +L89 +R89 +L49 +L51 +R36 +L73 +L63 +L14 +L81 +L986 +L37 +L82 +R44 +L467 +L304 +R69 +L42 +L109 +L3 +R412 +R514 +L14 +L7 +L78 +L15 +L87 +R33 +L56 +R75 +R443 +L42 +L866 +L278 +L22 +R94 +R9 +R94 +L97 +R23 +L823 +R20 +L20 +L85 +R5 +L25 +R768 +L63 +L50 +R5 +R103 +R576 +R8 +L40 +L67 +R55 +R316 +R84 +R10 +L80 +L20 +L29 +R726 +L87 +L110 +L6 +L94 +R45 +R855 +L71 +L62 +L67 +R21 +R79 +L60 +R60 +R196 +L20 +L47 +R25 +R46 +L9 +L503 +L90 +L98 +L455 +L84 +R839 +L56 +R14 +L45 +L14 +L36 +L83 +L80 +L53 +R53 +R247 +R53 +L771 +L80 +R101 +L50 +R62 +R53 +R396 +R58 +R35 +L80 +R285 +R860 +R31 +R38 +L38 +R81 +L81 +L14 +L886 +R13 +L13 +R32 +R68 +R59 +L89 +L31 +L597 +R33 +R78 +R47 +R59 +L90 +R731 +R69 +L169 +L23 +R10 +L98 +L369 +R55 +R57 +R68 +L41 +R28 +L87 +R63 +L19 +R69 +R87 +L80 +L72 +L48 +L47 +R20 +L73 +L956 +R6 +R32 +R156 +R62 +L12 +R20 +R8 +L182 +L74 +L860 +R40 +L40 +L92 +L18 +L90 +R79 +L79 +R41 +R62 +R324 +R401 +R572 +L51 +L571 +L90 +R12 +R37 +L50 +R2 +L28 +L61 +L74 +L726 +L94 +L7 +L99 +R42 +L80 +R11 +L73 +R11 +R2 +L13 +L305 +R95 +L28 +R22 +R5 +R66 +L55 +R95 +R5 +L66 +L34 +R553 +L24 +L29 +L85 +L1 +R23 +R63 +R41 +L91 +L485 +L96 +L169 +R88 +R69 +L57 +R22 +L7 +L15 +L37 +R5 +R39 +R7 +R86 +L81 +L81 +L238 +R9 +L17 +L58 +R15 +R51 +R26 +L26 +R86 +R514 +R74 +L130 +L99 +R255 +L79 +L21 +L16 +L30 +R39 +L87 +R94 +R13 +R68 +L81 +L80 +R9 +R971 +R63 +L99 +R79 +L43 +R32 +L32 +L77 +R58 +R19 +R899 +R41 +R67 +R8 +L15 +L89 +R689 +L421 +R702 +R19 +L41 +R41 +R55 +R317 +L67 +L45 +L58 +R798 +L41 +L15 +L97 +L84 +L27 +L81 +L55 +R32 +L32 +L515 +L46 +R61 +L80 +L32 +R812 +R4 +R239 +L43 +L30 +L70 +R2 +R98 +L568 +R57 +R11 +L62 +L98 +R60 +L72 +R72 +R959 +R54 +L15 +R965 +L54 +L909 +L4 +R612 +R5 +L13 +L31 +L57 +L54 +R60 +R11 +R63 +R1 +R11 +R15 +R322 +L96 +R18 +R19 +R28 +L10 +R70 +L70 +R18 +L86 +R594 +L73 +R747 +R494 +L434 +R40 +L69 +R94 +L67 +L76 +L82 +R434 +L273 +L383 +R30 +R37 +L84 +R2 +L763 +L839 +L92 +L69 +R99 +L18 +L81 +R16 +L16 +R55 +L455 +R56 +L42 +R86 +L48 +R29 +R84 +R35 +L36 +R731 +R437 +R56 +L789 +L29 +L81 +R45 +R4 +R5 +R31 +R26 +R95 +R5 +R823 +L48 +R65 +L55 +L672 +L13 +R52 +L52 +R54 +L60 +L955 +L339 +R12 +L12 +L94 +L6 +L294 +L706 +L42 +R523 +L845 +R16 +R437 +L89 +R36 +L56 +L80 +R46 +L643 +R76 +L971 +R775 +R17 +R57 +L57 +R65 +L65 +L62 +L89 +L49 +L81 +L19 +R605 +L58 +R53 +L31 +L52 +L17 +R44 +L368 +L528 +L48 +L92 +R87 +R25 +R96 +L16 +R282 +R18 +L330 +R730 +R45 +R42 +R65 +L95 +R32 +R56 +L245 +L32 +L44 +L520 +R4 +R401 +R691 +L37 +L29 +R750 +L92 +R8 +L53 +L29 +R82 +R80 +R95 +L920 +R412 +L267 +L4 +R440 +L36 +L90 +R90 +R502 +R98 +L45 +R45 +L7 +L495 +R11 +L3 +L6 +L51 +R51 +L2 +L898 +L61 +L86 +R298 +R392 +L55 +R12 +R80 +R920 +R88 +L864 +L91 +R37 +L25 +R55 +L92 +R5 +R31 +R81 +L23 +R698 +L75 +R312 +L14 +R777 +R61 +L61 +L51 +R53 +L269 +R67 +R73 +R27 +R8 +L508 +L473 +R82 +L90 +R217 +R88 +R76 +R857 +R97 +R8 +L462 +R67 +L808 +L950 +R55 +R42 +L58 +L91 +R96 +R947 +L40 +R340 +L74 +R571 +L82 +L793 +R90 +L12 +L5 +L97 +L316 +L82 +L75 +R152 +L13 +L64 +L14 +L86 +L796 +R27 +R69 +R36 +R352 +R12 +L167 +L13 +L20 +L68 +R82 +R45 +L41 +L18 +L47 +L446 +L54 +L91 +R333 +L95 +L22 +R22 +L74 +R38 +L20 +L39 +R85 +L76 +R74 +L82 +L6 +R36 +R64 +L27 +R27 +L86 +R86 +L40 +L20 +L86 +L65 +R28 +L12 +L573 +R529 +R39 +L10 +R19 +R491 +L169 +R888 +L5 +L37 +L65 +L5 +L107 +L3 +R97 +R36 +R95 +L178 +R56 +R291 +R98 +R8 +R83 +R371 +R69 +L72 +R649 +R76 +R25 +L1 +L20 +L65 +R16 +R27 +L58 +R246 +L46 +L75 +L82 +L43 +R439 +R61 +R46 +R52 +R21 +L29 +R10 +L51 +R691 +R60 +L840 +L85 +L75 +R95 +R63 +L80 +L56 +L22 +R668 +R212 +L62 +R82 +R24 +L124 +R17 +R15 +R68 +L30 +R306 +R24 +R56 +L11 +L913 +L32 +L721 +L79 +L53 +L47 +R39 +R82 +L476 +R134 +L79 +L9 +R9 +R89 +R11 +L71 +L29 +L35 +R93 +L931 +R78 +R18 +L23 +L51 +L81 +R7 +R291 +R68 +L934 +R52 +R48 +L50 +R50 +R77 +L77 +R503 +R97 +R21 +L21 +R39 +L83 +L202 +R13 +R933 +R145 +L545 +L13 +R90 +R93 +R95 +R735 +L327 +L73 +L44 +L656 +R40 +R60 +L6 +L94 +R15 +L15 +R4 +L4 +R60 +L52 +L408 +L75 +L21 +R685 +R95 +L608 +R89 +R35 +L55 +R89 +L94 +L740 +R50 +R11 +R96 +R85 +L42 +R6 +L6 +R370 +L770 +R558 +R211 +R69 +L238 +L84 +L258 +L42 +L962 +L48 +L36 +R589 +R41 +R16 +R84 +R38 +L38 +R70 +R81 +R149 +L94 +L6 +R741 +R36 +L64 +L20 +L693 +L140 +L89 +R29 +L211 +R11 +L13 +L49 +L938 +L62 +R62 +R71 +R21 +L258 +R66 +L9 +L76 +L38 +R46 +R97 +R11 +R648 +L66 +R95 +R92 +R563 +L87 +L59 +L4 +R87 +R77 +R23 +L885 +R57 +R5 +R11 +R267 +R22 +L77 +R27 +L25 +R498 +L74 +L16 +L10 +L712 +L979 +L64 +L45 +R95 +R205 +R394 +R295 +L46 +L43 +L83 +R159 +R95 +L897 +R963 +L37 +R10 +R890 +R733 +L54 +L479 +R49 +L79 +R799 +R931 +R269 +R587 +L38 +R82 +R64 +L30 +R66 +L94 +R35 +R721 +R38 +L47 +R47 +R80 +L709 +L15 +R84 +L55 +R215 +R26 +R95 +L57 +L97 +R20 +R76 +R72 +R65 +L372 +R795 +R77 +R78 +L78 +R34 +R66 +R81 +L66 +L65 +R50 +R34 +R932 +R234 +L35 +R295 +R85 +L7 +L938 +R809 +L34 +L41 +L34 +R17 +R47 +L64 +R54 +L17 +R60 +R27 +L24 +R57 +R10 +L31 +L36 +R96 +R738 +L10 +R326 +R553 +L67 +L65 +L76 +L95 +R82 +R18 +L78 +R732 +R884 +L68 +R9 +R20 +R88 +R94 +R14 +R5 +R11 +R89 +R926 +L58 +L68 +L831 +R23 +R91 +R30 +L48 +R90 +R13 +L68 +L95 +L14 +R54 +L45 +L75 +L990 +R694 +L29 +L570 +L77 +L76 +L66 +L911 +R286 +R14 +L54 +R6 +L6 +L78 +L235 +R67 +R579 +L79 +R713 +R534 +L67 +L66 +L23 +R263 +L25 +L67 +R428 +L18 +R35 +L75 +R59 +L2 +R82 +L71 +L31 +R7 +R527 +R797 +L31 +R86 +L91 +L86 +R88 +R34 +R839 +R81 +L47 +L35 +R60 +R2 +R694 +R81 +R25 +L44 +R342 +L546 +L98 +L54 +L2 +L98 +R944 +R56 +L24 +R71 +L47 +L65 +R53 +L84 +R52 +R79 +L726 +L62 +R753 +L42 +R94 +L3 +L49 +R66 +L370 +R4 +R49 +R18 +R10 +L177 +R878 +L78 +L804 +R88 +L62 +R78 +L519 +R19 +R97 +R69 +L91 +R16 +R45 +L36 +R61 +R18 +L79 +L7 +R58 +L54 +L731 +L266 +L15 +L59 +L57 +L782 +R13 +R38 +L614 +R51 +R25 +L44 +L256 +L72 +R4 +R64 +L547 +L40 +R692 +L1 +R915 +L6 +R61 +R85 +R43 +R679 +R9 +R19 +R95 +L94 +L38 +L68 +R41 +L41 +R16 +R43 +R12 +L331 +L87 +R47 +L69 +L84 +L47 +L40 +L60 +R63 +L19 +L44 +R61 +L108 +R47 +R95 +L95 +R432 +R71 +R53 +R86 +L418 +L24 +R39 +L531 +L8 +L452 +R32 +R45 +L58 +L43 +L77 +L47 +L95 +L306 +L99 +R85 +R15 +L26 +R726 +R81 +L81 +R64 +R92 +R30 +R2 +R412 +R51 +R28 +L79 +L42 +R27 +L21 +L51 +L13 +R415 +L5 +L76 +L13 +R60 +L81 +R99 +L99 +R4 +L804 +R715 +L52 +L63 +R80 +L98 +L82 +L6 +R56 +R650 +L46 +L54 +R40 +R60 +L8 +R8 +R176 +R45 +L18 +L3 +L67 +R73 +L49 +L9 +R52 +R74 +R431 +R95 +L30 +R738 +R92 +L17 +R17 +L46 +R204 +R46 +R96 +L5 +L131 +R32 +L96 +L66 +L634 +L39 +R639 +L92 +L15 +L93 +L5 +R6 +R35 +L36 +R804 +L18 +L48 +L7 +R83 +R569 +L35 +L48 +L125 +L67 +R92 +R98 +L98 +L15 +L753 +L30 +R747 +L21 +R57 +L635 +R747 +R3 +R17 +R79 +L45 +R53 +L4 +R49 +R89 +L38 +L26 +R876 +L337 +R71 +L23 +R37 +L398 +R9 +R70 +L11 +L12 +R42 +R2 +L56 +R48 +L37 +L55 +L68 +R32 +L64 +R91 +R13 +R51 +R76 +L17 +L69 +L45 +R72 +L73 +L13 +L72 +L55 +L16 +L10 +L32 +L62 +R61 +R39 +R52 +R79 +L48 +L61 +L96 +R57 +R19 +R79 +R45 +R35 +R15 +R85 +R1 +R64 +L65 +L51 +L76 +L17 +R44 +R4 +R15 +L30 +R32 +L48 +L43 +L19 +R27 +R15 +R2 +R22 +L23 +R11 +R34 +R50 +L30 +R34 +R36 +R7 +R27 +L34 +L10 +L48 +L48 +L27 +R21 +R2 +L49 +L24 +R49 +L15 +L44 +L41 +R43 +L20 +L47 +R20 +R7 +R11 +R1 +L44 +R2 +L31 +R7 +R21 +R7 +R23 +R6 +L8 +L14 +L47 diff --git a/2025/Makefile b/2025/Makefile new file mode 100644 index 0000000..0de7060 --- /dev/null +++ b/2025/Makefile @@ -0,0 +1,15 @@ +CXX := clang++ +CXXFLAGS := -std=c++17 -Wall -Wextra -I. + +TARGET := aoc +SRC := aoc.cpp + +all: $(TARGET) + +$(TARGET): $(SRC) + $(CXX) $(CXXFLAGS) $(SRC) -o $(TARGET) + +clean: + rm -f $(TARGET) + +.PHONY: all clean diff --git a/2025/aoc b/2025/aoc new file mode 100755 index 0000000..8b02657 Binary files /dev/null and b/2025/aoc differ diff --git a/2025/aoc.cpp b/2025/aoc.cpp new file mode 100644 index 0000000..99f2cd4 --- /dev/null +++ b/2025/aoc.cpp @@ -0,0 +1,118 @@ +#include +#include + +#include "aoc.hpp" +#include "day1.hpp" + +int main(int argc, char** argv) +{ + std::cout << "Advent of Code 2025 runner" << std::endl; + std::cout << "©Ben Kyd 2025, All Rights Reserved" << std::endl; + + // Very shit command-line parsing :tm: + int run_day = 0; + std::filesystem::path base = "./"; + + for (int i = 1; i < argc; ++i) + { + std::string arg = argv[i]; + + // Day flag + if (arg == "-d") + { + if (i + 1 >= argc) + { + std::cerr << "Error: -d requires a day number\n"; + return 1; + } + ++i; + run_day = std::atoi(argv[i]); + std::cout << "Selected day to run: " << run_day << "\n"; + } + + // Path flag + if (arg == "-p" || arg == "--path") + { + if (i + 1 >= argc) + { + std::cerr << "Error: " << arg << " requires a path\n"; + return 1; + } + ++i; + base /= argv[i]; + std::cout << "Selected base path: " << base.string() << "\n"; + } + + // Help flag + if (arg == "help" || arg == "--help" || arg == "-h") + { + std::cout << "\nUsage:\n" + << " -d [day] Run a specific day\n" + << " -p [path] Set a base path for input\n" + << " help Show this help message\n" + << " (no args) Run all days\n"; + return 0; + } + + // Unknown argument + if (arg != "-d" && arg != "-p" && arg != "--path" && + arg != "help" && arg != "--help" && arg != "-h") + { + std::cerr << "Unknown argument: " << arg << "\n" + << "Use 'help' for usage information.\n"; + return 1; + } + } + // + // Run days + if (run_day == 0) + { + for (auto& [num, day] : GetRegisteredDays()) + { + std::cout << "Running Day " << num << ":\n"; + + std::string filename = std::to_string(num) + ".txt"; + std::filesystem::path path = base / filename; + + std::cout << "Reading " << path << "..." << std::endl; + File file{path}; + File file1{path}; + + int partOne = day->PartOne(file); + int partTwo = day->PartTwo(file1); + + std::cout << "Part 1: " << partOne << "\n"; + std::cout << "Part 2: " << partTwo << "\n"; + } + } else + { + for (auto& [num, day] : GetRegisteredDays(run_day)) + { + std::cout << "Running only Day " << num << ":\n"; + + std::string filename = std::to_string(num) + ".txt"; + std::filesystem::path path = base / filename; + + std::cout << "Reading " << path << "..." << std::endl; + File file{path}; + File file1{path}; + + auto start = std::chrono::high_resolution_clock::now(); + + int partOne = day->PartOne(file); + + auto endpart1 = std::chrono::high_resolution_clock::now(); + auto startpart2 = std::chrono::high_resolution_clock::now(); + + int partTwo = day->PartTwo(file1); + + auto end = std::chrono::high_resolution_clock::now(); + + std::cout << "Part 1: " << partOne << " - took " << std::chrono::duration(endpart1 - start).count() << "ms" << std::endl; + std::cout << "Part 2: " << partTwo << " - took " << std::chrono::duration(end - startpart2).count() << "ms" << std::endl; + std::cout << "Day " << run_day << " ran in " << std::chrono::duration(end - start).count() << "ms" << std::endl; + } + } + +} + diff --git a/2025/aoc.hpp b/2025/aoc.hpp new file mode 100644 index 0000000..eca63d2 --- /dev/null +++ b/2025/aoc.hpp @@ -0,0 +1,221 @@ +#pragma once + +#include +#include +#include +#include +#include + +struct FileFragment +{ + int Line, Col; + std::string Data; +}; + +class File +{ +public: + File() = default; + + explicit File(const std::filesystem::path& path) + { + Load(path); + } + + void Load(const std::filesystem::path& path) + { + if (!std::filesystem::exists(path)) + { + throw std::runtime_error("File " + path.string() + " does not exist"); + } + + std::ifstream file(path.string()); + if (!file.is_open()) + { + throw std::runtime_error("Failed to open file " + path.string()); + } + + _lines.clear(); + std::string line; + while (std::getline(file, line)) + { + _lines.push_back(line); + } + } + + /// Split each line by a multi-character delimiter + void SplitBy(const std::string& delim) + { + _tokens.clear(); + + for (size_t lineIndex = 0; lineIndex < _lines.size(); ++lineIndex) + { + const auto& line = _lines[lineIndex]; + std::vector lineTokens; + + size_t start = 0; + int colIndex = 0; + + while (true) { + size_t pos = line.find(delim, start); + if (pos == std::string::npos) + { + lineTokens.push_back({ + static_cast(lineIndex + 1), + colIndex, + line.substr(start) + }); + break; + } + + lineTokens.push_back({ + static_cast(lineIndex + 1), + colIndex, + line.substr(start, pos - start) + }); + + start = pos + delim.size(); + ++colIndex; + } + + _tokens.push_back(std::move(lineTokens)); + } + } + + void SplitByIndex(const int index) + { + _tokens.clear(); + _tokens.reserve(_lines.size()); + + for (size_t lineIndex = 0; lineIndex < _lines.size(); ++lineIndex) + { + const auto& line = _lines[lineIndex]; + std::vector lineTokens; + + // Bounds check + if (index < 0 || static_cast(index) >= line.size()) + { + // Just return whole line as single token if index is out of range + lineTokens.push_back({ + static_cast(lineIndex + 1), + 0, + line + }); + } + else + { + // Left part (may be empty, e.g. index = 0) + lineTokens.push_back({ + static_cast(lineIndex + 1), + 0, + line.substr(0, index) + }); + + // Right part (may be empty) + lineTokens.push_back({ + static_cast(lineIndex + 1), + 1, + line.substr(index) + }); + } + + _tokens.push_back(std::move(lineTokens)); + } + } + + /// Access tokens for a given line (1-based) + const std::vector& TokensForLine(int line) const + { + if (line < 0 || line > static_cast(_tokens.size())) + { + static const std::vector empty; + return empty; + } + return _tokens[line]; + } + + // Access a chunk of tokens for a given line + // E.g. Iterate [1,2], [2,3], [3,4] + std::vector> ChunkView(int line, size_t size, size_t stride) + { + const auto& v = _tokens[line]; + std::vector> chunks; + + if (v.empty() || stride == 0) + return chunks; + + for (size_t i = 0; i + size <= v.size(); i += stride) + { + std::cout << "max " << i + size << " tokens " << v.size() << " index " << i << " size " << size << " stride " << stride << std::endl; + chunks.emplace_back(v.begin() + i, v.begin() + i + size); + } + + return chunks; + } + + + /// Iterate through all lines and their tokens + auto begin() const { return _tokens.begin(); } + auto end() const { return _tokens.end(); } + + /// Access raw lines (before splitting) + const std::vector& Lines() const { return _lines; } + +private: + std::vector _lines; + std::vector> _tokens; // [line][token] +}; + +class AOCDay +{ + public: + // The "driver" will expect the Name + // to have the same string as the input + // return 1 -> 1.txt + virtual int Day() = 0; + + virtual int PartOne(File&) = 0; + virtual int PartTwo(File&) = 0; +}; + +inline std::unordered_map& GetRegisteredDays(int day = 0) +{ + static std::unordered_map days; + + if (day != 0) + { + static std::unordered_map single; + single.clear(); + auto it = days.find(day); + if (it != days.end()) + single[day] = it->second; + else + std::cerr << "Warning: requested day " << day << " not found.\n"; + return single; + } + + return days; +} + +template +struct AOCDayRegistrar +{ + AOCDayRegistrar() + { + auto* instance = new T(); + int day = instance->Day(); + + auto& days = GetRegisteredDays(); + if (days.count(day)) + { + std::cerr << "Duplicate registration for day " << day << "\n"; + delete instance; + return; + } + + days[day] = instance; + } +}; + +#define ADD_AOC_DAY(DAYCLASS) \ + static AOCDayRegistrar DAYCLASS##_registrar_instance; diff --git a/2025/day1.hpp b/2025/day1.hpp new file mode 100644 index 0000000..f426b2b --- /dev/null +++ b/2025/day1.hpp @@ -0,0 +1,74 @@ +#include "aoc.hpp" + +#include +#include + +class Day01 : public AOCDay +{ +public: + Day01() {} + ~Day01() {} + int Day() override {return 1;} + + int dial = 50; + void RotateDial(int diff) + { + dial = (dial + diff) % 100; + if (dial < 0) dial += 100; + } + + int PartOne(File& f) override + { + f.SplitByIndex(1); + + dial = 50; + int res = 0; + for (const auto& lineTokens : f) + { + char direction = (char)lineTokens[0].Data[0]; + int amount = std::stoi(lineTokens[1].Data); + + if (direction == 'L') + { + amount = -amount; + } + + RotateDial(amount); + + if (dial == 0) res++; + } + + return res; + } + + int PartTwo(File& f) override + { + f.SplitByIndex(1); + + dial = 50; + int res = 0; + for (const auto& lineTokens : f) + { + char direction = (char)lineTokens[0].Data[0]; + int amount = std::stoi(lineTokens[1].Data); + + int dir = 1; + if (direction == 'L') + { + dir = -1; + } + + while (amount > 0) + { + RotateDial(dir); + if (dial == 0) res++; + amount--; + } + } + + return res; + } +}; + +ADD_AOC_DAY(Day01); +