Finish day 9
This commit is contained in:
		
							parent
							
								
									b38bd5f0ac
								
							
						
					
					
						commit
						ebbc0931b7
					
				|  | @ -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); | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -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); | ||||
| } | ||||
		Loading…
	
		Reference in New Issue