Better idea for double list comprehension?
CJS
Prometheus85 at hotmail.com
Sat Jan 18 14:04:59 PST 2014
>
> import std.stdio, std.conv, std.algorithm, std.array;
>
> string[] cross(in string A, in string B) {
> return cartesianProduct(A, B).map!(ab => ab[].text).array;
> }
>
> void main() {
> cross("ab", "12").writeln;
> }
>
>
> But note that currently cartesianProduct doesn't return the
> pairs in a natural order.
>
> cross() should be pure.
Great. Here's a similar follow-up question. I'm trying to
reproduce Peter Novig's Python code for solving Sudoku in D
(http://norvig.com/sudoku.html). As a way to understand both his
code and D/Phobos better. The entire code chunk I'm working on
now is
def cross(A, B):
"Cross product of elements in A and elements in B."
return [a+b for a in A for b in B]
digits = '123456789'
rows = 'ABCDEFGHI'
cols = digits
squares = cross(rows, cols)
unitlist = ([cross(rows, c) for c in cols] +
[cross(r, cols) for r in rows] +
[cross(rs, cs) for rs in ('ABC','DEF','GHI') for cs
in ('123','456','789')])
units = dict((s, [u for u in unitlist if s in u])
for s in squares)
peers = dict((s, set(sum(units[s],[]))-set([s]))
for s in squares)
Unfortunately my current best attemp doesn't compile:
import std.stdio : writeln;
import std.range : chunks, chain;
import std.algorithm;
import std.array;
import std.conv;
auto cross(R1, R2)(in R1 A, in R2 B){
return cartesianProduct(A,B).map!(ab => ab[].text).array;
}
void main(){
string letters = "ABCDEFGHI";
string digits = "123456789";
auto cols = digits;
auto rows = letters;
auto squares = cross(rows, cols);
string[][] unitlist;
foreach(c; cols){
unitlist ~= cross(rows, to!string(c));
}
foreach(r; rows){
unitlist ~= cross(to!string(r), cols);
}
foreach(r; chunks(rows, 3)){
foreach(c; chunks(cols, 3)){
unitlist ~= cross(to!string(r),to!string(c));
}
}
string[][][string] units;
string[][string] peers;
foreach(s; squares){
units[s] = filter!(x=>any!(y=>(s==y)))(unitlist);
}
foreach(s; squares){
peers[s] = remove(chain(units[s]), s);
}
}
Up until units and peers are defined it works, but I find the
to!string conversions ugly. Because of cross being templated I
don't think they should be necessary. Taking the cartesian
product of a string with a character seems like a reasonable
request. Simialrly, so does taking the cartesian product of a
string with a range of characters.
For the associative arrays I'm unsure I have the correct calls,
but they looked reasonable. Any suggestions?
More information about the Digitalmars-d-learn
mailing list