Halp! type system (__expand_field_0 error), compile time/runtime questions (AoC-2017 puzzle spoilers inside)
aliak
something at something.com
Thu Dec 14 15:28:22 UTC 2017
Warning: following has Advent of Code 2017 (day 14 and day 10)
spoilers incase you are doing those challenges. And apologies for
the slightly long post, I'm unsure how much information is needed
here and am a bit clueless. Any help would be much appreciated.
=====
Ok, so I'm trying to get through these daily code puzzles with D.
Most of my troubles so far have come from trying to coax the type
system in to behaving how I want/expect, and parsing input data
at compile time. My background is a fair amount of C++ in the
past, and these days Swift (just incase it helps with explaining
things)
(fun little tidbit, we're a decent size group at work doing these
challenges in many languages and D is usually second in
performance after C! :) - other contenders include python, go,
scala, scheme, elixr, elm, javascript, fortran(!), kotlin, and
quite a few more - one nut job actually decided to do a different
language every day this month)
So for executing each of these puzzles (they all have two parts)
I have the following setup:
app.d:
import _day14;
enum data = process(import("day14.txt")); // load input file
void main() { solveA(data); solveB(data) }
So input processing is compile time, and solutions are executed
at runtime (i think?). Today's problem involves a custom hash
function that was developed on day 10 of the calendar.
So in my "_14.d" file I have this at the top:
// takes a string, hashes it and returns 32 character hex string
module _14;
import _10: knotHashHex = solveB;
Today's problem requires this hex string to be converted in to
binary (i.e. each hex char to 4 binary chars) - I am aware that
an optimization here would be to use bits instead of chars but
meh :p. So I have this defined:
// Takes "af49cb351fa..." -> "0010010111011..."
alias knotHash = (string input)
=> knotHashHex(input)
.map!binary // converts a dchar to a binary string so 'f'
-> "1111"
.join;
So my app first calls "process" on the input data (which is a
random string for today) and then the output of that goes in to
solveA and solveB of my day14 module. My "process" function for
today is this:
// size "immutable size = 128;"
// The puzzle requires a 128x128 grid of 1's and 0's so we
reuse the input string
// each round and just append a "-i" to it.
auto process(string input) {
return size
.iota
.map!(i => input ~ "-" ~ i.text)
.array
.map!knotHash
}
So the output type of this function is:
MapResult!(function (string input) => join(map(solveB(input))),
string[])
My solveA part works fine, you're supposed to count the number of
1's in the grid so it's a simple:
auto solveA(ReturnType!process grid) {
return grid
.join
.count!q{a == '1'};
}
The next part is where I start to have problems. It involves a
recursive depth-first-search approach so I have a function that
recurses:
void visit(ref string[] grid, int i, int j, ref
bool[size][size] visited) {
// check stuff and call visit again
}
And my solveB looks like this:
auto solveB(ReturnType!process grid) {
auto arrayGrid = grid.array; // convert to string[]
// more code then at some point I call:
visit(arrayGrid, i, j, visited);
}
So up to here everything works. But now I don't like that I have
a "grid.array" inside solveB but not in solveA. Seems
asymmetrical. So I figured I could just change my "process"
function above to return an array directly by just adding a
".array" to the pipeline.
Then I get this error:
Error: couldn't find field __expand_field_0 of type ulong in
Tuple(0LU, 117)
117 is the ascii code for 'u' btw, which happens to be the first
character in my random input string. This error is coming from
inside my day 10's "solveB" function (which is imported in day 14
as "knotHashHex"). It comes from here:
int[] rotate(int[] list, int[] lengths) {
auto range = list.cycle;
foreach (skip, length; lengths.enumerate) { // <-- here is
error
// do stuff to range
}
return list;
}
So it says something about ulong and expanding a tuple type. But
I'm having a hard time with this error message.
Questions: What does it mean? It can't expand field 0 (the ulong)
in to my skip variable? Why not? And most importantly, why is it
having trouble here during my "process" function, but not
screaming when I call "grid.array" in my "solveB" function? What
am I doing wrong?
So anyway, Halp!
More information about the Digitalmars-d-learn
mailing list