Problem statement
Hey there. I’m doing advent of code day 6 and I want to store checks for a coordinate (x,y) and I want x to be able to map to many y’s.
I immediately wanted to use something which allows for duplicate y values.
I understand I can go off and craft my own data structures, but I’d rather not do that.
Attempting to nest autohashmap
I know this is possible, but I get memory access errors when I try it. There is some trick I’m unaware of.
AutoHashMap
const std = @import("std");
const input = @embedFile("input.txt");
const Coord = struct {
x: usize,
y: usize,
};
const DIRECTION = enum(u3) {
UP,
RIGHT,
DOWN,
LEFT,
};
fn check_for_obstical(data: std.ArrayList([]const u8), location: Coord, direction: DIRECTION) bool {
switch (direction) {
DIRECTION.UP => {
return data.items[location.y - 1][location.x] != '#';
},
DIRECTION.RIGHT => {
return data.items[location.y][location.x + 1] != '#';
},
DIRECTION.DOWN => {
return data.items[location.y + 1][location.x] != '#';
},
DIRECTION.LEFT => {
return data.items[location.y][location.x - 1] != '#';
},
}
}
fn spin(data: std.ArrayList([]const u8), location: Coord, direction: DIRECTION) DIRECTION {
const begin = direction;
var new_dir = blk: {
var nd = begin;
switch (begin) {
DIRECTION.UP => {
nd = DIRECTION.RIGHT;
},
DIRECTION.RIGHT => {
nd = DIRECTION.DOWN;
},
DIRECTION.DOWN => {
nd = DIRECTION.LEFT;
},
DIRECTION.LEFT => {
nd = DIRECTION.UP;
},
}
break :blk nd;
};
while (begin != new_dir) {
if (check_for_obstical(data, location, new_dir)) {
return new_dir;
}
new_dir = blk: {
var nd = begin;
switch (begin) {
DIRECTION.UP => {
nd = DIRECTION.RIGHT;
},
DIRECTION.RIGHT => {
nd = DIRECTION.DOWN;
},
DIRECTION.DOWN => {
nd = DIRECTION.LEFT;
},
DIRECTION.LEFT => {
nd = DIRECTION.UP;
},
}
break :blk nd;
};
}
unreachable;
}
fn part_1(in: []const u8) !usize {
var solution: usize = undefined;
solution = 0;
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
var data = std.ArrayList([]const u8).init(allocator);
var guard_location: Coord = undefined;
var it = std.mem.tokenizeScalar(u8, in, '\n');
while (it.next()) |line| {
try data.append(line);
// look for the starting point
const guard = std.mem.indexOf(u8, line, "^");
if (guard) |location| {
guard_location.x = location;
guard_location.y = data.items.len - 1;
}
}
var visited = std.AutoHashMap(usize, std.AutoHashMap(usize, void)).init(allocator);
var inside_data = true;
var direction = DIRECTION.UP;
while (inside_data) {
// mark current location as visited
const gop_result = try visited.getOrPut(guard_location.x);
try gop_result.value_ptr.*.put(guard_location.y, {});
switch (direction) {
DIRECTION.UP => {
// check if can proceed upwards
inside_data = guard_location.y - 1 > 0;
if (!inside_data) break;
const can_proceed = inside_data and check_for_obstical(data, guard_location, direction);
if (can_proceed) {
guard_location.y = guard_location.y - 1;
} else {
// attempt to turn right
direction = spin(data, guard_location, direction);
}
},
DIRECTION.DOWN => {},
DIRECTION.LEFT => {},
DIRECTION.RIGHT => {},
}
}
std.debug.print("start: {}\n", .{guard_location});
std.debug.print("solution: {d}\n", .{solution});
return solution;
}
pub fn main() !void {
_ = try part_1(input);
}
test "test" {
const test_in =
\\....#.....
\\.........#
\\..........
\\..#.......
\\.......#..
\\..........
\\.#..^.....
\\........#.
\\#.........
\\......#...
;
const test_1 = try part_1(test_in);
try std.testing.expect(test_1 == 41);
}
Errors
[jud@archlinux day_6]$ zig run src/main.zig
thread 13578 panic: incorrect alignment
/home/jud/zig_versions/0.13.0/files/lib/std/hash_map.zig:985:44: 0x10a58db in header (main)
return @ptrCast(@as([*]Header, @ptrCast(@alignCast(self.metadata.?))) - 1);
^
/home/jud/zig_versions/0.13.0/files/lib/std/hash_map.zig:999:31: 0x108be57 in capacity (main)
return self.header().capacity;
^
/home/jud/zig_versions/0.13.0/files/lib/std/hash_map.zig:1371:39: 0x108bfcb in getOrPutAssumeCapacityAdapted__anon_8971 (main)
const mask = self.capacity() - 1;
^
/home/jud/zig_versions/0.13.0/files/lib/std/hash_map.zig:1345:54: 0x107ed4d in getOrPutContextAdapted__anon_8793 (main)
return self.getOrPutAssumeCapacityAdapted(key, key_ctx);
^
/home/jud/zig_versions/0.13.0/files/lib/std/hash_map.zig:1318:56: 0x106f5d5 in getOrPutContext (main)
const gop = try self.getOrPutContextAdapted(allocator, key, ctx, ctx);
^
/home/jud/zig_versions/0.13.0/files/lib/std/hash_map.zig:1244:52: 0x10402f0 in putContext (main)
const result = try self.getOrPutContext(allocator, key, ctx);
^
/home/jud/zig_versions/0.13.0/files/lib/std/hash_map.zig:552:45: 0x103af0a in put (main)
return self.unmanaged.putContext(self.allocator, key, value, self.ctx);
^
/home/jud/code/AoC24/day_6/src/main.zig:110:39: 0x103a655 in part_1 (main)
try gop_result.value_ptr.*.put(guard_location.y, {});
^
/home/jud/code/AoC24/day_6/src/main.zig:136:19: 0x103b831 in main (main)
_ = try part_1(input);
^
/home/jud/zig_versions/0.13.0/files/lib/std/start.zig:524:37: 0x103a0a5 in posixCallMainAndExit (main)
const result = root.main() catch |err| {
^
/home/jud/zig_versions/0.13.0/files/lib/std/start.zig:266:5: 0x1039bc1 in _start (main)
asm volatile (switch (native_arch) {
^
???:?:?: 0x0 in ??? (???)
Aborted (core dumped)