Day 6.1
This commit is contained in:
14
06/build.zig
Normal file
14
06/build.zig
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
const Builder = @import("std").build.Builder;
|
||||||
|
|
||||||
|
pub fn build(b: *Builder) void {
|
||||||
|
const mode = b.standardReleaseOptions();
|
||||||
|
const exe = b.addExecutable("06", "src/main.zig");
|
||||||
|
exe.setBuildMode(mode);
|
||||||
|
exe.install();
|
||||||
|
|
||||||
|
const run_cmd = exe.run();
|
||||||
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
run_step.dependOn(&run_cmd.step);
|
||||||
|
}
|
102
06/src/main.zig
Normal file
102
06/src/main.zig
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const Link = struct {
|
||||||
|
a: [3]u8 = [3]u8{ 0, 0, 0 },
|
||||||
|
b: [3]u8 = [3]u8{ 0, 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
const Node = struct {
|
||||||
|
name: [3]u8 = [3]u8{ 0, 0, 0 },
|
||||||
|
depth: u32 = 0,
|
||||||
|
parent: ?*Node,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Links = std.ArrayList(Link);
|
||||||
|
const Nodes = std.StringHashMap(*Node);
|
||||||
|
|
||||||
|
fn parse(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) !Links {
|
||||||
|
var list: Links = Links.init(alloc);
|
||||||
|
var buf: [8]u8 = undefined;
|
||||||
|
var i: u32 = 0;
|
||||||
|
|
||||||
|
while (try stream.readUntilDelimiterOrEof(&buf, '\n')) |line| {
|
||||||
|
std.debug.assert(line.len == 7 and line[3] == ')');
|
||||||
|
std.debug.warn("{}\n", line);
|
||||||
|
|
||||||
|
var out: Link = Link{};
|
||||||
|
std.mem.copy(u8, &out.a, line[0..3]);
|
||||||
|
std.mem.copy(u8, &out.b, line[4..7]);
|
||||||
|
|
||||||
|
try list.append(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getOrCreateNode(alloc: *std.mem.Allocator, nodes: var, name: [3]u8) !*Node {
|
||||||
|
if (nodes.get(name)) |kv| {
|
||||||
|
return kv.value;
|
||||||
|
} else {
|
||||||
|
var node: *Node = try alloc.create(Node);
|
||||||
|
node.parent = null;
|
||||||
|
node.depth = 0;
|
||||||
|
|
||||||
|
std.mem.copy(u8, &node.name, name);
|
||||||
|
|
||||||
|
var kv = try nodes.put(name, node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() anyerror!void {
|
||||||
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
|
||||||
|
const alloc = &arena.allocator;
|
||||||
|
const file = std.io.getStdIn();
|
||||||
|
const stream = &file.inStream().stream;
|
||||||
|
|
||||||
|
var links = try parse(alloc, stream);
|
||||||
|
|
||||||
|
std.debug.warn("Part 1: {} links\n", links.len);
|
||||||
|
|
||||||
|
// name -> node
|
||||||
|
var nodes = Nodes.init(alloc);
|
||||||
|
|
||||||
|
// The input isn't ordered, so we need to pass over it several times
|
||||||
|
|
||||||
|
// Pass 1: create all nodes
|
||||||
|
for (links.toSlice()) |link| {
|
||||||
|
var a = try getOrCreateNode(alloc, &nodes, link.a);
|
||||||
|
var b = try getOrCreateNode(alloc, &nodes, link.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass 2: link all nodes to their parents
|
||||||
|
for (links.toSlice()) |link| {
|
||||||
|
var a = try getOrCreateNode(alloc, &nodes, link.a);
|
||||||
|
var b = try getOrCreateNode(alloc, &nodes, link.b);
|
||||||
|
|
||||||
|
std.debug.warn("\t{} ) {}\n", a.name, b.name);
|
||||||
|
|
||||||
|
std.debug.assert(b.parent == null);
|
||||||
|
b.parent = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass 3: The tree is fully constructed, so we can count parents
|
||||||
|
var count: u32 = 0;
|
||||||
|
var iter = nodes.iterator();
|
||||||
|
while (iter.next()) |kv| {
|
||||||
|
var node = kv.value;
|
||||||
|
|
||||||
|
// Count number of orbits
|
||||||
|
var n: *Node = node;
|
||||||
|
while (n.parent) |p| {
|
||||||
|
node.depth += 1;
|
||||||
|
n = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
count += node.depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.warn("Part 1: {}\n", count);
|
||||||
|
}
|
Reference in New Issue
Block a user