leonardo
View:Recent Entries.
View:Archive.
View:Friends.
View:User Info.
View:Website (My Website).
You're looking at the latest 10 entries.
Missed some entries? Then simply jump back 10 entries

Current Music:d language, haskell, static typing
Security:
Subject:An example of static type safety
Time:01:15 am
A nice small example of the safety coming from the strong static typing of Haskell:
http://blog.malde.org/posts/polymorphic-types-are-safer.html

This is an example of the code he is writing about (Haskell code):
type Alignment a b = [(a, b)]

trans_align :: (Ord x, Ord y) => Alignment x y -> Alignment y z -> Alignment x z
trans_align ((p1, p2):ps) ((q1, q2) : qs)
    | p2 == q1 = (p1, q2) : trans_align ps qs   -- return match and continue
    | p2 < q1 = trans_align ps ((q1, q2) : qs)  -- skip first 'p'
    | q1 < p2 = trans_align ((p1, p2) : ps) qs  -- skip first 'q'
trans_align _ _ = []                            -- one input is empty

main = do
    let s1 = [(1, 2), (2, 3), (4, 5)] :: Alignment Int Int
    let s2 = [(1, 2), (3, 4), (5, 6)] :: Alignment Int Int
    print $ trans_align s1 s2 -- Output: [(2,4),(4,6)]

See what have we done? In the end we’ll probably just use Int for all the type variables (x, y, and z), but the implementation of trans_align doesn’t know this. Thus the type ensures that indices in the different sequences are kept separately, and things like comparing indices from different sequences, or returning indices from the wrong sequence are no longer not just bad ideas, they’re illegal, and enforced by the compiler. How cool is that?
You see what he means swapping two names by mistake, this doesn't compile:

type Alignment a b = [(a, b)]

trans_align :: (Ord x, Ord y) => Alignment x y -> Alignment y z -> Alignment x z
trans_align ((p1, p2):ps) ((q1, q2) : qs)
    | p2 == q1 = (p1, q2) : trans_align ps qs   -- return match and continue
    | p2 < q1 = trans_align ps ((q1, q2) : qs)  -- skip first 'p'
    | q1 < p2 = trans_align ((p2, p1) : ps) qs  -- try this!
trans_align _ _ = []                            -- one input is empty

main = do
    let s1 = [(1, 2), (2, 3), (4, 5)] :: Alignment Int Int
    let s2 = [(1, 2), (3, 4), (5, 6)] :: Alignment Int Int
    print $ trans_align s1 s2 -- Output: [(2,4),(4,6)]


You can't do the same in D "naturally" (you have to introduce more code), D doesn't refuse the mistake:

import std.stdio, std.array, std.typecons;

template Alignment(a, b) {
    alias Tuple!(a,b)[] Alignment;
}

alias tuple T;

Tuple!(x,z)[] trans_align(x, y, z)(Tuple!(x,y)[] p, Tuple!(y,z)[] q) {
    if (p.empty || q.empty) return [];

    auto p1 = p[0][0];
    auto p2 = p[0][1];
    auto ps = p[1 .. $];
    auto q1 = q[0][0];
    auto q2 = q[0][1];
    auto qs = q[1 .. $];

    if (p2 == q1) return T(p1, q2) ~ trans_align(ps, qs); // return match and continue
    if (p2 < q1) return trans_align(ps, T(q1, q2) ~ qs);  // skip first 'p'
    if (q1 < p2) return trans_align(T(p1, p2) ~ ps, qs);  // skip first 'q'
    //if (q1 < p2) return trans_align(T(p2, p1) ~ ps, qs);  // skip first 'q'

    assert(0);
}

void main() {
    Alignment!(int,int) s1 = [T(1, 2), T(2, 3), T(4, 5)];
    Alignment!(int,int) s2 = [T(1, 2), T(3, 4), T(5, 6)];
    writeln(trans_align(s1, s2)); // Output: [Tuple!(int,int)(2, 4), Tuple!(int,int)(4, 6)]
}
comments: Leave a comment Add to Memories Share

Tags:
Security:
Subject:Updates and links
Time:01:05 am
Updates:

A nice image of Chakasa Bluefire by Elisa ("the_strange_thing"):


See it also also here (registration required to see this image):
http://www.furaffinity.net/view/7543422/

----------------

D and Python translations of a C++ solution of the "Hall of Mirrors" problem of the Google Code Jam 2012 qualifications:
http://www.fantascienza.net/leonardo/js/index.html#mirrors


Solution of a very simple problem appeared on Reddit-DailyProgrammer:
http://www.reddit.com/r/dailyprogrammer/comments/schnp/4162012_challenge_40_difficult/
http://www.fantascienza.net/leonardo/js/index.html#min_distance

----------------

Links:

To better understand the xkcd comics:
http://www.explainxkcd.com/


The significant difference between having 32 Vs 64 bit pointers if you are using a conservative garbage collector (like the GC currently used by D language):
http://www.deadalnix.me/2012/03/05/impact-of-64bits-vs-32bits-when-using-non-precise-gc/


An excellent article about using the sun to help reduce heating/cooling in houses, "The Solar Envelope: How to Heat and Cool Cities Without Fossil Fuels":
http://www.theoildrum.com/node/9074


A good general rule to follow while you program in an imperative language that allows mutability but also allows to enforce immutability. Where possible make variables immutable and reduce their scope as much as possible,
http://blog.knatten.org/2011/11/11/disempower-every-variable/


FatFonts, a simple but nice idea to represent a density map with a custom font, and show the numberical values too at the same time:
http://fatfonts.org/?page_id=68
http://fatfonts.org/?page_id=181
http://innovis.cpsc.ucalgary.ca/innovis/uploads/Publications/Publications/FatFonts.pdf
comments: Leave a comment Add to Memories Share

Tags:, , , ,
Security:
Subject:A simple usage example of Haskell type classes and D templates
Time:01:18 am
This is a nice introduction to Haskell language:
http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way/

Near the beginning there is this simple Haskell program:

f :: Num a => a -> a -> a
f x y = x*x + y*y

main = print (f 3 2.4)

