Last active
August 29, 2015 14:02
-
-
Save logicchains/2442dfca5d517f1e4bab to your computer and use it in GitHub Desktop.
D language implementation of magic forest problem from http://unriskinsight.blogspot.com.au/2014/06/fast-functional-goats-lions-and-wolves.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.algorithm; | |
import std.conv; | |
import std.stdio; | |
import std.array; | |
import std.range; | |
import std.format; | |
//Compile with ldc2 -O5 -release -disable-boundscheck MagicForest.d | |
struct forest_t{ | |
int goats; | |
int wolves; | |
int lions; | |
forest_t opBinary(string op)(forest_t rhs) pure nothrow if (op == "+") { | |
return forest_t(goats+rhs.goats, wolves+rhs.wolves, lions+rhs.lions); | |
} | |
} | |
void printForest(forest_t forest) { | |
writefln("Forest [goats= %d, wolves= %d, lions= %d]", forest.goats, forest.lions, forest.wolves); | |
} | |
bool forest_stable(in immutable forest_t forest) pure nothrow { | |
if (forest.goats == 0) return (forest.wolves == 0) || (forest.lions == 0); | |
return (forest.wolves == 0) && (forest.lions == 0); | |
} | |
bool forest_invalid(in immutable forest_t forest) pure nothrow{ | |
return (forest.goats < 0 || forest.wolves < 0 || forest.lions < 0); | |
} | |
forest_t[] meal(forest_t[] forests) { | |
// auto tst = only("1", "2", "3"); | |
return map!(a => [forest_t(-1, -1, +1)+a, forest_t(-1, +1, -1)+a, forest_t(+1, -1, -1)+a])(forests) | |
.join | |
.partition!(forest_invalid) | |
.sort.uniq.array; | |
} | |
bool devouring_possible(in forest_t[] forests) pure nothrow { | |
return !forests.empty() && !any!forest_stable(forests); | |
} | |
forest_t[] stable_forests(forest_t[] forests) { | |
return filter!(a => forest_stable(a))(forests).array; | |
} | |
forest_t[] find_stable_forests(in forest_t forest){ | |
forest_t[] forests = [forest]; | |
while(devouring_possible(forests)){ | |
forests = meal(forests); | |
} | |
return stable_forests(forests); | |
} | |
void main(string[] args){ | |
if(args.length != 4){ | |
writeln("Error: input must be three values; <goats> <wolves> <lions>"); | |
return; | |
} | |
immutable forest_t initialForest = {to!int(args[1]), to!int(args[2]), to!int(args[3])}; | |
forest_t[] stableForests = find_stable_forests(initialForest);; | |
if (stableForests.empty()) { | |
"No stable forests found.".writeln; | |
} | |
else { | |
foreach(forest; stableForests){ | |
printForest(forest); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment