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?


Reply via email to