Skip to content

Commit de6b7b6

Browse files
feat(day-10): completed day 10 with zig
1 parent 8741763 commit de6b7b6

File tree

5 files changed

+715
-0
lines changed

5 files changed

+715
-0
lines changed

day-10/.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
solution
2+
solution.o
3+
solution2
4+
solution2.o
5+
sample*
6+
problem*

day-10/Makefile

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
solution: solution.zig
3+
zig build-exe solution.zig
4+
5+
run: solution
6+
./solution
7+
8+
9+
solution2: solution2.zig
10+
zig build-exe solution2.zig
11+
12+
run2: solution2
13+
./solution2

day-10/solution.zig

+252
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
const std = @import("std");
2+
3+
const Table = struct {
4+
array: [][]u8,
5+
length: usize,
6+
ilength: usize,
7+
distance: [][]isize,
8+
9+
pub fn get_char(self: *Table, point: *Point) ?u8 {
10+
if ((point.x < self.ilength and point.x >= 0) and (point.y < self.length and point.y >= 0)) {
11+
return self.array[point.y][point.x];
12+
} else {
13+
return null;
14+
}
15+
}
16+
17+
pub fn update_distance(self: *Table, pt: *Point, value: isize) bool {
18+
if (self.distance[pt.y][pt.x] == -1 or self.distance[pt.y][pt.x] > value) {
19+
self.distance[pt.y][pt.x] = value;
20+
return true;
21+
}
22+
return false;
23+
}
24+
25+
pub fn find_start(self: *Table) ?Point {
26+
for (self.array, 0..) |inner, i| {
27+
for (inner, 0..) |el, j| {
28+
if (el == 'S') {
29+
return Point{ .x = j, .y = i, .tableRef = self };
30+
}
31+
}
32+
}
33+
return null;
34+
}
35+
36+
pub fn validate(self: *Table, point: *Point) bool {
37+
return ((point.x < self.ilength and point.x >= 0) and (point.y < self.length and point.y >= 0));
38+
}
39+
40+
pub fn startLookup(self: *Table, point: *Point, alloc: std.mem.Allocator) ![]Point {
41+
var output = try alloc.alloc(Point, 0);
42+
if (point.top()) |inner| {
43+
var i = inner;
44+
if (point.contains(try self.get_next(&i, alloc))) {
45+
output = try makeArray(Point, alloc, output, point.top());
46+
}
47+
}
48+
49+
if (point.left()) |inner| {
50+
var i = inner;
51+
if (point.contains(try self.get_next(&i, alloc))) {
52+
output = try makeArray(Point, alloc, output, point.left());
53+
}
54+
}
55+
56+
if (point.right()) |inner| {
57+
var i = inner;
58+
if (point.contains(try self.get_next(&i, alloc))) {
59+
output = try makeArray(Point, alloc, output, point.right());
60+
}
61+
}
62+
63+
if (point.bottom()) |inner| {
64+
var i = inner;
65+
if (point.contains(try self.get_next(&i, alloc))) {
66+
output = try makeArray(Point, alloc, output, point.bottom());
67+
}
68+
}
69+
70+
return output;
71+
}
72+
73+
pub fn get_next(self: *Table, point: *Point, alloc: std.mem.Allocator) ![]Point {
74+
var empty_start = try alloc.alloc(Point, 0);
75+
if (self.get_char(point)) |inner| {
76+
// std.debug.print("{c}\n", .{inner});
77+
return switch (inner) {
78+
'|' => try makeArray(Point, alloc, try makeArray(Point, alloc, empty_start, point.bottom()), point.top()),
79+
'-' => try makeArray(Point, alloc, try makeArray(Point, alloc, empty_start, point.left()), point.right()),
80+
'L' => try makeArray(Point, alloc, try makeArray(Point, alloc, empty_start, point.top()), point.right()),
81+
'J' => try makeArray(Point, alloc, try makeArray(Point, alloc, empty_start, point.top()), point.left()),
82+
'7' => try makeArray(Point, alloc, try makeArray(Point, alloc, empty_start, point.bottom()), point.left()),
83+
'F' => try makeArray(Point, alloc, try makeArray(Point, alloc, empty_start, point.bottom()), point.right()),
84+
// 'S' => try self.startLookup(point, alloc),
85+
else => empty_start,
86+
};
87+
} else {
88+
return empty_start;
89+
}
90+
}
91+
};
92+
93+
const Point = struct {
94+
tableRef: *Table,
95+
x: usize,
96+
y: usize,
97+
98+
pub fn new(x: usize, y: usize, table: *Table) Point {
99+
return Point{ .x = x, .y = y, .tableRef = table };
100+
}
101+
102+
pub fn eq(self: Point, other: *Point) bool {
103+
return (self.x == other.x and self.y == other.y);
104+
}
105+
pub fn contains(self: *Point, array: []Point) bool {
106+
for (array) |el| {
107+
if (el.eq(self)) {
108+
return true;
109+
}
110+
}
111+
return false;
112+
}
113+
114+
pub fn top(self: *Point) ?Point {
115+
if (self.y == 0) return null;
116+
var newPoint = Point.new(self.x, self.y - 1, self.tableRef);
117+
return if (self.tableRef.validate(&newPoint)) newPoint else null;
118+
}
119+
120+
pub fn bottom(self: *Point) ?Point {
121+
if (self.y == self.tableRef.length - 1) return null;
122+
var newPoint = Point.new(self.x, self.y + 1, self.tableRef);
123+
return if (self.tableRef.validate(&newPoint)) newPoint else null;
124+
}
125+
126+
pub fn left(self: *Point) ?Point {
127+
if (self.x == 0) return null;
128+
var newPoint = Point.new(self.x - 1, self.y, self.tableRef);
129+
return if (self.tableRef.validate(&newPoint)) newPoint else null;
130+
}
131+
132+
pub fn right(self: *Point) ?Point {
133+
if (self.x == self.tableRef.ilength - 1) return null;
134+
var newPoint = Point.new(self.x + 1, self.y, self.tableRef);
135+
return if (self.tableRef.validate(&newPoint)) newPoint else null;
136+
}
137+
// }
138+
};
139+
140+
fn makeArray(comptime T: type, alloc: std.mem.Allocator, array: []T, value: ?T) ![]T {
141+
if (value) |inner| {
142+
// Get the length of the existing array
143+
const length = array.len;
144+
145+
// Allocate memory for a new array with one additional element
146+
const newLength = length + 1;
147+
var output = try alloc.alloc(T, newLength);
148+
std.mem.copy(T, output, array);
149+
150+
// Copy the existing elements to the new array
151+
output[newLength - 1] = inner;
152+
153+
// Update the original array
154+
return output;
155+
}
156+
157+
return array;
158+
}
159+
160+
pub fn printArray(points: []Point) void {
161+
std.debug.print("[", .{});
162+
for (points) |point| {
163+
std.debug.print("({any},{any}),", .{ point.x, point.y });
164+
}
165+
std.debug.print("]\n", .{});
166+
}
167+
168+
pub fn printArray2(points: [][]isize) void {
169+
for (points) |point| {
170+
std.debug.print("{any}\n", .{point});
171+
}
172+
}
173+
174+
pub fn solve_my_problem_plij(point: Point, big_array: []Point, cursor: usize, alloc: std.mem.Allocator) !void {
175+
var pt = point;
176+
var cus = cursor;
177+
var possibilities: []Point = undefined;
178+
if (point.tableRef.get_char(&pt) == 'S') {
179+
possibilities = try point.tableRef.startLookup(&pt, alloc);
180+
} else {
181+
possibilities = try point.tableRef.get_next(&pt, alloc);
182+
}
183+
// printArray(possibilities);
184+
for (possibilities) |pos| {
185+
var ipos = pos;
186+
if (ipos.tableRef.update_distance(&ipos, @intCast(cus))) {
187+
// std.debug.print("{c} -> {c}\n", .{ point.tableRef.get_char(&pt).?, point.tableRef.get_char(&ipos).? });
188+
big_array[cus] = pos;
189+
cus += 1;
190+
try solve_my_problem_plij(pos, big_array, cursor + 1, alloc);
191+
cus -= 1;
192+
}
193+
}
194+
}
195+
196+
pub fn max(diss: [][]isize) isize {
197+
var inner_max: isize = -1;
198+
for (diss) |ell| {
199+
for (ell) |el| {
200+
if (el > inner_max) {
201+
inner_max = el;
202+
}
203+
}
204+
}
205+
return inner_max;
206+
}
207+
208+
pub fn main() !void {
209+
const stdout = std.io.getStdOut().writer();
210+
const in = std.io.getStdIn();
211+
var buf = std.io.bufferedReader(in.reader());
212+
var r = buf.reader();
213+
214+
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
215+
defer arena.deinit();
216+
217+
const allocator = arena.allocator();
218+
219+
var msg_buf: [10000]u8 = undefined;
220+
221+
var output = try allocator.alloc([]u8, 4096);
222+
var counter: usize = 0;
223+
224+
while (try r.readUntilDelimiterOrEof(&msg_buf, '\n')) |line| {
225+
var inner_array = try allocator.alloc(u8, line.len);
226+
std.mem.copy(u8, inner_array, line);
227+
228+
output[counter] = inner_array;
229+
counter += 1;
230+
}
231+
output = output[0..counter];
232+
233+
var distance = try allocator.alloc([]isize, output.len);
234+
for (distance, 0..) |_, idx| {
235+
distance[idx] = try allocator.alloc(isize, output[0].len);
236+
for (distance[idx], 0..) |_, jdx| {
237+
distance[idx][jdx] = -1;
238+
}
239+
}
240+
var table = Table{ .array = output, .length = output.len, .ilength = output[0].len, .distance = distance };
241+
var start = table.find_start().?;
242+
var point_array = try allocator.alloc(Point, start.tableRef.length * start.tableRef.ilength);
243+
var size: usize = 0;
244+
point_array[size] = start;
245+
size += 1;
246+
247+
_ = start.tableRef.update_distance(&start, 0);
248+
249+
try solve_my_problem_plij(start, point_array, size, allocator);
250+
251+
try stdout.print("{any}!\n", .{max(start.tableRef.distance)});
252+
}

0 commit comments

Comments
 (0)