diff --git a/day9/build.zig b/day9/build.zig new file mode 100644 index 0000000..a2d8eeb --- /dev/null +++ b/day9/build.zig @@ -0,0 +1,27 @@ +const Builder = @import("std").build.Builder; + +pub fn build(b: *Builder) void { + // Standard target options allows the person running `zig build` to choose + // what target to build for. Here we do not override the defaults, which + // means any target is allowed, and the default is native. Other options + // for restricting supported target set are available. + const target = b.standardTargetOptions(.{}); + + // Standard release options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. + const mode = b.standardReleaseOptions(); + + const exe = b.addExecutable("day9", "src/main.zig"); + exe.setTarget(target); + exe.setBuildMode(mode); + exe.install(); + + const run_cmd = exe.run(); + run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| { + run_cmd.addArgs(args); + } + + const run_step = b.step("run", "Run the app"); + run_step.dependOn(&run_cmd.step); +} diff --git a/day9/input b/day9/input new file mode 100644 index 0000000..7b49b61 --- /dev/null +++ b/day9/input @@ -0,0 +1,1000 @@ +38 +18 +28 +41 +37 +17 +24 +45 +50 +35 +9 +30 +11 +8 +40 +43 +46 +36 +33 +19 +14 +32 +3 +7 +16 +42 +10 +12 +13 +25 +52 +15 +21 +18 +29 +17 +20 +22 +11 +51 +23 +24 +34 +30 +26 +33 +14 +50 +27 +28 +31 +36 +44 +32 +35 +25 +37 +38 +40 +59 +39 +41 +42 +43 +70 +55 +45 +57 +46 +47 +58 +80 +52 +68 +53 +56 +60 +95 +62 +63 +72 +75 +77 +79 +109 +174 +83 +139 +96 +91 +92 +98 +93 +99 +100 +254 +120 +428 +161 +162 +154 +149 +195 +153 +232 +334 +581 +156 +170 +175 +176 +189 +197 +187 +183 +190 +191 +199 +219 +220 +309 +269 +302 +372 +345 +751 +305 +323 +410 +331 +326 +332 +339 +346 +374 +359 +370 +769 +382 +373 +381 +419 +418 +439 +489 +592 +571 +607 +651 +669 +628 +665 +685 +709 +657 +658 +1068 +792 +705 +1151 +729 +1060 +754 +763 +791 +1010 +1342 +857 +928 +1146 +1163 +1178 +1297 +1515 +1648 +1285 +1438 +1315 +1362 +1363 +1387 +1434 +1459 +1468 +1483 +1492 +1517 +1926 +1620 +1719 +2091 +2003 +2020 +3237 +2309 +2341 +2475 +3011 +2927 +4242 +3640 +2821 +2893 +2846 +4540 +2917 +2902 +4305 +2985 +6130 +3009 +4728 +4094 +3339 +3722 +4023 +4312 +4329 +5294 +4650 +4816 +5296 +8142 +5667 +5714 +5723 +5902 +6707 +8625 +5819 +8708 +8067 +5994 +6324 +6348 +10231 +9006 +9608 +11115 +11625 +10653 +8641 +8979 +9466 +10112 +10483 +10963 +11437 +11381 +11533 +11542 +12672 +14635 +16106 +19949 +17046 +28483 +15814 +22914 +17647 +17620 +17985 +19604 +18107 +18445 +39446 +18753 +19091 +19578 +30985 +34091 +33726 +27251 +24053 +23075 +24214 +27307 +30449 +36137 +36430 +36092 +41861 +33434 +36860 +38669 +66586 +42679 +37198 +36552 +54997 +79211 +37844 +42166 +42653 +47128 +47289 +51360 +48267 +50382 +59505 +51521 +60741 +63883 +69526 +88558 +74396 +80523 +69986 +75221 +148063 +73750 +79851 +88719 +80010 +89294 +99788 +80497 +84819 +102158 +94417 +98649 +131211 +168409 +101903 +148702 +112262 +149996 +137633 +143276 +252154 +143736 +184607 +182248 +148971 +217026 +175653 +164829 +160507 +165316 +259246 +186722 +179236 +272769 +193066 +196320 +200552 +255998 +375556 +364416 +249895 +347564 +292707 +280909 +309478 +309052 +304243 +314287 +342037 +354889 +325336 +530804 +339743 +365958 +526800 +648795 +554792 +435234 +465835 +389386 +859035 +493259 +604784 +542602 +554138 +941502 +573616 +780122 +885693 +613295 +1376736 +963002 +669176 +1047397 +665079 +691294 +1567786 +1222411 +755344 +824620 +928493 +855221 +901069 +882645 +931988 +1334260 +1147386 +1096740 +1207681 +1127754 +1282471 +1186911 +1304589 +1278374 +1334255 +1446638 +1356373 +1360470 +1420423 +2010399 +1579964 +1610565 +1951961 +1656413 +2011531 +1737866 +1756290 +2660962 +1814633 +2214459 +2224494 +3076836 +3804458 +2628104 +2314665 +3184504 +2638844 +2915154 +2612629 +2690628 +4208068 +3531925 +2780893 +3000387 +5691015 +3190529 +3266978 +4537183 +3394279 +5315052 +3552499 +3570923 +4029092 +4039127 +4438953 +4539159 +5708944 +4927294 +5527783 +6661257 +5251473 +7833232 +5781280 +5303257 +5471521 +8718312 +8505581 +5971422 +7610050 +7229656 +6457507 +11162549 +6946778 +11385731 +7123422 +7581591 +8478080 +8068219 +8578286 +8978112 +9466453 +10779256 +10554730 +13849499 +11222895 +13084705 +10774778 +11084537 +11274679 +15841734 +12428929 +12918200 +21777625 +13404285 +14525726 +15601502 +14070200 +14528369 +19752759 +19532842 +15649810 +16546299 +20550990 +22870738 +18444565 +20021183 +21329508 +21639267 +21859315 +31251312 +26488990 +26926271 +26988400 +23703608 +25347129 +25833214 +26322485 +44200246 +53248756 +22406676 +47692529 +28598569 +32196109 +34094375 +38185566 +34990864 +36567482 +38465748 +43188823 +40083832 +41350691 +61082775 +43498582 +51005245 +64298962 +46110284 +47753805 +48239890 +48729161 +60824078 +52155699 +86425456 +56501051 +79888638 +67186973 +60794678 +62692944 +66290484 +69085239 +71558346 +73456612 +105881767 +78549580 +81434523 +123487622 +84849273 +98265983 +91738472 +93864089 +148239523 +94350174 +99909504 +96969051 +100884860 +123688024 +145014958 +117295729 +119193995 +142581582 +127085162 +128983428 +135375723 +139747096 +166054290 +159984103 +195235034 +163398853 +173172995 +175298612 +176587745 +178713362 +185602561 +186088646 +302401386 +191319225 +194259678 +196878555 +260868963 +243466442 +236489724 +244380891 +246279157 +248177423 +262460885 +256068590 +411576276 +321464369 +299731199 +323382956 +430469537 +494966233 +420054187 +351886357 +354011974 +355301107 +607954947 +371691207 +377407871 +668231610 +385578903 +757270110 +433368279 +479956166 +623114155 +480870615 +490660048 +494456580 +562192084 +651617556 +579451546 +621195568 +644847325 +675269313 +677394930 +723577564 +705898331 +707187464 +725703181 +862351255 +726992314 +749099078 +1108637592 +818947182 +971530663 +1430765028 +1371839639 +913324445 +970616214 +1146074136 +1322242255 +985116628 +1200647114 +1513968811 +1286639010 +1224298871 +2430879847 +1320116638 +1352664243 +1383293261 +1450569878 +1413085795 +1432890645 +1719715292 +2559207470 +1568046260 +2415881656 +1732271627 +1790477845 +2131190764 +2920362406 +1883940659 +1898441073 +1955732842 +2185763742 +3415996475 +2209415499 +3241047723 +2510937881 +3905479034 +4386612689 +2672780881 +2703409899 +4056074142 +6336358881 +3018616138 +2845976440 +3000936905 +3358524105 +3300317887 +3451986919 +3616212286 +6204500545 +4069704401 +3782381732 +3839673501 +4917057211 +3854173915 +4141496584 +7441814471 +7310752124 +5450463222 +5214347780 +5376190780 +6526954796 +5673717786 +5518757321 +6844906483 +7757708870 +5846913345 +5864592578 +6146294327 +11360642107 +9504818432 +8369044130 +7068199205 +7398594018 +12444389985 +7622055233 +7636555647 +7693847416 +7995670499 +17126873665 +9355844364 +13155312968 +10590538560 +14881009212 +11192475107 +10894948101 +11365670666 +22973787010 +11383349899 +11711505923 +11993207672 +12010886905 +12932791783 +18781943917 +14466793223 +14690254438 +15063869704 +14704754852 +15020649251 +25585202539 +19059518082 +19019905546 +25958817805 +18586209059 +20739194263 +24866818891 +21973888459 +21485486661 +22087423208 +25897229959 +22905835006 +22749020565 +23094855822 +23376557571 +23704713595 +29395009290 +24943678688 +29171548075 +29710903689 +35803063967 +34040554797 +39798712345 +29725404103 +37108072459 +37606114605 +48784922185 +39325403322 +43488214828 +40071695720 +60746742655 +43572909869 +44722909024 +44234507226 +92357832054 +45654855571 +52144029855 +46453734160 +46471413393 +47081271166 +48648392283 +54115226763 +62549793293 +58882451764 +91315778392 +73298313972 +63765958900 +66833476562 +76433475781 +90377764595 +89750144460 +79397099042 +97798885426 +83559910548 +94186922483 +89889362797 +87807417095 +114693823148 +112997678527 +92108589731 +92126268964 +98597764015 +227691501675 +100586640156 +95729663449 +152927557888 +116665020056 +121432245057 +159469091920 +130599435462 +140199434681 +143163057942 +156583621022 +243749698098 +183537080544 +167204516137 +247276509015 +171367327643 +173449273345 +177696779892 +179916006826 +235271647673 +184234858695 +187838253180 +222018885213 +187855932413 +395468158558 +307403950818 +320132074025 +535667593239 +238097265113 +371393012957 +261631679738 +297803951599 +270798870143 +545501215931 +365181943155 +323788137159 +351439374832 +573164938450 +338571843780 +351146053237 +448495650035 +353365280171 +365552712305 +364150865521 +375694185593 +449469932918 +739845051114 +559435631337 +511644069572 +569035630556 +499728944851 +568602821742 +642191883100 +508896135256 +532430549881 +600203523518 +662985894754 +594587007302 +662359980939 +907607474336 +1008905564255 +689717897017 +702722709301 +995557163271 +1564592793827 +815022645223 +717516145692 +729703577826 +887338255165 +825164118511 +1442567760415 +1008625080107 +1324290585128 +1214366778873 +1685275060288 +1032159494732 +1231588716496 +1041326685137 +1103483142558 +1948934159473 +1194790530820 +1256946988241 +1365082690240 +2880065591108 +2240213796603 +1392440606318 +2379615439050 +1420238854993 +1544726223049 +1447219723518 +2812302413758 +1542680264203 +1554867696337 +3705229709619 +1833789198618 +2298273673378 +2040784574839 +2550702866076 +2812679461311 +2811814684578 +2678808440014 +2272915401633 +2615029385813 +5426844070391 +2677185843234 +3376469462821 +2839660329836 +4259899184829 +2867458578511 +3853141369715 +5397867592764 +6320259095432 +3281008922136 +2989899987721 +5679760992269 +3097547960540 +3583464839042 +8593174497065 +3874573773457 +9554334765726 +5321793496975 +7636368647650 +5292215229047 +4887944787446 +5829560317557 +6864473761178 +4950101244867 +5454689715649 +8707852992527 +5516846173070 +6742032351968 +6573364826763 +5965006539051 +5857358566232 +6087447948261 +11208203882878 +8954906526772 +8614394133610 +6972121733997 +8047649205407 +6681012799582 +9166789002504 +8824675018324 +17781183136114 +9838046032313 +10180160016493 +10404790960516 +10242316473914 +10342634503095 +10466947417937 +12197858972652 +14812265093004 +10971535888719 +11374204739302 +11481852712121 +11822365105283 +11944806514493 +17214438207911 +12538371365814 +12768460747843 +13653134533579 +20709263891851 +21554364755795 +17085803760098 +14728662004989 +21724169186035 +18662721050637 +19004835034817 +20018206048806 +20080362506227 +24908822021482 +20809581921032 +20584950977009 +21314170391814 +21438483306656 +39472302971669 +32291434633153 +22345740628021 +42309120163044 +23304217817404 +23767171619776 +36219273242728 +38743083556864 +25306832113657 +26421595281422 +28381796538568 +35538243926021 +31814465765087 +33391383055626 +45387194619884 +39023041083623 +38680927099443 +39085197541044 +45649958445425 +78108238624667 +41394532898041 +42023434283665 +41899121368823 +42752653698470 +87044491343466 +70495392864530 +47071389437180 +59986444862504 +49725813098826 +48611049931061 +59812978337048 +51728427395079 +67352709691108 +75032645212483 +54803391819990 +67062723638011 +81433580797913 +88465922335221 +75414817339291 +77766124640487 +84735155986469 +80984318909867 +80479730439085 diff --git a/day9/src/main.zig b/day9/src/main.zig new file mode 100644 index 0000000..9ad1d8f --- /dev/null +++ b/day9/src/main.zig @@ -0,0 +1,163 @@ +const std = @import("std"); + +pub fn main() anyerror!void { + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + var gpa = &arena.allocator; + + var stream = std.ArrayList(u64).init(gpa); + var f = try std.fs.cwd().openFile("input", .{}); + var contents = try f.readToEndAlloc(gpa, std.math.maxInt(u32)); + var it = std.mem.tokenize(contents, "\n"); + while (it.next()) |line| { + //std.log.debug("{}", .{atoi(line)}); + try stream.append(atoi(line)); + } + + var first_not_matching = find_first_with_no_sum_property(stream.items[0..], 25); + std.log.info("First with no sum property: {} (at index {})", + .{stream.items[first_not_matching.?], first_not_matching.?}); + + // Part 2 + // 22406676 + var ranges = std.ArrayList(Range).init(gpa); + try find_contiguous_sets_matching(stream.items[0..], 22406676, &ranges); + std.log.debug("Found {} ranges summing to {}", .{ranges.items.len, 22406676}); + for (ranges.items) |r| { + std.log.info("Range: {}, len {}. Sum of edge indices: {}", + .{r, r.y - r.x + 1, stream.items[r.x] + stream.items[r.y-1]}); + var s : u64 = 0; + var min: u64 = std.math.maxInt(u64); + var max: u64 = 0; + for (stream.items[r.x..r.y]) |v| { + std.log.debug("{}", .{v}); + s += v; + min = std.math.min(v, min); + max = std.math.max(v, max); + } + std.log.debug("Sum of items in range: {}, min: {}, max: {}; sum min+max {}", + .{s, min, max, min+max}); + } +} + +const Range = struct { + x : usize = 0, + y : usize = 0, +}; + +pub fn find_contiguous_sets_matching(stream: []u64, match: u64, ranges: *std.ArrayList(Range)) !void { + var i : usize = 0; + // start create a window from 0 ... end of list breaking when + // the sum is greater than the match value + // then go on 1 ... end of list + while (i < stream.len) : (i += 1) { + var j : usize = i+1; + while (j < stream.len) : (j += 1) { + std.log.debug("Checking range {}..{}", .{i, j}); + var sum : u64 = 0; + for (stream[i..j]) |v| { + sum += v; + } + if (sum > match) { + break; + } + if (sum == match) { + try ranges.append(Range{.x = i, .y = j}); + break; + } + } + } +} + +/// returns the INDEX of the first non-matching +pub fn find_first_with_no_sum_property(stream: []u64, preamble: u64) ?u64 { + var i : u64 = preamble; + while (i < stream.len) : (i += 1) { + //std.log.debug("Searching for match for {} in indicess {} to {}: {}", + // .{stream[i], i-preamble, i, stream[i-preamble..i]}); + if (!has_sum_property(stream[i], stream[i-preamble..i])) { + return i; + } + } + return null; +} + +pub fn has_sum_property(value: u64, preceding_values: []u64) bool { + for (preceding_values) |v, k| { + for (preceding_values) |w, k2| { + if (k == k2) { + continue; // don't sum against our selves + } + //std.log.debug("[{}, {}] -> {} + {} => {} (searching for {})", + // .{k, k2, v, w, v+w, value}); + if ((v+w) == value) { + return true; + } + } + } + return false; +} + +test "first not having a sum of 5 preamble" { + const preamble : u64 = 5; + var stream = [_]u64 { + 35, + 20, + 15, + 25, + 47, + 40, + 62, + 55, + 65, + 95, + 102, + 117, + 150, + 182, + 127, + 219, + 299, + 277, + 309, + 576, + }; + var idx_not_matching = find_first_with_no_sum_property(stream[0..], preamble); + var i = stream[idx_not_matching.?]; + std.testing.expectEqual(i, 127); +} + + +fn atoi(a: []const u8) u64 { + var i : u64 = 0; + var mul : u64 = 1; + var start : usize = 0; + if (a[0] == '-' or a[0] == '+') { + start = 1; + if (a[0] == '-') { + //mul *= -1; + unreachable; + } + } + for(a[start..]) |v, k| { + if (! std.ascii.isDigit(v)) { + std.log.warn("Byte {x} is not a digit", .{v}); + continue; + } + // 48 is '0' in ascii + std.debug.assert(v >= 48 and v < 58); + i += @as(u64, @as(u64, (v - 48)) * std.math.pow(u64, 10, @intCast(u64, a.len - k - 1 - start))); + } + //std.log.debug("0x{x} --> {}", .{a, i}); + return i * mul; +} + +test "atoi_regular" { + var i = atoi("1234"); + std.testing.expectEqual(i, 1234); +} + +test "atoi_pos" { + var i = atoi("+1234"); + std.testing.expectEqual(i, 1234); +}