From 8b3477650849ae3f54bc3310f93e253e7e472130 Mon Sep 17 00:00:00 2001 From: Moritz Gmeiner Date: Mon, 9 Dec 2024 16:20:46 +0100 Subject: [PATCH] day 9 finished --- day6.zig | 2 +- day7.zig | 2 +- day8.zig | 308 +++++++++++++++++++++++++++++++++++++++++++++ day9.zig | 329 ++++++++++++++++++++++++++++++++++++++++++++++++ inputs/day8.txt | 50 ++++++++ inputs/day9.txt | 1 + lib/utils.zig | 32 +++++ 7 files changed, 722 insertions(+), 2 deletions(-) create mode 100644 day8.zig create mode 100644 day9.zig create mode 100644 inputs/day8.txt create mode 100644 inputs/day9.txt diff --git a/day6.zig b/day6.zig index bda28e2..3bc18f1 100644 --- a/day6.zig +++ b/day6.zig @@ -23,7 +23,7 @@ pub fn main() !void { const result = try part2(alloc, file_reader.reader()); - try std.io.getStdOut().writer().print("Day 6, part 1: {}\n", .{result}); + try std.io.getStdOut().writer().print("Day 6, part 2: {}\n", .{result}); } } diff --git a/day7.zig b/day7.zig index 30fb48f..6d110df 100644 --- a/day7.zig +++ b/day7.zig @@ -25,7 +25,7 @@ pub fn main() !void { const result = try part2(alloc, file_reader.reader()); - try std.io.getStdOut().writer().print("Day 7, part 1: {}\n", .{result}); + try std.io.getStdOut().writer().print("Day 7, part 2: {}\n", .{result}); } } diff --git a/day8.zig b/day8.zig new file mode 100644 index 0000000..9fe2b66 --- /dev/null +++ b/day8.zig @@ -0,0 +1,308 @@ +const std = @import("std"); + +const utils = @import("lib/utils.zig"); + +const spice = @import("lib/spice.zig"); + +const filename = "inputs/day8.txt"; + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const alloc = gpa.allocator(); + + { + const file_reader = try utils.FileReader.init(alloc, filename); + defer file_reader.deinit(); + + const result = try part1(alloc, file_reader.reader()); + + try std.io.getStdOut().writer().print("Day 8, part 1: {}\n", .{result}); + } + + { + const file_reader = try utils.FileReader.init(alloc, filename); + defer file_reader.deinit(); + + const result = try part2(alloc, file_reader.reader()); + + try std.io.getStdOut().writer().print("Day 8, part 2: {}\n", .{result}); + } +} + +fn part1(alloc: std.mem.Allocator, reader: anytype) !u64 { + const Pos = struct { + x: usize, + y: usize, + }; + + var arena = std.heap.ArenaAllocator.init(alloc); + defer arena.deinit(); + + var freq_pos = std.AutoHashMap(u8, std.ArrayList(Pos)).init(arena.allocator()); + defer freq_pos.deinit(); + + var line_reader = utils.lineReader(alloc, reader); + defer line_reader.deinit(); + + var x_size: usize = 0; + var y_size: usize = 0; + + while (try line_reader.next()) |line| : (x_size += 1) { + if (line.len == 0) { + break; + } + + if (y_size == 0) { + y_size = line.len; + } else { + std.debug.assert(y_size == line.len); + } + + for (0.., line) |y, c| { + if (c != '.') { + const entry = try freq_pos.getOrPut(c); + + const pos_list = entry.value_ptr; + + if (!entry.found_existing) { + pos_list.* = std.ArrayList(Pos).init(arena.allocator()); + } + + try pos_list.append(.{ .x = x_size, .y = y }); + } + } + } + + const antinodes = try utils.allocGridInit(bool, alloc, x_size, y_size, false); + defer utils.deinitGrid(bool, alloc, antinodes); + + for (antinodes) |line| { + for (line) |b| { + std.debug.assert(b == false); + } + } + + var it = freq_pos.iterator(); + + while (it.next()) |entry| { + const pos_list = entry.value_ptr.items; + const n = pos_list.len; + + for (0..n) |i| { + const pos_i = pos_list[i]; + + for (0..i) |j| { + const pos_j = pos_list[j]; + + const diff_x = pos_i.x -% pos_j.x; + const diff_y = pos_i.y -% pos_j.y; + + const antinode1_x = pos_i.x +% diff_x; + const antinode1_y = pos_i.y +% diff_y; + + if (antinode1_x < x_size and antinode1_y < y_size) { + antinodes[antinode1_x][antinode1_y] = true; + } + + const antinode2_x = pos_j.x -% diff_x; + const antinode2_y = pos_j.y -% diff_y; + + if (antinode2_x < x_size and antinode2_y < y_size) { + antinodes[antinode2_x][antinode2_y] = true; + } + } + } + } + + var antinode_count: u64 = 0; + + for (antinodes) |line| { + for (line) |b| { + if (b) { + antinode_count += 1; + } + } + } + + return antinode_count; +} + +fn part2(alloc: std.mem.Allocator, reader: anytype) !u64 { + const Pos = struct { + x: usize, + y: usize, + }; + + var arena = std.heap.ArenaAllocator.init(alloc); + defer arena.deinit(); + + var freq_pos = std.AutoHashMap(u8, std.ArrayList(Pos)).init(arena.allocator()); + defer freq_pos.deinit(); + + var line_reader = utils.lineReader(alloc, reader); + defer line_reader.deinit(); + + var x_size: usize = 0; + var y_size: usize = 0; + + while (try line_reader.next()) |line| : (x_size += 1) { + if (line.len == 0) { + break; + } + + if (y_size == 0) { + y_size = line.len; + } else { + std.debug.assert(y_size == line.len); + } + + for (0.., line) |y, c| { + if (c != '.') { + const entry = try freq_pos.getOrPut(c); + + const pos_list = entry.value_ptr; + + if (!entry.found_existing) { + pos_list.* = std.ArrayList(Pos).init(arena.allocator()); + } + + try pos_list.append(.{ .x = x_size, .y = y }); + } + } + } + + const antinodes = try utils.allocGridInit(bool, alloc, x_size, y_size, false); + defer utils.deinitGrid(bool, alloc, antinodes); + + for (antinodes) |line| { + for (line) |b| { + std.debug.assert(b == false); + } + } + + var it = freq_pos.iterator(); + + while (it.next()) |entry| { + const pos_list = entry.value_ptr.items; + const n = pos_list.len; + + for (0..n) |i| { + const pos_i = pos_list[i]; + + for (0..i) |j| { + const pos_j = pos_list[j]; + + const i_minus_j_x = pos_i.x -% pos_j.x; + const i_minus_j_y = pos_i.y -% pos_j.y; + + { + var antinode_x = pos_i.x; + var antinode_y = pos_i.y; + + while (antinode_x < x_size and antinode_y < y_size) { + antinodes[antinode_x][antinode_y] = true; + + antinode_x +%= i_minus_j_x; + antinode_y +%= i_minus_j_y; + } + } + + { + var antinode_x = pos_j.x; + var antinode_y = pos_j.y; + + while (antinode_x < x_size and antinode_y < y_size) { + antinodes[antinode_x][antinode_y] = true; + + antinode_x -%= i_minus_j_x; + antinode_y -%= i_minus_j_y; + } + } + } + } + } + + var antinode_count: u64 = 0; + + for (antinodes) |line| { + for (line) |b| { + if (b) { + antinode_count += 1; + } + } + } + + return antinode_count; +} + +test "part1 example" { + const alloc = std.testing.allocator; + + const example = + \\............ + \\........0... + \\.....0...... + \\.......0.... + \\....0....... + \\......A..... + \\............ + \\............ + \\........A... + \\.........A.. + \\............ + \\............ + ; + + var stream = std.io.fixedBufferStream(example); + + const result = try part1(alloc, stream.reader()); + + try std.testing.expectEqual(14, result); +} + +test "part1 input" { + const alloc = std.testing.allocator; + + const file_reader = try utils.FileReader.init(alloc, filename); + defer file_reader.deinit(); + + const result = try part1(alloc, file_reader.reader()); + + try std.testing.expectEqual(381, result); +} + +test "part2 example" { + const alloc = std.testing.allocator; + + const example = + \\............ + \\........0... + \\.....0...... + \\.......0.... + \\....0....... + \\......A..... + \\............ + \\............ + \\........A... + \\.........A.. + \\............ + \\............ + ; + + var stream = std.io.fixedBufferStream(example); + + const result = try part2(alloc, stream.reader()); + + try std.testing.expectEqual(34, result); +} + +test "part2 input" { + const alloc = std.testing.allocator; + + const file_reader = try utils.FileReader.init(alloc, filename); + defer file_reader.deinit(); + + const result = try part2(alloc, file_reader.reader()); + + try std.testing.expectEqual(1184, result); +} diff --git a/day9.zig b/day9.zig new file mode 100644 index 0000000..89ea072 --- /dev/null +++ b/day9.zig @@ -0,0 +1,329 @@ +const std = @import("std"); + +const utils = @import("lib/utils.zig"); + +const spice = @import("lib/spice.zig"); + +const filename = "inputs/day9.txt"; + +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const alloc = gpa.allocator(); + + { + const file_reader = try utils.FileReader.init(alloc, filename); + defer file_reader.deinit(); + + const result = try part1(alloc, file_reader.reader()); + + try std.io.getStdOut().writer().print("Day 8, part 1: {}\n", .{result}); + } + + { + const file_reader = try utils.FileReader.init(alloc, filename); + defer file_reader.deinit(); + + const result = try part2(alloc, file_reader.reader()); + + try std.io.getStdOut().writer().print("Day 8, part 2: {}\n", .{result}); + } +} + +fn part1(alloc: std.mem.Allocator, reader: anytype) !u64 { + const FsEntry = enum(u32) { + empty = std.math.maxInt(u32), + _, + }; + + const input = try reader.readAllAlloc(alloc, std.math.maxInt(usize)); + defer alloc.free(input); + + var filesystem_list = std.ArrayList(FsEntry).init(alloc); + defer filesystem_list.deinit(); + + var next_id: u16 = 0; + var is_gap = false; + + for (input) |byte| { + if (byte == '\n') { + break; + } + + std.debug.assert('0' <= byte and byte <= '9'); + + const len: usize = @as(usize, byte - '0'); + + if (is_gap) { + try filesystem_list.appendNTimes(.empty, len); + } else { + try filesystem_list.appendNTimes(@enumFromInt(next_id), len); + + next_id += 1; + + std.debug.assert(next_id != @intFromEnum(FsEntry.empty)); + } + + is_gap = !is_gap; + } + + const filesystem = filesystem_list.items; + + // for (filesystem) |x| { + // switch (x) { + // .empty => std.debug.print(".", .{}), + // else => std.debug.print("{}", .{@intFromEnum(x)}), + // } + // } + // std.debug.print("\n", .{}); + + var start_idx: usize = 0; + var end_idx: usize = filesystem.len - 1; + + while (start_idx < end_idx) { + + // for start_idx: seek next empty position + if (filesystem[start_idx] != .empty) { + start_idx += 1; + continue; + } + + // for end_idx: seek next full position + if (filesystem[end_idx] == .empty) { + end_idx -= 1; + continue; + } + + std.debug.assert(filesystem[start_idx] == .empty and filesystem[end_idx] != .empty); + + filesystem[start_idx] = filesystem[end_idx]; + filesystem[end_idx] = .empty; + } + + const first_empty_idx = std.mem.indexOfScalar(FsEntry, filesystem, .empty).?; + + for (filesystem[first_empty_idx..]) |id| { + std.debug.assert(id == .empty); + } + + var checksum: u64 = 0; + + for (0.., filesystem) |idx, id| { + if (id == .empty) { + break; + } + + checksum += @as(u64, idx) * @intFromEnum(id); + } + + return checksum; +} + +fn part2(alloc: std.mem.Allocator, reader: anytype) !u64 { + const FsId = enum(u16) { + empty = std.math.maxInt(u16), + _, + }; + + const FsEntry = struct { + len: u16, + id: FsId, + }; + + const input = try reader.readAllAlloc(alloc, std.math.maxInt(usize)); + defer alloc.free(input); + + var filesystem = std.ArrayList(FsEntry).init(alloc); + defer filesystem.deinit(); + + var max_id: u16 = undefined; + + { + var next_id: u16 = 0; + var is_gap = false; + + for (input) |byte| { + if (byte == '\n') { + break; + } + + std.debug.assert('0' <= byte and byte <= '9'); + + const len: u16 = @as(u16, byte - '0'); + + if (is_gap) { + try filesystem.append(.{ .len = len, .id = .empty }); + } else { + try filesystem.append(.{ .len = len, .id = @enumFromInt(next_id) }); + + next_id += 1; + + std.debug.assert(next_id != @intFromEnum(FsId.empty)); + } + + is_gap = !is_gap; + } + + max_id = next_id - 1; + } + + // for (filesystem.items) |entry| { + // for (0..entry.len) |_| { + // switch (entry.id) { + // .empty => std.debug.print(".", .{}), + // else => std.debug.print("{}", .{@intFromEnum(entry.id)}), + // } + // } + // } + // std.debug.print("\n", .{}); + + { + // next ID to check; neccessary for checking all files once + // since file entries are sorted in increasing order, we can simply decrease this with each + // checked file + var next_id = max_id; + + // index of next filesystem entry to check + var idx: usize = filesystem.items.len - 1; + while (idx > 0) : (idx -= 1) { + const entry = filesystem.items[idx]; + + // we should never see and ID smaller than the one we're looking for + // if we do that means we would skip that file + std.debug.assert(entry.id == .empty or @intFromEnum(entry.id) >= next_id); + + if (@intFromEnum(entry.id) != next_id) { + continue; + } + + // found next entry to move + + // decrease next ID to find + next_id -= 1; + + const len = entry.len; + + for (0..idx) |jdx| { + const target_entry = filesystem.items[jdx]; + + // find the first entry with is empty and at least as large as our entry + if (target_entry.id != .empty or target_entry.len < len) { + continue; + } + + // found target entry + + if (target_entry.len == entry.len) { + // exact hit! no need to split entry, just swap IDs + + std.mem.swap(FsId, &filesystem.items[idx].id, &filesystem.items[jdx].id); + } else { + // empty space is larger than our entry; need to split + + // warning! this (potentially) invalidates all pointers into filesystem.items + // and we need to adjust indices (i.e. increase idx by one) since everything after + // jdx shift back by one index + + _ = try filesystem.addManyAt(jdx + 1, 1); + + idx += 1; + + // jdx + 1 becomes empty entry of len target_entry.len - entry.len + filesystem.items[jdx + 1].id = .empty; + filesystem.items[jdx + 1].len = target_entry.len - entry.len; + + // jdx becomes entry + filesystem.items[jdx].len = entry.len; + filesystem.items[jdx].id = entry.id; + + // idx becomes empty + filesystem.items[idx].id = .empty; + } + + break; + } + } + } + + // for (filesystem.items) |entry| { + // for (0..entry.len) |_| { + // switch (entry.id) { + // .empty => std.debug.print(".", .{}), + // else => std.debug.print("{}", .{@intFromEnum(entry.id)}), + // } + // } + // } + // std.debug.print("\n", .{}); + + var checksum: u64 = 0; + + { + var idx: usize = 0; + + for (filesystem.items) |entry| { + const len = entry.len; + + // skip over empty entry + if (entry.id == .empty) { + idx += len; + + continue; + } + + const id = @intFromEnum(entry.id); + + for (0..len) |_| { + checksum += id * idx; + + idx += 1; + } + } + } + + return checksum; +} + +test "part1 example" { + const alloc = std.testing.allocator; + + const example = "2333133121414131402"; + + var stream = std.io.fixedBufferStream(example); + + const result = try part1(alloc, stream.reader()); + + try std.testing.expectEqual(1928, result); +} + +test "part1 input" { + const alloc = std.testing.allocator; + + const file_reader = try utils.FileReader.init(alloc, filename); + defer file_reader.deinit(); + + const result = try part1(alloc, file_reader.reader()); + + try std.testing.expectEqual(6307275788409, result); +} + +test "part2 example" { + const alloc = std.testing.allocator; + + const example = "2333133121414131402"; + + var stream = std.io.fixedBufferStream(example); + + const result = try part2(alloc, stream.reader()); + + try std.testing.expectEqual(2858, result); +} + +test "part2 input" { + const alloc = std.testing.allocator; + + const file_reader = try utils.FileReader.init(alloc, filename); + defer file_reader.deinit(); + + const result = try part2(alloc, file_reader.reader()); + + try std.testing.expectEqual(6327174563252, result); +} diff --git a/inputs/day8.txt b/inputs/day8.txt new file mode 100644 index 0000000..d85f44e --- /dev/null +++ b/inputs/day8.txt @@ -0,0 +1,50 @@ +......................D....B...h.................. +..............................h................... +.............D...3.....X..................9....... +...........C........X....2.hB......v........b..... +....................................O............. +......u.....3.........p........................... +....u......................v....6................. +......................y..D.....Ov.2..............b +.....u..........X...........o........y............ +.........................y...B.f...........s...... +.7....................C.2.....Bsyp..........t...q. +.u.7...........X............................Oe..t. +...........V........3......6v.s........o....h....t +..E........L.................6..........o......9.. +........E......m.2.P.......O...9...8....b......... +..m..........3.......p..........M8................ +..1.....................K.p....................b.e +5...............L...........s.6..........S.M...... +....5..1.......E.........k.f.........M............ +.E..Y..V......l.......T...D.......9....Q.......... +..............................M................... +.....5....P................m...x..q......F......e. +................f...c......................x..F... +..V.C...........7.......a....o....8.........F..... +.......4....L.a..g..P.....8......Q....7d.......... +...1......4..a............k......t...d............ +..........V..........L....m........K....Q........S +..................1....k.....T.................... +..........l......a...............F................ +...........P...4.......l......x................... +.............c....g........T...................... +.....g............c...Q.......................S... +...............l..................A.d.T.U......... +..........................f...0.............d..... +..........G..................A............e.S...x. +.........Y.......q........g....K.................. +.....................q.H4...0.................j... +....................HA..............J............. +..Y..........................0...J.......j........ +.......................G.JA...................U... +.......5.......................................... +...........c..............G.........K............. +...............................G.................. +...........................0.j.................... +............................H.......k..........U.. +.........................H........................ +...................................Y....J......... +..................................j............... +.................................................. +.................................................. diff --git a/inputs/day9.txt b/inputs/day9.txt new file mode 100644 index 0000000..0f82a6a --- /dev/null +++ b/inputs/day9.txt @@ -0,0 +1 @@ +2378984580121520505930414446619015763552254236131228507744846522796247291626876463763556946912861452548524349536664248882715601886972771266057508255974582502497516580516230639351796322994373788969746852705458592550888399898574349029716597285229426155611176455883193664625020468455952536507361762145279392476941196162991574955145267828812260293292459177217150908841914969253174884880104377103132376869257225616384421272417089229952593327534384622532292462917552158794635925222175411448598283716549972035725859118482496293366879353578241876336442699442321945989352959995245253652755182189365693902473533822862236381585169972756459453638793660893996852296881874443313543194497787231370558934379689668959571116597696867555803036736054557968481159511248465866668332453616469849131270824079788473709572247855377282734480287958513420862644385727632314959556183993607284693216704113757013381329112153622933266121399843321439977644292476853682286244521224881625823919703469524759857954201157828918356461457778567832549688208190349061588210149791545118339165767317757574321977551825191870154819233535267610507814258088267860429874254610956540257839897838649945867695129940983973609750536378628983808190323652349413485143293095503016118739851419904748701827143357758817848551354065442482891214375748687288309687893759224660109298577232568585328545522819178084275725164438453279219414156944605941475028714087859633115098221023491268463253572545437796715175607380791043962730959321576980833533801257468487896934839857119445245067976935818024817198615470288615954638283664348293146511867892104066429585684386751592639240519662844433636050344246507860658686836078639723697541764871803847667674867680177850324815833955788698126721979726895586976310165617578214936984236127494122539431109791235026876712747383297034805148874015842837786567159828669458765044439920991171731787384796474151561147573691368798403588951655337248403197863368243240471648853277986935396995212189692584746615279942934321203910476880756795106544191158981614638811163610563746176255509412814595648347999296512985455988744537231739842420946319824443156380345568531063635064829425285879789194143017241676729126161614979734911883676364754890987140872222658498535089222998702355229831984283663433553695528972827553749232269113554593818696554473678790652693952367585412495593358953777245881279282513527853495316298477505751246491765047677688458715512617566973586192885652996810505966429036401824581981156235491673745750917983177597869891888271611997425328491651204791511343659823516515889012177024247359819623769584383887392396794773951255722384992853748961286511845981385637383554429064132254183522522547564162713031105490794255252289593841194785793693439315745498454934525822734324431857803356743840291533586870529649569336833533297372582484854578439273847366101016628743821197872527348497645385674476823452741195994913674156431081438156912546719565411839331142746782182742941926982086507111816562426954151518533931965557157098868647222734266535734497527681809339788342515367248077914446463966918417987812592917162530998812469227863760859693725474366744836758799984188866407430289978966430804416812652856954414656821963819223255065511847377996107644822668703590266959949676443758953327232239879952628273864819688222925799634241363923917261285878636945538698952917813672703654571973896155751020376193984813536455963387148541339224513891776052761632512170475152678858283695692338424827332733136592243514149634308072902984996966916197793745683942785825682772987518903034912687843031774818765089583332473428955625391422176665964066492372334841877316184841484431841236646837411260191279106614689195762680985185167376115935916720901080509315308954239642478122807030233167504635129332243064281130352114331152128848222280487057863147908278512683768736374430362483265369369166318860403754854540841758108936878776281125573151255440702345266146574373903734846157454956541714661541192235941598201128633120847365338595654478859923957447963070668037111168886737908538751010232650509532847814248175355196983119842925265865314762807455657328974847968896113145151636622164664956901197426916875973989478543467844981461977968699357266515156309484267063565657417249763597402081817770916278287557714717814622626092467289732320257557223829972277739497421178719492117383945041613143269838126618192690472094713025163867947817417114754292637294679886302820584734896658883329746164753244715826976327276714937553107933345684349171472069118621432176203924955122127510122940587451438188626832293928902034719851926633318712337456348682715071897680587311239781111867581253996069942863678366308925194639473650704948911893598426533461325882192359712345632953185626622396212131462965285596157321476827435486879053351951292363378514419126903376974999922444529517507118698981942577752524274513712586785028753499193470145475428756174126379019387175719854363625492739284855685922615892713132441235978566252040538535304477137335493729495967321851194256952949409382705145677199825175549571204889424059219986488135244443963658668688963515603154336874449020705640147759138531362438381274859356731928215462726057295542164144927824453683378151185815575974904558718120514748915681857148585756761760125451261536918295476165405367482739473040529351231535327221585227704478584842301993939340776741981636107610225382653384839513166999168360809563769716952740439636682542792628326933388760199619909323537379824067343089401785271676351418819531372445671751584544872266495795767895121435422665439290927470281946113564671289565468648472711347956499381115386431787082914124619537687331906099643424784918434425418511802945288273915781708873196799313920434247814561353390164027337220661233424498223672396942673094877578409458441055443368735076309224279196584334557676408479115326201361615625519033344654769448636289952754653299516896777262429076332956703838781455141330689753342884361836118830509347697696701440402871944229244114952293308980436313567274374442959358132645683839656769148183749586724142291287686013752237456287993392834088722164789361196622908692231273322685239134237068961725573251411691727468378632859941897549713787913487167534434677287070742627274613978092734676332666148570255315168728673659548969573917386837409317732637823956443966118251132719725232369372937994752173476898749959294152169890611151283286827499495817415829757495904667532984795649829642177590674210465886855336244130568161875357559330792522139547961192717282542719229567752315882386526968384026943444783573546555449814185314609178462556314384733956363812859062708464465541563244726927845890842049141399423430892798176919151982664642666058945234688528617390653124874440911626175338932299972692453271771326106780123668848658864713266252766945965596304410793957474530771546153746173159446963739346139841103834659721667815851417375659982678278914414369669345414874407389449249213958867872262243464354834032831080855633595161198864586937438643441379338434392465873026673340692681349838692166752486805610389842435427406067363157826045468280103015402729805391151182588957594959546128295794757768421126425415749428721167636473467068871270801239199347402982886078124725332215471328806997653876487852267232986124503859479825322927698236319646965926629326925858136594213216808056644623208171915359694492738322476670714340123624936584965717977020726864577876884537251245899047524647563613186028808697274064898278368259108567972178193940694188461968733185934423255491877491699891856352117998798527346770753342222839491332733557412278569091287995436365437249719519339262376396511069342592759325477238385895652050716938678475617757768031518276408070717974252875683541278664486760226937128634771176251239226431454871776832381524246651562549124061302854852088748199812449262823847677871171296142355162404740241220361575677065163089854629529464128269852320202012441479736618835199132748375561488172576118787260772553556373112737657571194913554692493993304262751549501333346413809146792196982286353313312036787458809882288227213669197592974499123146176673806469605275334895311577785988916197919925978774182923554821481417186970222817617351459680641857547242461699318647867421913597362296479431743837729235458814888193849683701220131551741889189967448393206051868917477085724695103382739062879155581684796961397611922094944351498312355232261833266040187573964382519761126995953552333670703470475137579956132815385031512698618986234725139882101110449053771219276723863439243197769275882942632722257680257015857757185199581348789995244010364090321292613867271050636053232383334167404266965155789587566539286146859547708569348876983418453992611028411662287076563219446739684719995951984679221346398313295062715414415940148557125977519439548252746256638881304218198651737123829729323140377051359329616224162097122915428161687971515541387533946985777845689728968861358181612267475524772650955875691932304570652433792955499280945334913117171548349434361418408474969341381087928727308789992455518958259416996368862074123823501693114692474413372895978361714066446365431311315853718611149739148436268764405094839671672783328983655737835615667776981129992029383272813867251546878596782350649117995061145541361710554447682514175333864934341479268970527090841167987234891250352921183638839748375899224428763314202130611788141389744625206996904221371621916023281618559324317665972699549696517618125819463899689499259647112847652590935950777630546068947952557423833362275458777349451056115898133858972217467642645870546546813548789842426147296172906419115790208951622675833532243652367045494035622172991145565013191571411377871061754495838087246597556647583413146932194532525126566718408953346352757535992841273739266134495035422238115785673879164834854455378335353210833844537687753399176767171460881324526747908968304164871623194678653465802437882684782123694312714636813517946340737699949962899541217692209561703458675431276669725018584549495865293765483092462438793094388187136321534235408782945055378653725714661275949073137190658611776294277296955288402046861322218583972646228982338331415369277672797470554298939371299889749078726792673881856135914816425838629684514254901474594360623881233768216498687745472584161012211968389224613151521679322688144752541729138138557975745786245042377898952951543739258877529527984111769213956149378177306917362194417583839431161796845948253049205379122072552653896534389028617064162913328454452880629818137739254134473897701116145175454898177832324684479325879553636265237940994651567353936670485524337843152529635624236893677334249887809377282520185425712842721923249194612486311342228916323962679539558783951230964543944185859938184548444572202966517029428158744921986513141764339924465145764473391671983147268835146173768286679798925237621454159227921936665116847587843097603097803535435485869360209370487843619670753739415656305215858134718940875920223070533440839555784296523391388119124046486117434118884537391428195862507226425427901338866024737563907541245378109080574929174766862247846269294123568036617950788351773453982566124761211745991028402580892666482746122088744422848656926371508167563927982438597416454378118428233266765133471393768039537272492213276329329493112117568310674037281277264847476799794197928650166155994097402190433596778520996759404869914640425991393698869925473235336193898352219622768638514065105142598726798932879088995361692226357354807841758059575795203859357874136423759230921023616254286026236995208762118345176925752388527611118686855161169122356736678456453774162689754863596455781563617134517625149760296964124658586215515419258133107038131564423597878792417279449118428087956477443533812574716186661576108797228335352089545687378121409756749086375877433644727076875229963880403296473077969574963942546567648036496314242428181164647241493485912626912972992268801722413656834119595353462213796133923372958846172691746762394616891428563734338542927224197074917528566891626944913823261661518144605853324965691395602093254326774860374041132896552258412839833449767476661383247196493183143667218692182821712499293252853221195763745786999192526110514435285084981243143750191895137088675759258352356123206856776152411611906652527477486094321916718811712860409099702340362183485598369359355463416551259252317570649792645495949777284880448368623086391213396676448027328232614248124259112111455462293697518781454557625018499913157263309520969611231743701436271069498641747320188350249229978149325791501144401641457450321541671420882451974621272689298041317199416374719666755918137160947862324226315717153325427959436035738945384883436082363856732774356110432217144542998221251830388614515076787575893592489258109292524287744962145249936339132594511092265090912046112349174554984377564990168062574790562059637476613433307259473264816157459561256472373328808735148143349434244857854933278521157097425211831327377838742629276584539595728777475272237222518056723314262719171949308722147875808890943413414144954157417882639431207090775648378891967961459746606599185963634586594644425126165367926946605632866318125321566031884240356173519311367731953285385032542571604281661324588357177131581353447716143875965690253142913170242718187493266432118891546048273013717150293184104561588788405247873640584087583951587489192478924840955953232531654893549250928696711633532740739684281731616640281182556617833381478852406028223736361261994655785344272177448186531740406343164290226029843538238084207071122483442940721574234234915479925618897080537188718810852732924396365027265021611758459240857213326380535979424669308272533174235546673720118365479075932291989154579222734328867566868626313870577971615593682647737420287636405120754744406113699529105674682593289125841892256631946339202368808115106997866350286482903779308996337641734290205539496247502146323414783499943357678229786211364857458961783962142755538988174556281192337722358656825357488688399823954692641637898170123415625996238430491664913259416466301072368261974864222462489734157065132572207191146312688151177617138127805866477310204154951459787481698995443767471468744257696561988923565179834266877440977362443811745620829314903572613842598222691120196367661656562939999513894218864512776561832538493161711466176476778736511166141518614183229677924567684014142918177013186489142620688186223351893151944070983436853214862369593660556141668076642069987528278978151912203356449771109971235696835361166914623238363230115314168774788798633638474116665917672633988760157190803025571014861755264791105917959187392843121399719282299135286286531218633719361083729275997876102936359719861167648438164680141329121493758322958794638819652011988758806953229720857150358791734515863144193415185024899065853354922012194311356972372849168482707154197212393313569144121954502353838231102151469897668445429935528447314834237261823377935225622496496832684614559879986292233672454066763770835286378581937084522569722855384556912754556223605248777198982493986370914547774162626673432632144063786733707128407757395334242541655272391769754156894279737251673458264255255164483250517478273023261923371489891635758493538732693155547293682042259482523347703784485632726744747122338754878140433514858113944412993562361833782539755584496673667463161177642874956569242150917595977026843721289396424187369123295873641282141470114826705541463579237625453818613578504065862714764548129718653247121150117095907486369652454741867653555480843213563291857969883558928378863233808698944230335088424044581024547670792769215252532351352760696457317976928265962486548283794241659836397815179072535281735695153286529074922587652487719941497758122094675234279039852166852741782063374998455436527919928648676868353395265616509765939739952362213098685359193486477060451621652970276618148490947234796770683187621133131218359768837962911790904427222032695143432317371679451434913798137054989647905684563124993562648435555216123186916878957164277210349325511575265513851515401972914592348232416696793673189522906086835892595459361790511212489190703462401961105720133231498611642243286579117122588229833541989098138224577345824932276781908546108678222684379749958845845945998271573476557638585962667037491483668419705318614947386925692694729811177289538390891081516459606859957616195820408288593857131356312056882156276622982798204066579218882187656718687064964650106388509212244447711526385399973728803536556773829088411928165314447764514015997065477567158784437833957859845573938591795545959656265540126671876280237223532396507295866484459238493452733259621016189678855279389281784654545768298165675734935929596788207561319456524720181444941719315565201164845126425431248711519959626718929841634024101887242520301615177480252843657490521915221419347147439296359043482148692953523985936121746640207962217580844674583419114320109382137211965713745749117236529475698235715575339852985485637191927997742558227598379742799924528052794475499546147846694786453114593485625263964796396857894039542986707551393576805436491368125170584214385842876736184950701845807552293982543038801381447120227439205592896980601093944264335856146430832822158731995420496722211721677325196331727391678280528950447085276273801654343441632619767232668161433669526574802191308173666561311481501651168185831758462130407389656990596412635775276699961415379428848951365266797098318491184873581550836747415064722064557396939270989861811367589997184645567713421924297381558487402182598329103168737347847118294986642754179886246418815255366069969614443364318135501256387094724439251141741746576494283131877647798278769281268140525353619423933289249425436921746173918279511587223053503665387328812911876743462949595369365710373243348716681089836025773654815277886662239775807680287537417193788712738078695395283337953428331169801341834349426116207292186665416363282283523047455668599043461474534265963583185867161192985973415353961330172946127390774274688344463430505266723721411549898063183376297493391991479899709663896640277692965863233341458323928928357250234719898573342661727242242557883757458459493146628310741656612312988622127797711993283276772943824899115754651752847292795394388234616233472655119542711423217973169078949626891017594292143067811480597090717735813951904296237542552869922520731316909134592751272315498868796718409410179048516565285119433692391948811716451432462369436560294293682884973790579422862214478548138288579745698663678750568199819059319612335280199921316119513066722341834827589810631450616586424240618227507735388176579588565070827180442332898684775675352183809863653555275884737581567047313620744483213857732038215331833868316333712245965645273791992095759928906295769174247592946262752838149878848320901337183633327032118184423436682915113640617445882330201694633371109974221874123411917651968358118872131525866881578546495422545120866643296538386937914316262082365561665017628212744728241617746015945023679941385612952937368728941553885172474482298113539845375569845269284058265081214123216843914895819597507544824574682435682121585026692023275834965477622420394224701771683949656217497647357287771942751715873814155488989674906692782350606366598223456652563841852745224827772854757455763124198013688548736059996658135912124546959463145216771931365311751434654768941644688758456153716883819454247832799437314899841274498844152569894072137565758612973061146815749990252484371811593321948027926538203221237627893820318578762242445756773344727728624644899115703649797825949053934252565932302748968239498520968485376024972933375627931013881446466745546080933115804948263590605649169019589322376426574669165841902113221523748230259445688267207427669655555856192450908581591860485298738034804232467840172175328534647160992633775717639457907035847714833049829017771567227955904664824576978590161925456951657551578523539438359698581948867669696324575723603720154657884585766322604327668531402640868689749889684036735566117740572597833396662041898532516692477339896849888291484877342991261341943115779952642648741173575710822167305324425859415921428247134462182027541730608 diff --git a/lib/utils.zig b/lib/utils.zig index b0c33ed..ed80b7b 100644 --- a/lib/utils.zig +++ b/lib/utils.zig @@ -100,6 +100,38 @@ pub fn numberParserWithDelimiter(comptime T: type, input: []const u8, delimiter: return NumberParser(T){ .token_it = std.mem.tokenizeScalar(u8, input, delimiter) }; } +pub fn allocGrid(comptime T: type, alloc: std.mem.Allocator, n: usize, m: usize) ![][]T { + const grid = try alloc.alloc([]T, n); + + for (grid) |*line| { + line.* = try alloc.alloc(T, m); + } + + return grid; +} + +pub fn allocGridInit(comptime T: type, alloc: std.mem.Allocator, n: usize, m: usize, init: T) ![][]T { + const grid = try alloc.alloc([]T, n); + + for (grid) |*line| { + line.* = try alloc.alloc(T, m); + + for (line.*) |*x| { + x.* = init; + } + } + + return grid; +} + +pub fn deinitGrid(comptime T: type, alloc: std.mem.Allocator, grid: [][]T) void { + for (grid) |line| { + alloc.free(line); + } + + alloc.free(grid); +} + pub fn rangeComptime(comptime n: usize) [n]usize { var array: [n]usize = undefined;