It compiles and produces the 14.76 output because:
`3` is a valid representation both for Fractional numbers like Float and for Integer. As `2.4` is a Fractional number, `3` is then interpreted as being also a Fractional number.

Despite the D language is sometimes better than C++, D templates are not Haskell type classes. This (heavily annotated) D code works (all those annotations are optional, but template constraints are often handy, also to help the compiler produce better error messages):
import std.traits;

T f(T)(in T x, in T y) pure nothrow @safe if (isNumeric!T) {
    return x ^^ 2 + y ^^ 2;
}

void main() {
    import std.stdio;
    writeln(f(2.1, 4.2));
}

But unlike in the Haskell example, D templates don't perform implicit type coercion (as it happens for normal D functions), so this code causes a compilation error:
import std.traits;

T f(T)(in T x, in T y) pure nothrow @safe if (isNumeric!T) {
    return x ^^ 2 + y ^^ 2;
}

void main() {
    import std.stdio;
    writeln(f(2, 4.2)); // does not match any function template
}

If you also want it to work with the multi-precision numbers currently defined in Phobos standard library you have to drop the "pure" and "nothrow" annotations because currently Phobos BigInt code doesn't have those qualities. And you also have to drop the "in" (that in D equals to "scope const") annotations on the input arguments because currently BigInt doesn't work well with immutability. You also need to keep in mind that isNumeric is a Phobos trait defined for built-in numbers only, so you need to add another specialization:
import std.traits, std.bigint;

T f(T)(T x, T y) if (isNumeric!T || is(T == BigInt)) {
    return x ^^ 2 + y ^^ 2;
}

void main() {
    import std.stdio;
    writeln(f(BigInt(2), BigInt(4)));
}

What if you want to use Rational numbers too or other kind of user-defined numbers? You have probably to write and use a isNumber template trait that contains actual D code that uses the basic numeric capabilities inside a __traits(compiles, {...}). Something like this for isInputRange:
template isInputRange(R) {
    enum bool isInputRange = __traits(compiles, {
        R r = void; // can define a range object
        if (r.empty) {} // can test for empty
        r.popFront(); // can invoke popFront()
        auto h = r.front; // can get the front of the range
    });
}

Such code is not hard to write, it's just a minimal list of operations you want to verify, but sometimes you need some tries to put inside it all your requirements. So here it's a good idea to write some compile-time unit tests to verify that your isNumber is working well with several types and usages. D template constraints are not the mythic C++0x Concepts, they can't verify conformance in both directions. So you usually have to write compile-time unit tests to design and write them well.
comments: 1 comment or Leave a comment Add to Memories Share

Tags:,
Security:
Subject:Updates and links
Time:11:42 pm
Updates:

Updated nbody (from Shootout site) benchmark in D:
http://www.fantascienza.net/leonardo/js/index.html#nbody

Updated slow_d (a list of slow D micro-benchmarks) with "alloca_vs_gc":
http://www.fantascienza.net/leonardo/js/index.html#slowd

Updated Richards benchmark in D:
http://www.fantascienza.net/leonardo/js/index.html#richards

Added D and Python implementation of a 3D rose, originally in JavaScript:
http://www.fantascienza.net/leonardo/js/index.html#rose3d

--------------------

Links:

Naked mole rats have an incredible biology:
http://www.slate.com/articles/health_and_science/the_mouse_trap/2011/11/naked_mole_rats_can_they_help_us_cure_cancer_.html

CS240h lecture notes, several ideas of functional programming:
http://www.scs.stanford.edu/11au-cs240h/notes/

