Advent of Code, day 4 in Zig

katafrakt profile image Paweł Świątkowski Updated on ・2 min read

For day 4 of Advent of Code I wrote my solution in Zig. In this blog post I want to share a couple of my notes from the process.

Zig was brought to my attention earlier this year as an example of well-designed new programming language. By just looking at examples, it looked for me like "a more correct Rust", which was not very promising, given my problems with writing in Rust in the past. Also, I wanted to give it a shot earlier in Advent of Code, however... I found I don't really know how to read the file in it. The docs are vague and it seems that filesystem support is very rudimentary at the moment. This discouraged me for a while, however, when I saw that today's problem does not need a separate file for the input, I decided to give it a go anyway.

I would describe my experience as relatively pleasant. I had some problems, but all along the way the compile led me nicely with its error messages. The syntax itself is quite intuitive (with some exceptions listed below). Overall, the solution is not very pretty, but I bet it wouldn't be very beautiful in C either. And Zig targets itself as C replacement.

I found it weird that to populate an array I need to use syntax like this:

for (array) |*item| {
    const digit = @mod(value, 10);
    item.* = digit;
    value = @divFloor(value, 10);

Also, I needed to use weird methods like @mod and @divFloor instead of regular ones, because apparently Zig make a huge difference between compilation time integers (i.e. given in the code) and runtime ones. There was quite a lot of casting going on in my code. I understand this probably allows having more correct programs and is better for compiler implementation, but I find it a bit awkward.

On the upside, builtin unit tests helped me a lot checking small pieces of my logic for correctness. The pattern itself is not new for me, I really love it in D, and seing it in Zig made me really happy.

fn numToDigits(num: i32) [6]i32 {
    // ...body
    return array;

test "numToDigits" {
    const num: i32 = 321456;
    const re = numToDigits(num);
    assert(re[0] == 6);
    assert(re[3] == 1);

Overall, I think Zig is an interesting language to look at. It still needs some love for less-hardcore compilers fans (my opinion, creators probably have different one). But I see why people give it as an example of a really well designed low-level language. I definitely want to try it out some more.


markdown guide