3

I am very new to zig and doing a very simple coding exercise. The question is about scoring words in scrabble and presents a table. As a sort of challenge I wanted to replicate the scoring table as an array of arrays where the index of the outer array represent the points for a letter and the inner arrays contain the letters that match that score. Then I wanted to convert this to a lookup table (really just a flat array of scores) in comptime. I also wanted to be able to change the table without having to change any of the conversion code.

I'm currently having difficulty with the very initial part, declaring the multi dimensional input array. I've tried this:

const point_letters = [_][_]u8 {
    [_]u8{'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T',},
    [_]u8{'D', 'G',},
    [_]u8{'B', 'C', 'M', 'P',},
    [_]u8{'F', 'H', 'V', 'W', 'Y',},
    [_]u8{'K',},
    [_]u8{},
    [_]u8{},
    [_]u8{'J', 'X',},
    [_]u8{},
    [_]u8{'Q', 'Z',},
};

as well as

const point_letters = [_](*[_]u8){
    ([_]u8{'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T',}).*,
    ([_]u8{'D', 'G',}).*,
    ([_]u8{'B', 'C', 'M', 'P',}).*,
    ([_]u8{'F', 'H', 'V', 'W', 'Y',}).*,
    ([_]u8{'K',}).*,
    ([_]u8{}).*,
    ([_]u8{}).*,
    ([_]u8{'J', 'X',}).*,
    ([_]u8{}).*,
    ([_]u8{'Q', 'Z',}).*,
};

But they both give the same error pointing at the size for the inner arrays:

error: unable to infer array size

2 Answers 2

5

Arrays in Zig are homogeneous, i.e. all elements have the same type.

Since the length of an array is part of its type, trying to create an array containing arrays of different lengths is not possible.

What you can do is create an array containing slices, because a slice consists of a pointer (pointing to an array stored elsewhere) and an integer, i.e. all slices have the same type.

So first of all you need to change the type of point_letters to [_][]u8.

Then, to construct the slices, you have to use &[_]u8{ … } instead of [_]u8{ … }.

In addition, the compiler (version 0.11.0) told me that @constCast is required (after trying @ptrCast first in order to fix the error when using &[_]u8{ … } alone).

This works:

const point_letters = [_][]u8 {
    @constCast(&[_]u8{'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T',}),
    @constCast(&[_]u8{'D', 'G',}),
    // …
};

To make it less verbose, you can use a helper function that is executed at compile time:

fn slice(comptime a: anytype) []u8 {
    return @constCast(&a);
}

const point_letters = [_][]u8 {
    slice([_]u8{'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T',}),
    slice([_]u8{'D', 'G',}),
    // …
};

I just found out that if you change the type of point_letters to [_][]const u8 (taking jjmerelo's answer as a hint), no cast is needed:

const point_letters = [_][]const u8 {
    &[_]u8{'A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T',},
    &[_]u8{'D', 'G',},
    // …
};

(And at this point it becomes clear that for the special case of u8 as the base type, &[_]u8{'A', 'E', …} is just the same as "AEIOULNRST".)

Sign up to request clarification or add additional context in comments.

Comments

1

This seems to work:

const std = @import("std");

pub fn main() void {
    const point_letters = [10][]const u8{ "AEIOULNRST", "DG", "BCMP", "FHVWY", "K", "", "", "JX", "", "QZ" };
    std.debug.print("Point_letters = {s}\n", .{point_letters[0]});
}

But I'm not sure this would work for Scrabble, and not sure if this represents exactly what you have there, mainly the empty elements. A set might work better, but there's no such primitive type. Anyhow, you can search for specific letters in these strings, as explained here, for instance (using std.mem)

1 Comment

This is a great answer to my specific problem, but it isn't as widely applicable as the other answer -- what if instead of slices of u8 we had arrays of structs -- hence I marked the other one as correct. But thank you for writing it up anyway. It's still very useful. I think it's also very interesting that we don't have to cast it to a slice like an array. I was wondering why, and found this to be very informative: zig.news/kristoff/what-s-a-string-literal-in-zig-31e9

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.