The problem can be solved by computer with some backtracking, or by hand with some thought. Being a Perl programmer, I naturally thought to golf it, and thought that the best solution would involve a clever regex or substitution. Here's a terse, but un-obfuscated version:
And here's the output, where "b", "c", "g", and "w" represent the boat, cabbage, goat, and wolf being on the right bank:sub wgc { return if $seen{"@_"}++; my%x=@_; if ($x{b} && $x{c} && $x{g} && $x{w}) { print+(sort keys%$_),"\n" for @h; exit; } elsif ((!$x{b} && ($x{c} && $x{g} || $x{g} && $x{w})) || ($x{b} && (!$x{c} && !$x{g} || !$x{g} && !$x{w}))) { return; } else { if ($x{b}) { delete $x{b}; for ('xx', keys %x) { my %y=%x; delete $y{$_}; local @h=(@h, \%y); wgc(%y); } } else { $x{b}=1; { local (@h) = (@h, \%x); wgc(%x); } for my $k (qw(c g w)) { if (!$x{$k}) { my %y=(%x,$k,1); local (@h) = (@h, \%y); wgc(%y); }; } } } } wgc
I wasn't clever enough to come up with the regex solution, but here's a compressed version of the above, weighing in atbg g bcg c bcw cw bcgw
Have at it!sub w{return if$s{"@_"}++;my%x=@_;if($x{b}&$x{c}&$x{g}&$x{w}){print+(s +ort keys%$_),"\n"for@h;exit;}elsif(($x{b}||!($x{c}&&$x{g}||$x{g}&&$x{ +w}))&&(!$x{b}||!(!$x{c}&&!$x{g}||!$x{g}&&!$x{w}))){if($x{b}){delete$x +{b};for(A,keys%x){my%y=%x;delete$y{$_};local@h=(@h,\%y);w(%y)}}else{$ +x{b}=1;{local@h=(@h,\%x);w(%x);}for(qw(c g w)){if(!$x{$_}){my%y=(%x,$ +_,1);local@h=(@h,\%y);w(%y)}}}}}w
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Golf: Cabbage, Goat, Wolf
by tobyink (Canon) on Dec 28, 2013 at 17:25 UTC | |
Re: Golf: Cabbage, Goat, Wolf
by Athanasius (Archbishop) on Jan 06, 2014 at 02:06 UTC | |
Re: Golf: Cabbage, Goat, Wolf
by hdb (Monsignor) on Jan 06, 2014 at 16:02 UTC | |
by educated_foo (Vicar) on Jan 07, 2014 at 02:07 UTC | |
by hdb (Monsignor) on Jan 07, 2014 at 14:19 UTC | |
by educated_foo (Vicar) on Jan 08, 2014 at 01:12 UTC | |
by hdb (Monsignor) on Jan 08, 2014 at 15:13 UTC |