Java Anti-null annotation. A bit complex, but it looks useful (and it's missing in D2):
http://eclipseandjazz.blogspot.com/2011/12/inter-procedural-null-analysis-using.html

A large amount of notes on algorithms:
http://www.cs.uiuc.edu/~jeffe/teaching/algorithms/everything.pdf

The new Python JIT is much more than it looks:
http://tratt.net/laurie/tech_articles/articles/fast_enough_vms_in_fast_enough_time

Nice demo ideas for interactive programming and interactive design:
http://vimeo.com/36579366
comments: Leave a comment Add to Memories Share

Tags:, ,
Security:
Subject:Dice and random sources
Time:02:47 am
On Le Scienze (an edition of Scientific American) number 519, November 2011 there is a small mathematical problem. It asks to extract a random number among 8 using a die (that gives just a 1-6 result).

The Le Scienze number 520, December 2011 shows two alternative answers. The first is to throw the die three times, and take the parity of each result. This means producing three random bits, that are the binary digits of a 0..7 number. The second solution is to use the rotation too of the physical die, and look at the numbers on the other faces, this gives 24 random possibilities, that are usable to find a 0..8 random number.


This simple D v.2 code uses the first solution. random8() returns a random 0..8 number. It requires three throws to find a result:
import std.stdio, std.random, std.algorithm;

__gshared uint dieCount;

int throwDie() {
    dieCount++;
    return uniform(0, 6);
}

int random8() {
    return ((throwDie() % 2) << 2) +
           ((throwDie() % 2) << 1) +
           (throwDie() % 2);
}

void main() {
    enum int N = 10_000_000;
    uint[int] freqs;

    foreach (_; 0 .. N)
        freqs[random8()]++;

    foreach (k; freqs.keys.sort())
        writeln(k, " ", freqs[k]);

    writefln("\n%.6f", dieCount / cast(double)N);
}


Output:
0 1249566
1 1250357
2 1251060
3 1248940
4 1250848
5 1248829
6 1250353
7 1250047

3.000000


A die throw gives about 2.6 random bits, if you look at just its upper face. So using 3 bits from 3 throws means wasting about 4.75 random bits (log(6 * 6 * 6, 2) ~= 7.75).

But it's not hard to reduce the number of dice to throw on average. The idea is to just throw away a die result if it's larger than 4 (but in the code the die gives a 0..6 result, so the limit is 3), to collect two random bits, and then to find the parity of another die throw to collect the third bit of the result. On average this requires just a little more than two and half throws for each 1..9 random result. But this strategy too wastes some bits of the random source:

import std.stdio, std.random, std.algorithm;

__gshared uint dieCount;

int throwDie() {
    dieCount++;
    return uniform(0, 6);
}

int random8() {
    while (true) {
        immutable int d1 = throwDie();
        if (d1 < 4)
            return (d1 << 1) + (throwDie() % 2);
    }
}

void main() {
    enum int N = 10_000_000;
    uint[int] freqs;

    foreach (_; 0 .. N)
        freqs[random8()]++;

    foreach (k; freqs.keys.sort())
        writeln(k, " ", freqs[k]);

    writefln("\n%.6f", dieCount / cast(double)N);
}



Output:

0 1250850
1 1249593
2 1248823
3 1248606
4 1249314
5 1250182
6 1251221
7 1251411

2.500165


There are ways to waste less bits on average, but they become more complex and require more total throws to reach the average.

Update Dec 19 2011: for a smarter solution see this rosettacode task:
http://rosettacode.org/wiki/Seven-sided_dice_from_five-sided_dice#D

The Task: Given an equal-probability generator of one of the integers 1 to 5 as dice5; create dice7 that generates a pseudo-random integer from 1 to 7 in equal probability using only dice5 as a source of random numbers.

Two D solutions, fiveToSevenSmart minimizes the number of calls to dice7:
import std.random: uniform;

__gshared uint die5Count;

/// Generates a random number in [1, 5].
int dice5() /*nothrow*/ {
    die5Count++; // update count
    return uniform(1, 6);
}

/// Naive, generates a random number in [1, 7] using dice5.
int fiveToSevenNaive() /*nothrow*/ {
    immutable int r = dice5() + dice5() * 5 - 6;
    return (r < 21) ? (r % 7) + 1 : fiveToSevenNaive();
}

/**
Generates a random number in [1, 7] using dice5,
minimizing calls to dice5.
*/
int fiveToSevenSmart() /*nothrow*/ {
    static int rem = 0, max = 1;

    while (rem / 7 == max / 7) {
        while (max < 7) {
            immutable int rand5 = dice5() - 1;
            max *= 5;
            rem = 5 * rem + rand5;
        }

        immutable int groups = max / 7;
        if (rem >= 7 * groups) {
            rem -= 7 * groups;
            max -= 7 * groups;
        }
    }

    immutable int result = rem % 7;
    rem /= 7;
    max /= 7;
    return result + 1;
}

void main() {
    import std.algorithm; // sort, reduce
    import std.stdio; // writefln
    enum int N = 10_000_000;

    foreach (rnd; [&fiveToSevenNaive, &fiveToSevenSmart]) {
        uint[int] counts;
        .die5Count = 0;

        foreach (_; 0 .. N)
            counts[rnd()]++;

        immutable tot = reduce!q{a + b}(counts.byValue());
        foreach (k; sort(counts.keys))
            writefln("%d %.2f%%", k, (100 * counts[k]) / cast(double)tot);

        writefln("Average dice5 throws: %.4f\n",
                 die5Count / cast(double)N);
    }
}


That prints:
1 14.29%
2 14.30%
3 14.27%
4 14.29%
5 14.26%
6 14.29%
7 14.29%
Average dice5 throws: 2.3813

1 14.28%
2 14.28%
3 14.29%
4 14.30%
5 14.29%
6 14.29%
7 14.27%
Average dice5 throws: 1.5458
comments: Leave a comment Add to Memories Share

Tags:, , ,
Security:
Subject:Updates and links
Time:01:26 am
Two new small D programs, to compute sorting networks at compile time, and to compute PI:
http://www.fantascienza.net/leonardo/js/index.html#bose_nelson
http://www.fantascienza.net/leonardo/js/index.html#machin_pi

-------------------

A little but nice introduction to Haskell:
http://www.ozonehouse.com/mark/haskell-amuse-bouche/slides.html
And its code:
https://github.com/mtnviewmark/haskell-amuse-bouche
And its talk:
http://youtu.be/b9FagOVqxmI


An Adventure in the Nth Dimension, by the good Brian Hayes, some simple but interesting and important comments about higher higher dimensions geometry:
http://www.americanscientist.org/issues/id.13850,y.0,no.,content.true,page.1,css.print/issue.aspx


One of the strangest things I've seen in JavaScript, used with the Agda language:
https://github.com/agda/agda-frp-js
comments: Leave a comment Add to Memories Share

Tags:, , ,
Security:
Subject:Einstein's Riddle solutions in D
Time:02:46 am
[Update: the same text with colorized code: http://www.fantascienza.net/leonardo/ar/einstein_riddle.html ]

This post is about the D translation of two old little C++ programs, to show some differences in the idioms of the two languages, and to discuss a little about static typing too.

I have found the original C++ code in this page:
See also: http://www.weitz.de/einstein.html

Both C++ programs solve a logic problem named "Einstein's Riddle". Here you find more info about its variants:
http://en.wikipedia.org/wiki/Zebra_Puzzle

The original C++ versions are by Klaus Betzler and by Dr. Gabor Csanyi.

This post is not a discussion of the Einstein's Riddle, or of algorithms that solve it. The C++ code is about ten years old, so it doesn't use some of the handy features of modern C++0x, that are sometimes comparable to D features. So this is not meant to be a fair comparison between modern C++ and modern D V.2 language.

To compile the D code I am using DMD v.2.056 (or an alpha version of v.2.057 from GitHub).

See here for the complete C++ and D code:
http://www.fantascienza.net/leonardo/js/einstein.zip

Archive contents:
- einstein1.cpp: original first C++ (fast) solution.
- einstein1a.d: D translation of the first C++ solution.
- einstein2.cpp: original second C++ (slow) solution.
- einstein2a.d: first D translation of the second C++ solution. This contains a good amount of strong static typing. This uses more idiomatic D arrays.
- einstein2b.d: second D translation of the second C++ solution. This uses arrays that are more efficient but less idiomatic D.
- einstein2c.py: Python2 translation of the first D translation of the second C++ solution. This program is rather slow, even counting it's in Python, I don't fully know why.

==========================================

Comments on the first program (einstein1.cpp and einstein1a.d):


C> inline unsigned long BIT(unsigned n) {return 1<<n;}
C>
C> const unsigned long
C> yellow = BIT(0),
C> blue = BIT(1),
C> red = BIT(2),
C> green = BIT(3),
C> white = BIT(4),
C>
C> norwegian = BIT(5),
C> dane = BIT(6),
C> brit = BIT(7),
C> german = BIT(8),
C> swede = BIT(9),
C>
C> water = BIT(10),
C> tea = BIT(11),
C> milk = BIT(12),
C> coffee = BIT(13),
C> beer = BIT(14),
C>
C> dunhill = BIT(15),
C> marlboro = BIT(16),
C> pallmall = BIT(17),
C> rothmans = BIT(18),
C> winfield = BIT(19),
C>
C> cat = BIT(20),
C> horse = BIT(21),
C> bird = BIT(22),
C> fish = BIT(23),
C> dog = BIT(24);
C>
C> const char * Label[] = {
C> "Yellow","Blue","Red","Green","White",
C> "Norwegian","Dane","Brit","German","Swede",
C> "Water","Tea","Milk","Coffee","Beer",
C> "Dunhill","Marlboro","Pallmall","Rothmans","Winfield",
C> "Cat","Horse","Bird","Fish","Dog"
C> };

D> string bitFlags(BaseType=uint)(string enumName, string enumItems) {
D> string result = text("enum ", enumName, " : ", BaseType.stringof, " {\n");
D> result ~= text(" None = 0,\n");
D> foreach (i, flag; enumItems.split())
D> result ~= text(" ", flag, " = (1 << ", i, "),\n");
D> return result ~ "}";
D> }
D>
D> mixin(bitFlags!uint("E", "
D> Yellow Blue Red Green White
D> Norwegian Dane Brit German Swede
D> Water Tea Milk Coffee Beer
D> Dunhill Marlboro Pallmall Rothmans Winfield
D> Cat Horse Bird Fish Dog"
));
The D version uses named enums, so D writeln is able to print their names, this avoids the need of the Label array. A simplified bitFlags compile-time function allows to create a simple enumeration of bit flags.

----------------------------------------------

C> const unsigned long color = yellow+blue+red+green+white;
C> const unsigned long country = norwegian+dane+brit+german+swede;
C> const unsigned long drink = water+tea+milk+coffee+beer;
C> const unsigned long cigar = dunhill+marlboro+pallmall+rothmans+winfield;
C> const unsigned long animal = cat+horse+bird+fish+dog;
C>
C> unsigned long house[5] = {norwegian,blue,milk,0,0}; // rules 8,9,14
C> unsigned long result[5];
C>
C> const unsigned long comb[] = { // simple rules
C> brit+red, // 1
C> swede+dog, // 2
C> dane+tea, // 3
C> green+coffee, // 5
C> pallmall+bird, // 6
C> yellow+dunhill, // 7
C> winfield+beer, // 12
C> german+rothmans // 13
C> };
C>
C> const unsigned long combmask[] = { // corresponding selection masks
C> country+color,
C> country+animal,
C> country+drink,
C> color+drink,
C> cigar+animal,
C> color+cigar,
C> cigar+drink,
C> country+cigar
C> };

D> enum E color =   E.Yellow    | E.Blue     | E.Red      | E.Green    | E.White;
D> enum E country = E.Norwegian | E.Dane | E.Brit | E.German | E.Swede;
D> enum E drink = E.Water | E.Tea | E.Milk | E.Coffee | E.Beer;
D> enum E cigar = E.Dunhill | E.Marlboro | E.Pallmall | E.Rothmans | E.Winfield;
D> enum E animal = E.Cat | E.Horse | E.Bird | E.Fish | E.Dog;
D>
D> immutable E[] comb = [ // simple rules
D> E.Brit | E.Red, // 1
D> E.Swede | E.Dog, // 2
D> E.Dane | E.Tea, // 3
D> E.Green | E.Coffee, // 5
D> E.Pallmall | E.Bird, // 6
D> E.Yellow | E.Dunhill, // 7
D> E.Winfield | E.Beer, // 12
D> E.German | E.Rothmans // 13
D> ];
D>
D> immutable E[] combMask = [ // corresponding selection masks
D> country | color,
D> country | animal,
D> country | drink,
D> color | drink,
D> cigar | animal,
D> color | cigar,
D> cigar | drink,
D> country | cigar
D> ];

The D version uses | (or) instead of +, for better clarity. comb and combMask are not enums for more efficiency.

D> int main() {
D> E[5] house = [E.Norwegian, E.Blue, E.Milk, E.None, E.None]; // rules 8, 9, 14
D> E[5] result;
The D code defines 'house' and 'result' inside the main(), this avoids global mutable variables. 'house' is needed as argument by most functions, but the overall performance of the program is about unchanged.

'house' is an array of E enums, that are strongly typed, so I have had to add E.None, that is represented with 0.

==========================================

Comments on the second program (einstein2.cpp and einstein2a.d):

C> char *NationS[] = {"British", "Swedish", "Danish", "Norvegian", "German"};
C> enum Nation {British, Swedish, Danish, Norvegian, German};
C> char *NumberS[] = {"One", "Two", "Three", "Four", "Five"};
C> enum Number {One, Two, Three, Four, Five};
C> char *ColourS[] = {"Red", "Green", "Blue", "White", "Yellow"};
C> enum Colour {Red, Green, Blue, White, Yellow};
C> char *DrinkS[] = {"Milk", "Coffee", "Water", "Beer", "Tea"};
C> enum Drink {Milk, Coffee, Water, Beer, Tea};
C> char *SmokeS[] = {"PallMall", "Dunhill", "Blend", "BlueMaster", "Prince"};
C> enum Smoke {PallMall, Dunhill, Blend, BlueMaster, Prince};
C> char *PetS[] = {"Dog", "Cat", "Fish", "Horse", "Bird"};
C> enum Pet {Dog, Cat, Fish, Horse, Bird};

D> enum Number : ubyte { One,      Two,     Three,  Four,       Five   };
D> enum Color : ubyte { Red, Green, Blue, White, Yellow };
D> enum Drink : ubyte { Milk, Coffee, Water, Beer, Tea };
D> enum Smoke : ubyte { PallMall, Dunhill, Blend, BlueMaster, Prince };
D> enum Pet : ubyte { Dog, Cat, Fish, Horse, Bird };
D> enum Nation : ubyte { British, Swedish, Danish, Norvegian, German };
In D enums are almost strongly typed, but not as strongly as C++0x "enum class" enumerations:

http://en.wikipedia.org/wiki/C%2B%2B0x#Strongly_typed_enumerations

In D writeln is able to print the name of named enums, so the arrays like PetS are not necessary. In D unsigned bytes are named "ubyte".

----------------------------------------------

C> void
C> myprint(char *ptr, char **s)
C> {
C> printf("%12s%12s%12s%12s%12s\n", s[ptr[0]], s[ptr[1]], s[ptr[2]], s[ptr[3]], s[ptr[4]]);
C> }
...
C> main()
C> {
...
C> // woo-hoo!
C> printf("Found a solution:\n");
C> printf("Nation: ");
C> myprint(nation, NationS);
C> printf("Number: ");
C> myprint(number, NumberS);
C> printf("Colour: ");
C> myprint(colour, ColourS);
C> printf("Drink : ");
C> myprint(drink, DrinkS);
C> printf("Smoke : ");
C> myprint(smoke, SmokeS);
C> printf("Pet  : ");
C> myprint(pet, PetS);
C> printf("\n");

D> void showRow(E)(in E[] data) {
D> auto names = [EnumMembers!E];
D> writefln("%6s: %12s%12s%12s%12s%12s",
D> (Unqual!E).stringof,
D> text(names[data[0]]), text(names[data[1]]),
D> text(names[data[2]]), text(names[data[3]]),
D> text(names[data[4]]));
D> }
...
D> void main() {
...
D> writeln("Found a solution:");
D> showRow(nation);
D> showRow(number);
D> showRow(color);
D> showRow(drink);
D> showRow(smoke);
D> showRow(pet);
D> writeln();
D> }

D here is doing more at compile-time. The printing template function showRow is able to find the names of the enums and of their elements.

text() is used because formats like "%12s" are not yet supported (DMD 2.056) for enum members.

----------------------------------------------

C> char perms[][5] = {
C> { 4, 3, 2, 1, 0},
C> { 3, 4, 2, 1, 0},
C> { 4, 2, 3, 1, 0},
C> { 2, 4, 3, 1, 0},
C> { 3, 2, 4, 1, 0},
C> { 2, 3, 4, 1, 0},
C> { 4, 3, 1, 2, 0},
C> { 3, 4, 1, 2, 0},
C> { 4, 1, 3, 2, 0},
C> { 1, 4, 3, 2, 0},
C> { 3, 1, 4, 2, 0},
C> { 1, 3, 4, 2, 0},
C> { 4, 2, 1, 3, 0},
C> { 2, 4, 1, 3, 0},
C> { 4, 1, 2, 3, 0},
C> { 1, 4, 2, 3, 0},
C> { 2, 1, 4, 3, 0},
C> { 1, 2, 4, 3, 0},
C> { 3, 2, 1, 4, 0},
C> { 2, 3, 1, 4, 0},
C> { 3, 1, 2, 4, 0},
C> { 1, 3, 2, 4, 0},
C> { 2, 1, 3, 4, 0},
C> { 1, 2, 3, 4, 0},
C> { 4, 3, 2, 0, 1},
C> { 3, 4, 2, 0, 1},
C> { 4, 2, 3, 0, 1},
C> { 2, 4, 3, 0, 1},
C> { 3, 2, 4, 0, 1},
C> { 2, 3, 4, 0, 1},
C> { 4, 3, 0, 2, 1},
C> { 3, 4, 0, 2, 1},
C> { 4, 0, 3, 2, 1},
C> { 0, 4, 3, 2, 1},
C> { 3, 0, 4, 2, 1},
C> { 0, 3, 4, 2, 1},
C> { 4, 2, 0, 3, 1},
C> { 2, 4, 0, 3, 1},
C> { 4, 0, 2, 3, 1},
C> { 0, 4, 2, 3, 1},
C> { 2, 0, 4, 3, 1},
C> { 0, 2, 4, 3, 1},
C> { 3, 2, 0, 4, 1},
C> { 2, 3, 0, 4, 1},
C> { 3, 0, 2, 4, 1},
C> { 0, 3, 2, 4, 1},
C> { 2, 0, 3, 4, 1},
C> { 0, 2, 3, 4, 1},
C> { 4, 3, 1, 0, 2},
C> { 3, 4, 1, 0, 2},
C> { 4, 1, 3, 0, 2},
C> { 1, 4, 3, 0, 2},
C> { 3, 1, 4, 0, 2},
C> { 1, 3, 4, 0, 2},
C> { 4, 3, 0, 1, 2},
C> { 3, 4, 0, 1, 2},
C> { 4, 0, 3, 1, 2},
C> { 0, 4, 3, 1, 2},
C> { 3, 0, 4, 1, 2},
C> { 0, 3, 4, 1, 2},
C> { 4, 1, 0, 3, 2},
C> { 1, 4, 0, 3, 2},
C> { 4, 0, 1, 3, 2},
C> { 0, 4, 1, 3, 2},
C> { 1, 0, 4, 3, 2},
C> { 0, 1, 4, 3, 2},
C> { 3, 1, 0, 4, 2},
C> { 1, 3, 0, 4, 2},
C> { 3, 0, 1, 4, 2},
C> { 0, 3, 1, 4, 2},
C> { 1, 0, 3, 4, 2},
C> { 0, 1, 3, 4, 2},
C> { 4, 2, 1, 0, 3},
C> { 2, 4, 1, 0, 3},
C> { 4, 1, 2, 0, 3},
C> { 1, 4, 2, 0, 3},
C> { 2, 1, 4, 0, 3},
C> { 1, 2, 4, 0, 3},
C> { 4, 2, 0, 1, 3},
C> { 2, 4, 0, 1, 3},
C> { 4, 0, 2, 1, 3},
C> { 0, 4, 2, 1, 3},
C> { 2, 0, 4, 1, 3},
C> { 0, 2, 4, 1, 3},
C> { 4, 1, 0, 2, 3},
C> { 1, 4, 0, 2, 3},
C> { 4, 0, 1, 2, 3},
C> { 0, 4, 1, 2, 3},
C> { 1, 0, 4, 2, 3},
C> { 0, 1, 4, 2, 3},
C> { 2, 1, 0, 4, 3},
C> { 1, 2, 0, 4, 3},
C> { 2, 0, 1, 4, 3},
C> { 0, 2, 1, 4, 3},
C> { 1, 0, 2, 4, 3},
C> { 0, 1, 2, 4, 3},
C> { 3, 2, 1, 0, 4},
C> { 2, 3, 1, 0, 4},
C> { 3, 1, 2, 0, 4},
C> { 1, 3, 2, 0, 4},
C> { 2, 1, 3, 0, 4},
C> { 1, 2, 3, 0, 4},
C> { 3, 2, 0, 1, 4},
C> { 2, 3, 0, 1, 4},
C> { 3, 0, 2, 1, 4},
C> { 0, 3, 2, 1, 4},
C> { 2, 0, 3, 1, 4},
C> { 0, 2, 3, 1, 4},
C> { 3, 1, 0, 2, 4},
C> { 1, 3, 0, 2, 4},
C> { 3, 0, 1, 2, 4},
C> { 0, 3, 1, 2, 4},
C> { 1, 0, 3, 2, 4},
C> { 0, 1, 3, 2, 4},
C> { 2, 1, 0, 3, 4},
C> { 1, 2, 0, 3, 4},
C> { 2, 0, 1, 3, 4},
C> { 0, 2, 1, 3, 4},
C> { 1, 0, 2, 3, 4},
C> { 0, 1, 2, 3, 4}
C> };

D> const(T[][]) permutations(T)(in T[] items) pure nothrow {
D> const(T[])[] result;
D>
D> void perms(in T[] s, in T[] prefix=[]) nothrow {
D> if (s.length)
D> foreach (i, c; s)
D> perms(s[0 .. i] ~ s[i+1 .. $], prefix ~ c);
D> else
D> result ~= prefix;
D> }
D>
D> perms(items);
D> return result;
D> }
...
D> void main() {
D> static immutable permsNumber = permutations([EnumMembers!Number]);
D> static immutable permsColor = cast(immutable(Color[][]))permsNumber;
D> static immutable permsDrink = cast(immutable(Drink[][]))permsNumber;
D> static immutable permsSmoke = cast(immutable(Smoke[][]))permsNumber;
D> static immutable permsPet = cast(immutable(Pet[][]))permsNumber;

Here I have used one of the peculiar features of D, the compile-time function evaluation. The C++ 'perms' array is just an array of all permutations of the [0, 1, 2, 3, 4] numbers. So I have written a little permutations() function (a function as commonly useful as this one, maybe as a lazy range, needs to be present in Phobos. Python has a similar generator in the itertools standard library module) that returns an array of all the permutations.

In D the enums are strongly typed, and the functions of this program work with strongly typed enums to avoid bugs, so I need different permutations of the enum members. Probably a good compiler is able to see all those immutable arrays contain the same bit patterns (despite being of different types), but this program iterates on them many times, so to be sure there is low pressure on the CPU cache, the other arrays are just aliases of the first one. I don't last casts a lot, because they are quite unsafe in D, but here I think they are acceptable.

The D 2D arrays like permsNumber are dynamic arrays of dynamic arrays of 5 enum members, that are represented with ubytes. In the C++ code perms is an array of fixed-sized arrays, this gives a bit higher performance to the C++ code. I have created another D version that solves this problem, but needs to use the arrays in a not D idiomatic way, see below.

----------------------------------------------

C> char
C> possible(char *number, char *colour, char* drink, char *smoke, char *pet)
C> {
C> // Rules, with the rule number as a comment
C>
C> // single property rules
C> if(number != NULL && number[Norvegian] != One) // 9
C> return FALSE;
C> if(colour != NULL && colour[British] != Red) // 1
C> return FALSE;
C> if(drink != NULL && drink[Danish] != Tea) // 3
C> return FALSE;
C> if(smoke != NULL && smoke[German] != Prince) // 13
C> return FALSE;
C> if(pet != NULL && pet[Swedish] != Dog) // 2
C> return FALSE;

D> bool isPossible(in Number[] number, in Color[] color, in Drink[] drink,
D> in Smoke[] smoke, in Pet[] pet) pure nothrow {
D> // Rules, with the rule number as a comment
D>
D> // single property rules
D> if (!number.empty && number[Nation.Norvegian] != Number.One) // 9
D> return false;
D> if (!color.empty && color[Nation.British] != Color.Red) // 1
D> return false;
D> if (!drink.empty && drink[Nation.Danish] != Drink.Tea) // 3
D> return false;
D> if (!smoke.empty && smoke[Nation.German] != Smoke.Prince) // 13
D> return false;
D> if (!pet.empty && pet[Nation.Swedish] != Pet.Dog) // 2
D> return false;

Here the stronger typing of the D enums allows to write safer code, with less chance for bugs.

Generally the D function uses const/immutable/pure/nothrow everywhere it's possible, this gives performance and safety.

==========================================

Comments on the second program, second version (einstein2b.d):

This is very similar to einstein2a.d, the main difference comes from the desire to increase the performance avoiding one pointer level using fixed-size arrays to represent the is various permutations.


D> import std.stdio, std.math, std.traits, std.array, std.conv;
D>
D>
D> const(T[N][]) permutationsFixed(T, size_t N)(in T[N] items) pure nothrow {
D> const(T[N])[] result;
D> T[N] row;
D>
D> void perms(in T[] s, in T[] prefix=[]) nothrow {
D> if (s.length)
D> foreach (i, c; s)
D> perms(s[0 .. i] ~ s[i+1 .. $], prefix ~ c);
D> else {
D> row[] = prefix[];
D> result ~= row;
D> }
D> }
D>
D> perms(items);
D> return result;
D> }

The permutationsFixed() function returns an dynamic array of fixed size arrays.

----------------------------------------------
D> enum Number : uint { One,      Two,     Three,  Four,       Five   };
D> enum Color : uint { Red, Green, Blue, White, Yellow };
D> enum Drink : uint { Milk, Coffee, Water, Beer, Tea };
D> enum Smoke : uint { PallMall, Dunhill, Blend, BlueMaster, Prince };
D> enum Pet : uint { Dog, Cat, Fish, Horse, Bird };
D> enum Nation : uint { British, Swedish, Danish, Norvegian, German };

The enums have uint as base type because it's about or more efficient than ubytes, in this program.

----------------------------------------------

D> bool isPossible(immutable(Number[5])* number,
D> immutable(Color[5])* color,
D> immutable(Drink[5])* drink,
D> immutable(Smoke[5])* smoke,
D> immutable(Pet[5])* pet
D> ) pure nothrow {
D> // Rules, with the rule number as a comment
D>
D> // single property rules
D> if (number && (*number)[Nation.Norvegian] != Number.One) // 9
D> return false;
D> if (color && (*color)[Nation.British] != Color.Red) // 1
D> return false;
D> if (drink && (*drink)[Nation.Danish] != Drink.Tea) // 3
D> return false;
D> if (smoke && (*smoke)[Nation.German] != Smoke.Prince) // 13
D> return false;
D> if (pet && (*pet)[Nation.Swedish] != Pet.Dog) // 2
D> return false;
D>
D> // only check complicated rules, if everything is defined
D> if (!number || !color || !drink || !smoke || !pet)
D> return true;
D>
D> // double property rules
D> foreach (i; 0 .. 5) {
D> if ((*color)[i] == Color.Green && (*drink)[i] != Drink.Coffee) // 5
D> return false;
D> if ((*smoke)[i] == Smoke.PallMall && (*pet)[i] != Pet.Bird) // 6
D> return false;
...
D> void main() {
...
D> foreach (ref number; permsNumber)
D> if (isPossible(&number, null, null, null, null))
D> foreach (ref color; permsColor)
D> if (isPossible(&number, &color, null, null, null))

Normally in D you pass static arrays efficiently using "const ref T[N]", but in this program also nulls must be supported. So I have had to perform some experiments to find a flexible enough but efficient way to give them to the isPossible() function.

So I pass them as pointers to immutable fixed size arrays:

D>                 immutable(Color[5])* color,

They are pointers to arrays (so they are like C/C++/D1 fixed size arrays), so they are efficient, despite this is a not idiomatic way to use arrays in D.

To use the array items you need to deference the pointer first:

(*color)[i]

An alternative syntax, but it's less natural because the first isn't really an array of size 1, it's a pointer to an array:

color[0][i]
==========================================
Some benchmarks:

Runtime timings, seconds:
  einstein1.cpp:  0.01
  einstein1a.d:   0.05
  einstein2.cpp:  0.70
  einstein2a.d:   1.09
  einstein2b.d:   0.76
  einstein2c.py: 19.03 (with Psyco)
DMD 2.057 head

G++ 4.6.1
Python 2.6.6

Celeron 2.3 GHz, 32 bit OS.

----------------------------------------------

Strong static typing is useful, but it often also requires lot of work. In practical D programs I try to find a balance point in the amount of strong static typing I use, to avoid wasting some of my time. Yet, as I get more experienced in programming, I like to express more and more code invariants in statically enforced constraints, like the ones of a static type system, because despite they ask me lot of work, they help me avoid some bugs.

So "Make illegal states unrepresentable", as it's said here regarding OCaML code:
http://ocaml.janestreet.com/?q=node/85

So write your code to turn the illegal states into static errors.

comments: Leave a comment Add to Memories Share

Tags:,
Security:
Subject:Bluespark
Time:12:53 am
Second version of my ponysona, Bluespark, a teenager pegasus pony. His mane colors will probably change a bit still (swap of the yellow and light blue of the mane and tail), image by Scale:


Bluespark image by Gilda/Gilden/Sans Souci:


Bluespark lacks the cutie mark still, despite his age, because he changes his activities often. Eventually he will gain this cutie mark, this is the first version. This cutie mark shows that he appreciates, studies and he will be good in managing lighthing sparks. The red column over the cloud is a Red_sprite:


All the images are here, at the bottom of the page, there is a first version too of Bluespark:
http://www.fantascienza.net/leonardo/im/index.html
comments: 2 comments or Leave a comment Add to Memories Share

Tags:, , ,
Security:
Subject:Updates and links
Time:12:57 am
K-means++ in D:
http://www.fantascienza.net/leonardo/js/index.html#kmeanspp

---------------------

kinectfusion, realtime 3D surface reconstruction and interaction, 3D data from Kinect:
http://www.youtube.com/watch?v=quGhaggn3cQ

Prescient but Not Perfect: A Look Back at a 1966 Scientific American Article on Systems Analysis, by Peter Norvig:
http://blogs.scientificamerican.com/at-scientific-american/2011/08/23/systems-analysis-look-back-1966-scientific-american-article/

Debugger Canvas, by Microsoft:
http://www.youtube.com/watch?v=3p9XUwIlhJg

All MCmicrocomputer, for free, it contains lot of stuff:
http://issuu.com/adpware/docs

What does it feel like to fly over planet Earth? We'll see this in movies too:
http://www.youtube.com/watch?&v=74mhQyuyELQ

Intro to Scala:
http://twitter.github.com/scala_school/ 

Very good intro to labirithm creation algorithms:
http://www.jamisbuck.org/presentations/rubyconf2011/index.html

Some free slides from a F# book:
http://fsharpgamedev.codeplex.com/releases/view/74008

---------------------

Luna's lament (a fan-made cartoon with ponies):
http://www.youtube.com/watch?v=TkpRUhdVNmU
comments: Leave a comment Add to Memories Share

Tags:, , , ,
Security:
Subject:Ant Puzzle solutions
Time:05:44 pm
A simple problem found here, "F# for python programmers", from page 42:
http://combiol.org/fs/FSUG_FS4PPv2.pptx

Ant puzzle:
There is an ant which can walk around on a planar grid. The ant can move one space at a time left, right, up or down. That is, from (x, y) the ant can go to (x+1, y), (x-1, y), (x, y+1), and (x, y-1).

Points where the sum of the digits of the x coordinate plus the sum of the digits of the y coordinate are greater than 25 are inaccessible to the ant. For example, the point (59,79) is inaccessible because 5 + 9 + 7 + 9 = 30, which is greater than 25.

How many points can the ant access if it starts at (1000, 1000), including (1000, 1000) itself?

The author compares a Python2 solution with a F# solution (with the idea that the F# is better), the solutions offered (sorry, no text here, just images):





In a successive slide it shows that the Python implementation returns the correct result (148848) in about 12.4 seconds, but only on certain compuer, while on another one it produces a stack overflow, while the F# version returns the correct result in 5.8 seconds (and only one machine is tested).

I don't know enough about F# to comment, but that Python solution is just bad. This was my first python version, and it has given the right result on the first try:
from collections import deque
import psyco; psyco.full()

def sum_digits(n):
    tot = 0
    while n:
        tot += n % 10
        n //= 10
    return tot

def ant():
    seen = set()
    count = 0
    stack = deque([(1000, 1000)])

    while stack:
        p = stack.pop()
        if p not in seen:
            seen.add(p)
            x, y = p
            if sum_digits(x) + sum_digits(y) <= 25:
                count += 1
                stack.append((x+1, y  ))
                stack.append((x-1, y  ))
                stack.append((x,   y+1))
                stack.append((x,   y-1))

    return count

print ant()

It gives no stack overflows, and on my oldish PC (Celeron 2.3 GHz, Python v2.6.6) runs in about 0.56 seconds (more than ten times faster than the F# version that maybe runs on a faster PC), without Psyco it runs in about 1.28 seconds. And in my opinion its code is simpler than the F# version.

In the standard library of the D language there is no stack data structure yet, so I have used recursion (and there is no hash set yet, so I have used a built-in hash map), this is a basic version, similar to the first one I have written:
import std.stdio;

struct P { int x, y; }

int sumDigits(int n) {
    int sum = 0;
    while (n) {
        sum += n % 10;
        n /= 10;
    }
    return sum;
}

uint[P] seen;
size_t count;

void walk(P p) {
    if (p !in seen) {
        seen[p] = 0;
        if (sumDigits(p.x) + sumDigits(p.y) <= 25) {
            count++;
            walk(P(p.x+1, p.y));
            walk(P(p.x-1, p.y));
            walk(P(p.x, p.y+1));
            walk(P(p.x, p.y-1));
        }
    }
}

void main() {
    walk(P(1000, 1000));
    writeln(count);
}

It runs in about 0.27 seconds if I compile it with (DMD 2.055):
dmd -L/STACK:1000000 -O -release -inline ant_puzzle1_d.d

This is a faster D version (0.20 seconds run time), but it cheats a little because it knows the max size of the stack (but I think a dynamic stack implemented with a deque, is not much slower than this, even if it doesn't use a region allocator):

import std.stdio, std.typetuple;

size_t ant() pure nothrow {
    static int sumDigits(int n) pure nothrow {
        int sum = 0;
        while (n) {
            sum += n % 10;
            n /= 10;
        }
        return sum;
    }

    static struct P { short x, y; }

    // This speeds up the hashing...
    static uint mapP(in P p) pure nothrow {
        return (p.x << 16) + p.y;
    }

    uint[uint] seen;
    size_t count;

    P[44_000] stack = void;
    size_t stackLen;

    stack[stackLen] = P(1000, 1000);
    stackLen++;

    while (stackLen) {
        immutable P p = stack[stackLen - 1];
        stackLen--;
        if (mapP(p) !in seen) {
            seen[mapP(p)] = 0;
            if (sumDigits(p.x) + sumDigits(p.y) <= 25) {
                count++;
                foreach (s; TypeTuple!(P(1,0), P(-1,0), P(0,1), P(0,-1))) {
                    stack[stackLen] = P(cast(short)(p.x+s.x), cast(short)(p.y+s.y));
                    stackLen++;
                }
            }
        }
    }

    return count;
}

void main() {
    writeln(ant());
}


A C++0x translation, it uses a dynamic stack:
#include <stdio.h>
#include <stdint.h>
#include <stack>
#include <boost/unordered_set.hpp>

using namespace std;

inline int sum_digits(int n) {
    int sum = 0;
    while (n) {
        sum += n % 10;
        n /= 10;
    }
    return sum;
}

struct P { int16_t x, y; };

inline uint32_t map_p(const P p) {
    return (p.x << 16) + p.y;
}

size_t ant() {
    size_t count = 0;
    boost::unordered_set<uint32_t> seen;
    stack

mystack; mystack.push({1000, 1000}); while (!mystack.empty()) { const P p = mystack.top(); mystack.pop(); if (seen.find(map_p(p)) == seen.end()) { seen.insert(map_p(p)); if (sum_digits(p.x) + sum_digits(p.y) <= 25) { count++; mystack.push({ (int16_t)(p.x + 1), p.y }); mystack.push({ (int16_t)(p.x - 1), p.y }); mystack.push({ p.x, (int16_t)(p.y + 1) }); mystack.push({ p.x, (int16_t)(p.y - 1) }); } } } return count; } int main() { printf("%u\n", ant()); return 0; }


Its runtime is 0.12 seconds if I compile it with G++ 4.6.1 like this:
g++ -std=c++0x -Wall -Wextra -s -Ofast ant_puzzle_cpp.cpp -o ant_puzzle_cpp

All the code shown here:
http://www.fantascienza.net/leonardo/js/ant_puzzle.zip
comments: 7 comments or Leave a comment Add to Memories Share

leonardo
View:Recent Entries.
View:Archive.
View:Friends.
View:User Info.
View:Website (My Website).
You're looking at the latest 10 entries.
Missed some entries? Then simply jump back 10 entries