Sudoku Py / C++11 / D?

bearophile bearophileHUGS at lycos.com
Sat Aug 25 08:24:56 PDT 2012


maarten van damme:

> Ok, I'll try with Array!bool instead of bool.

There is also a BitVector, but it's heap-allocated, so probably
it's not a good idea. A ucent used as bit vector on a 64 bit
system is maybe the best way to implement that :-) But we don't
have ucents yet.

So maybe you have to implement your own bitvector with an uint[N]
where N is the minimal possible, it's 3 for the 9*9 Sudoku.


> I now renamed a few things, added a few extra checks and 
> generalized
> bearophiles modifications. Now the only thing keeping it from 
> solving
> 25 x 25 size sudoku's is the way I input numbers :)
>
> However, I now have a very strange issue. Compiling with dmd -O
> -release -inline works but compiling with dmd -O -release 
> -inline
> -noboundscheck gives the following compile time error:
>
> Assertion failure: 'semanticstarted == 2' on line 829 in file 
> 'module.c'
>
> abnormal program termination

Congratulations, you have found a compiler bug. I have found
maybe one hundred of those. Please minimize the code and submit
it to Bugzilla :-)


> Code is at http://dpaste.dzfl.pl/41a01039

Replacing side and size with boardSide and boardSize is a good
idea. But the two variables differ only by one char, so there's
space for further improvements.

The code contains:

// But, atention, an ushort is only 16 bits. Change this to uint
to be able to solve 25 x 25 sudoku's (http://dlang.org/type.html)
alias ushort SudokuCell; // contains only values in (0,
everythingPossible)

In D there are smarter ways to do that.
Generally in all your programs try to move as much semantics as
possible from comments to code.

In this case this means using static ifs to choose ushort or uint
(or give a compile-time error) to choose the best SudokuCell
type. There are fancier ways to do it, but this is simple and
seems OK, but I have not tested it:

// SudokuCell contains only values in (0, everythingPossible) (a
RangedValue when available)
static if (boardSide <= short.sizeof * 8) {
      alias ushort SudokuCell;
} else static if (boardSide <= uint.sizeof * 8) {
      alias uint SudokuCell;
} else static if (boardSide <= ulong.sizeof * 8) {
      alias ulong SudokuCell;
} else
      static assert(false, "");


Eventually a SudokuCell is meant to be replaced by a ranged
value, something like:

static if (boardSide <= short.sizeof * 8) {
      alias RangedValue!(ushort, 0, everythingPossible+1)
SudokuCell;
} else static if...

This moves another comment to code, and avoids some potential
run-time bugs in the code, because it forbids you to assign a
value outside that range (in non-release mode) to a Sudoku cell.


> Also, why do you use enum's and not consts ?

If you assign a global value like an int, using const or enum
produces the same binary. But generally enum conveys better that
meaning, because in D enum means that it's known at compile-time,
while const is for run-time constants too. Often while you code
it's better to use the tightest semantics available :-)
You just have to be careful with enum arrays, because they cause
extra allocations.

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list