const std = @import("std"); const Box = struct { x: i64, y: i64, z: i64, circuit: usize }; const Pair = struct { p1: usize, p2: usize, dist: i64 }; const CONNECTIONS = 100; pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); var stdin_buffer: [1024]u8 = undefined; var stdin_reader = std.fs.File.stdin().reader(&stdin_buffer); const stdin = &stdin_reader.interface; const allocator = gpa.allocator(); var boxes = try std.ArrayList(Box).initCapacity(allocator, 1); defer boxes.deinit(allocator); var counter: usize = 0; while (try stdin.takeDelimiter('\n')) |line| { const line_trimmed = std.mem.trim(u8, line, "\n"); var it = std.mem.splitScalar(u8, line_trimmed, ','); const x = try std.fmt.parseInt(i64, it.next().?, 10); const y = try std.fmt.parseInt(i64, it.next().?, 10); const z = try std.fmt.parseInt(i64, it.next().?, 10); try boxes.append(allocator, Box{ .x = x, .y = y, .z = z, .circuit = counter }); counter += 1; } var pairs = try std.ArrayList(Pair).initCapacity(allocator, 1); defer pairs.deinit(allocator); for (boxes.items, 0..) |box1, i| { for (boxes.items[i + 1 ..], i + 1..) |box2, j| { const d = distance(box1, box2); try pairs.append(allocator, Pair{ .p1 = i, .p2 = j, .dist = d }); } } std.mem.sort(Pair, pairs.items, {}, pair_sort); for (0..CONNECTIONS) |i| { const p1 = pairs.items[i].p1; const p2 = pairs.items[i].p2; const c1 = boxes.items[p1].circuit; const c2 = boxes.items[p2].circuit; // Both if (c1 == c2) { continue; } // Different circuits // Switch every box from circuit c2 to c1 for (boxes.items) |*box| { if (box.circuit == c2) { box.circuit = c1; } } // Check if we are a single circuit const first = boxes.items[0].circuit; var found = false; for (boxes.items) |box| { if (box.circuit != first) { found = true; break; } } if (!found) { std.debug.print("{d}\n", .{ boxes.items[p1].x * boxes.items[p2].x }); break; } } var circuits = try std.ArrayList(usize).initCapacity(allocator, 1); defer circuits.deinit(allocator); for (0..boxes.items.len) |_| { try circuits.append(allocator, 0); } for (boxes.items) |box| { circuits.items[box.circuit] += 1; } std.mem.sort(usize, circuits.items, {}, comptime std.sort.desc(usize)); var task1: usize = 1; for (0..3) |i| { task1 *= circuits.items[i]; } // for (0..boxes.items.len) |i| { // for (0..boxes.items.len) |j| { // std.debug.print("{d}", .{adjacency.items[i].items[j]}); // } // std.debug.print("\n", .{}); // } std.debug.print("{d}\n", .{task1}); } fn pair_sort(_: void, p1: Pair, p2: Pair) bool { return p1.dist < p2.dist; } fn distance(p1: Box, p2: Box) i64 { return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) + (p1.z - p2.z) * (p1.z - p2.z); }