Zebra puzzle: Difference between revisions
Content added Content deleted
(add mercury) |
(→{{header|Raku}}: Make use of temp over clone. Variable renaming.) |
||
Line 6,060: | Line 6,060: | ||
for gather solve(@houses, @facts) { |
for gather solve(@houses, @facts) { |
||
#-- output |
#-- output |
||
say . |
say .head.sort.map(*.key.uc.fmt("%-9s")).join(' | '); |
||
say |
say .sort.map(*.value.fmt("%-9s")).join(' | ') |
||
for .list; |
for .list; |
||
last; # stop after first solution |
last; # stop after first solution |
||
Line 6,067: | Line 6,067: | ||
} |
} |
||
#| |
#| a solution has been found that fits all the facts |
||
multi sub solve(@solution, @facts [ ]) { |
multi sub solve(@solution, @facts [ ]) { |
||
take @solution; |
take @solution; |
||
} |
} |
||
#| extend |
#| extend this scenario to fit the next fact |
||
multi sub solve(@scenario, [ $fact, *@facts ] is copy) { |
multi sub solve(@scenario, [ $fact, *@facts ] is copy) { |
||
for gather |
for gather suppose(@scenario, |$fact) -> @houses { |
||
solve(@ |
solve(@houses, @facts) |
||
} |
} |
||
} |
} |
||
#| find all possible solutions for pairs of houses with |
#| find all possible solutions for pairs of houses with |
||
#| %a |
#| lemma %a, left of a house with lemma %b |
||
multi sub |
multi sub suppose(@houses, :Left-Of(%b)!, *%a) { |
||
for @houses { |
for @houses { |
||
my $idx = .<num> - 1; |
my $idx = .<num> - 1; |
||
if $idx > 0 && plausible(@houses[$idx-1], %a) && plausible(@houses[$idx], %b) { |
if $idx > 0 && plausible(@houses[$idx-1], %a) && plausible(@houses[$idx], %b) { |
||
temp @houses[$idx-1].Hash ,= %a; |
|||
temp @houses[$idx].Hash ,= %b; |
|||
take @houses; |
|||
take @scenario; |
|||
} |
} |
||
} |
} |
||
} |
} |
||
#| suppose these houses are next to each other (left or right) |
|||
#| find all possible pairs of houses with %a attributes, either side |
|||
multi sub suppose(@houses, :Next-To(%b)!, *%a ) { |
|||
#! of a house with %b attributes |
|||
suppose(@houses, |%a, :Left-Of(%b) ); |
|||
suppose(@houses, |%b, :Left-Of(%a) ); |
|||
choices(@houses, |%b, :Left-Of(%a) ); |
|||
} |
} |
||
#| find all possible houses that match the given attributes |
#| find all possible houses that match the given attributes |
||
multi sub |
multi sub suppose(@houses, *%lemma) { |
||
for @houses.grep({plausible($_, % |
for @houses.grep({plausible($_, %lemma)}) -> $house { |
||
my @scenario = @houses.clone; |
|||
my $idx = $house<num> - 1; |
my $idx = $house<num> - 1; |
||
@ |
temp @houses[$idx] = %( %$house, %lemma ); |
||
take @ |
take @houses; |
||
} |
} |
||
} |
} |
||
#| plausible if doesn't conflict with anything |
#| plausible if doesn't conflict with anything |
||
sub plausible(%house, % |
sub plausible(%house, %lemma) { |
||
! %lemma.first: {%house{.key} && %house{.key} ne .value }; |
|||
} |
} |
||
</lang> |
</lang> |