Dynamic associative array, to hold many values per key
Logesh Pillay
lp at webafrica.org.za
Tue Oct 29 20:29:00 PDT 2013
On Wednesday, 30 October 2013 at 01:14:53 UTC, Daniel Davidson
wrote:
> On Tuesday, 29 October 2013 at 18:02:46 UTC, Logesh Pillay
> wrote:
>> On Sunday, 20 October 2013 at 16:08:50 UTC, bearophile wrote:
>>> Logesh Pillay:
>>>
>>>> Thanks. Coming to D from python, I have to say D's tuples
>>>> look difficult. I'm going to see how far I can get with
>>>> structs writing my sudoku solver.
>>>
>>> I think defining the full correct hashing protocol manually
>>> for structs is harder than using tuples.
>>>
>>> There were many discussions to improve and simplify D tuples,
>>> but nothing has come out of them yet.
>>>
>>> Bye,
>>> bearophile
>>
>> This thread is dead. But I'm just posting to say using struct
>> as a key to an associative array worked fine without opHash
>> and other special methods. Does that mean (Alexandrescu, ch
>> 4.4.7) that the array retrieves slower (The sudoku solver
>> seems fast enough though) If so, there is an obvious way to
>> write (x, y) as an int: 10x + y
>
> What do you mean when you say "using a struct as a key to an
> associative array worked fine without opHash and other special
> methods? Do you have sample code showing it work?
Here's the program. Sorry, it's long and I don't see the
enclosing code labels.
import std.stdio;
struct Kie {int a, b;}
int[][Kie] possibles;
int[2][][Kie] associates;
void print_grid(ref int[][] ar) {
foreach (y; 0 .. 9) {
foreach (x; 0 .. 9)
if (ar[y][x])
writef("%s ", ar[y][x]);
else writef(". ");
writeln;
}
writeln;
}
void removeElem (int n, ref int[] lst) {
foreach (i, v; lst)
if (v == n) {
lst = lst[0 .. i] ~ lst[i+1 .. $];
break;
}
}
void setup (ref int[][] ar) {
foreach (y; 0 .. 9)
foreach (x; 0 .. 9)
if (!ar[y][x]) {
Kie k = {y, x};
foreach (i; 0 .. 9) {
if (i <> x)
associates[k] ~= [y, i]; //ass's in column
if (i <> y)
associates[k] ~= [i, x]; //ass's in row
}
foreach(c; 3 * (y/3) .. 3 + (3 * (y/3)))
foreach(r; 3 * (x/3) .. 3 + (3 * (x/3)))
if ((c <> y) && (r <> x))
associates[k] ~= [c, r]; //ass's in 9-block
int[10] used; // setup possible values
foreach (i; associates[k])
if (ar[i[0]][i[1]])
used [ar[i[0]][i[1]]] = 1;
foreach (i; 1 .. 10)
if (!used[i])
possibles[k] ~= i;
}
}
void eliminate (ref int[][] ar) {
bool ansFound = true;
while (ansFound) {
ansFound = false;
foreach (y; 0 .. 9)
foreach (x; 0 .. 9)
if (!ar[y][x]) {
Kie k = {y, x};
if (possibles[k].length == 1) {
int ans = ar[y][x] = possibles[k][0];
ansFound = true;
foreach (i; associates [k])
if (!ar[i[0]][i[1]]) {
Kie m = {i[0], i[1]};
removeElem (ans, possibles[m]);
}
}
}
}
}
void backtrack (ref int[][] ar) {
uint count;
bool ansFound = false;
foreach (y; 0 .. 9)
foreach (x; 0 .. 9)
if (!ar[y][x])
++count;
if (count) {
int[2][] lst;
foreach (y; 0 .. 9)
foreach (x; 0 .. 9)
if (!ar[y][x])
lst ~= [y, x];
void b2 (int i) {
if (i == count) {
ansFound = true;
return;
}
if (!ansFound) {
int c = lst[i][0],
r = lst[i][1];
Kie k = {c, r};
foreach (v; possibles[k]) {
if (ansFound)
break;
bool valid = true;
foreach (s; associates[k])
if (ar[s[0]] [s[1]] == v) {
valid = false;
break;
}
if (valid) {
ar[c][r] = v;
b2(i+1);
if (!ansFound)
ar[c][r] = 0;
}
}
}
}
b2(0);
}
}
void main() {
/*
int[][] arr = [
[0, 0, 3, 0, 2, 0, 6, 0, 0], //easy
[9, 0, 0, 3, 0, 5, 0, 0, 1],
[0, 0, 1, 8, 0, 6, 4, 0, 0],
[0, 0, 8, 1, 0, 2, 9, 0, 0],
[7, 0, 0, 0, 0, 0, 0, 0, 8],
[0, 0, 6, 7, 0, 8, 2, 0, 0],
[0, 0, 2, 6, 0, 9, 5, 0, 0],
[8, 0, 0, 2, 0, 3, 0, 0, 9],
[0, 0, 5, 0, 1, 0, 3, 0, 0]];
int [][] arr = [
[7, 3, 0, 9, 0, 0, 5, 0, 0], //hard
[0, 0, 5, 0, 8, 0, 0, 3, 0],
[0, 0, 6, 5, 0, 4, 0, 9, 0],
[0, 0, 0, 0, 0, 0, 3, 5, 6],
[3, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 5, 8, 0, 0, 0, 0, 0, 0],
[0, 7, 0, 3, 0, 5, 6, 0, 0],
[0, 4, 0, 0, 9, 0, 2, 0, 0],
[0, 0, 2, 0, 0, 6, 0, 1, 3]];
*/
int [][] arr = [ // harder
[8, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 3, 6, 0, 0, 0, 0, 0],
[0, 7, 0, 0, 9, 0, 2, 0, 0],
[0, 5, 0, 0, 0, 7, 0, 0, 0],
[0, 0, 0, 0, 4, 5, 7, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 3, 0],
[0, 0, 1, 0, 0, 0, 0, 6, 8],
[0, 0, 8, 5, 0, 0, 0, 1, 0],
[0, 9, 0, 0, 0, 0, 4, 0, 0]];
print_grid(arr);
setup(arr);
eliminate (arr);
backtrack(arr);
print_grid(arr);
}
More information about the Digitalmars-d-learn
mailing list