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
In reply to Golf: Cabbage, Goat, Wolf by educated_foo
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |