Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: My first cpan module - App::ForKids::LogicalPuzzleGenerator

by choroba (Cardinal)
on Feb 23, 2018 at 21:56 UTC ( [id://1209865]=note: print w/replies, xml ) Need Help??


in reply to My first cpan module - App::ForKids::LogicalPuzzleGenerator

I know it as Einstein's Puzzle and one of its charms is that you don't name the full sets, so the question sounds like a joke to an unprepared:

Three friends live here. Each likes a different fruit and has a different profession.
John doesn't like pears. The programmer likes cherries. Patrick is a blacksmith. Edward isn't a fisherman.
Who likes apples?

($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

Replies are listed 'Best First'.
Re^2: My first cpan module - App::ForKids::LogicalPuzzleGenerator
by tybalt89 (Monsignor) on Feb 24, 2018 at 15:46 UTC

    That was fun! Thanks.

    #!/usr/bin/perl -l # http://perlmonks.org/?node_id=1209857 use strict; use warnings; $_ = <<END; # starting conditions John apples,cherries,pears blacksmith,fisherman,programmer Patrick apples,cherries,pears blacksmith,fisherman,programmer Edward apples,cherries,pears blacksmith,fisherman,programmer END my $prev; do { print; $prev = $_; s/^John \S*\Kpears//m; # John doesn't like pears s/^Patrick \S+ \K\S+/blacksmith/m; # Patrick is a blacksmith s/^Edward \S+ \S*\Kfisherman//m; # Edward isn't a fisherman s/\S+(?= programmer$)/cherries/m; # The programmer likes cherries s/,+\K,|\B,+|,+\B//g; # cleanup extra commas for my $col (1 .. tr/ // / tr/\n// ) # for each column { for my $one ( /^(?:\S+ ){$col}(\w+)\s/gm ) # find each single one { s/^(?:\S+ ){$col}(?:\K$one,|\S+\K,$one\b)//gm; # delete in other + rows } } } until $_ eq $prev;

    Outputs:

    John apples,cherries,pears blacksmith,fisherman,programmer Patrick apples,cherries,pears blacksmith,fisherman,programmer Edward apples,cherries,pears blacksmith,fisherman,programmer John apples,cherries fisherman,programmer Patrick apples,cherries,pears blacksmith Edward apples,cherries,pears programmer John apples fisherman Patrick apples,pears blacksmith Edward cherries programmer John apples fisherman Patrick pears blacksmith Edward cherries programmer
      Choroba's Version of the Zebra puzzle was very easy.

      For real "fun" try to solve this one with regexes

      The following version of the puzzle appeared in Life International in 1962:
      • There are five houses.
      • The Englishman lives in the red house.
      • The Spaniard owns the dog.
      • Coffee is drunk in the green house.
      • The Ukrainian drinks tea.
      • The green house is immediately to the right of the ivory house.
      • The Old Gold smoker owns snails.
      • Kools are smoked in the yellow house.
      • Milk is drunk in the middle house.
      • The Norwegian lives in the first house.
      • The man who smokes Chesterfields lives in the house next to the man with the fox.
      • Kools are smoked in the house next to the house where the horse is kept.
      • The Lucky Strike smoker drinks orange juice.
      • The Japanese smokes Parliaments.
      • The Norwegian lives next to the blue house.
      update

      Now, who drinks water? Who owns the zebra?

      In the interest of clarity, it must be added that each of the five houses is painted a different color, and their inhabitants are of different national extractions, own different pets, drink different beverages and smoke different brands of American cigarets sic. One other thing: in statement 6, right means your right.

      — Life International, December 17, 1962

      update end

      At some point you will need a branch and bound algorithm here, maybe by exploiting the backtracking of the regex engine.

      Good fun! ;)

      Extra motivation: you can add your potential regex solution to Rosetta code then.

      Cheers Rolf
      (addicted to the Perl Programming Language and ☆☆☆☆ :)
      Wikisyntax for the Monastery

        That was fun :) Thanks!

        #!/usr/bin/perl -l # http://perlmonks.org/?node_id=1209931 use strict; use warnings; # columns # 0 house number left to right # 1 colors # 2 pets (only 4 mentioned, 5th called 'spot') # 3 drink (only 4 mentioned, 5th called 'drink') # 4 nationality # 5 smokes $_ = <<END; # starting configuration 1 blue,red,green,ivory,yellow dog,snails,fox,horse,spot coffee,tea,mil +k,orangejuice,drink Englishman,Spaniard,Ukrainian,Japanese,Norwegian +OldGold,Kools,Chesterfields,LuckyStrike,Parliaments 2 blue,red,green,ivory,yellow dog,snails,fox,horse,spot coffee,tea,mil +k,orangejuice,drink Englishman,Spaniard,Ukrainian,Japanese,Norwegian +OldGold,Kools,Chesterfields,LuckyStrike,Parliaments 3 blue,red,green,ivory,yellow dog,snails,fox,horse,spot coffee,tea,mil +k,orangejuice,drink Englishman,Spaniard,Ukrainian,Japanese,Norwegian +OldGold,Kools,Chesterfields,LuckyStrike,Parliaments 4 blue,red,green,ivory,yellow dog,snails,fox,horse,spot coffee,tea,mil +k,orangejuice,drink Englishman,Spaniard,Ukrainian,Japanese,Norwegian +OldGold,Kools,Chesterfields,LuckyStrike,Parliaments 5 blue,red,green,ivory,yellow dog,snails,fox,horse,spot coffee,tea,mil +k,orangejuice,drink Englishman,Spaniard,Ukrainian,Japanese,Norwegian +OldGold,Kools,Chesterfields,LuckyStrike,Parliaments END my @stack = $_; while( $_ = pop @stack ) { my $prev; do { #print; $prev = $_; # The Englishman lives in the red house. s/ \K\S*red\S*(?= (\S+ ){2}Englishman )/red/; s/ red (\S+ ){2}\K\S*Englishman\S*/Englishman/; / red .* (Norwegian|Spaniard|Japanese|Ukrainian) / and next; / (blue|ivory|green|yellow) .* Englishman / and next; # The Spaniard owns the dog. s/ \K\S*dog\S*(?= \S+ Spaniard )/dog/; s/ dog \S+ \K\S*Spaniard\S*/Spaniard/; / dog .* (Norwegian|Japanese|Englishman|Ukrainian) / and next; / (horse|snails|fox|spot) .* Spaniard / and next; # Coffee is drunk in the green house. s/ green \S+ \K\S*coffee\S*/coffee/; s/ \K\S*green\S*(?= \S+ coffee )/green/; / green .* (drink|orangejuice|milk|tea) / and next; / (red|blue|ivory|yellow) .* coffee / and next; # The Ukrainian drinks tea. s/ \K\S*tea\S*(?= Ukrainian )/tea/; s/ tea \K\S*Ukrainian\S*/Ukrainian/; / tea (Norwegian|Spaniard|Japanese|Englishman) / and next; / (drink|orangejuice|milk|coffee) Ukrainian / and next; # The green house is immediately to the right of the ivory house. s/1 \K(green,|,green)//; s/5 .*\K(ivory,|,ivory)//; s/ ivory .*\n\d \K\S*green\S*/green/; s/ \K\S*ivory\S*(?= .*\n.* green )/ivory/; / ivory (.*\n){2,}.* green / and next; / green (.*\n)+.* ivory / and next; # The Old Gold smoker owns snails. s/ \K\S*snails\S*(?= (\S+ ){2}OldGold\s)/snails/; s/ snails (\S+ ){2}\K\S*OldGold\S*/OldGold/; / snails .* (LuckyStrike|Parliaments|Chesterfields|Kools)\s/ and n +ext; / (dog|fox|house|spot) .* OldGold\s/ and next; # Kools are smoked in the yellow house. s/ yellow (\S+ ){3}\K\S*Kools\S*/Kools/; s/ \K\S*yellow\S*(?= (\S+ ){3}Kools\s)/yellow/; / yellow ,* (LuckyStrike|Parliaments|Chesterfields|Kools)\s/ and n +ext; / (red|blue|ivory|green) .* Kools\s/ and next; # Milk is drunk in the middle house. s/3 (\S+ ){2}\K\S*milk\S*/milk/; # The Norwegian lives in the first house. s/1 (\S+ ){3}\K\S*Norwegian\S*/Norwegian/; # The man who smokes Chesterfields lives in the house next to the man +with the fox. s/1 .* fox .*\n(\S+ ){5}\K\S*Chesterfields\S*/Chesterfields/; s/ \K\S*fox\S*(?= .*\n5 .* Chesterfields\n)/fox/; s/ (dog,horse,snails,spot) .*\n.* Chesterfields\n.* \K\S*fox\S*/fo +x/; s/ \K\S*fox\s*(?= .*\n.* Chesterfields\n.* (dog,horse,snails,spot) + )/fox/; / fox .* Chesterfields\s/ and next; / fox (.*\n){2,}.* Chesterfields\s/ and next; / Chesterfields\n(.*\n)+.* fox / and next; # Kools are smoked in the house next to the house where the horse is k +ept. s/1 .* Kools\n(\S+ ){2}\K\S*horse\S*/horse/; s/ \K\S*horse\S*(?= .*\n5 .* Kools\n)/horse/; / horse .* Kools\s/ and next; / horse (.*\n){2,}.* Kools\s/ and next; / Kools\n(.*\n)+.* horse / and next; # The Lucky Strike smoker drinks orange juice. s/ orangejuice \S+ \K\S*LuckyStrike\S*/LuckyStrike/; s/ \K\S*orangejuice\S*(?= \S+ LuckyStrike\s)/orangejuice/; / orangejuice .* (OldGold|Parliaments|Chesterfields|Kools)\s/ and +next; / (drink|milk|coffee|tea) .* .LuckyStrike\s/ and next; # The Japanese smokes Parliaments. s/ Japanese \K\S*Parliaments\S*/Parliaments/; s/ \K\S*Japanese\S*(?= Parliaments\s)/Japanese/; / Japanese (OldGold|LuckyStrike|Chesterfields|Kools)\s/ and next; / (Norwegian|Spaniard|Englishman|Ukrainian) Parliaments\s/ and nex +t; # The Norwegian lives next to the blue house. s/1 .* Norwegian .*\n\d \K\S+/blue/; s/ \K\S*blue\s*(?= .*\n5 .* Norwegian .*\n)/blue/; / blue .* Norwegian / and next; / blue (.*\n)+.* Norwegian / and next; / Norwegian (.*\n){2,}.* blue / and next; for my $col (1 .. tr/ // / tr/\n// ) # for each column { for my $cell ( /^(?:\S+ ){$col}(\w+)\s/gm ) # find each single c +ell { s/^(?:\S+ ){$col}(?:\K$cell,|\S+\K,$cell\b)//gm; # delete in o +ther rows } } } until $_ eq $prev; if( /\S+,\S+/ ) # if some cell has a comma, fork (sort of) { push @stack, $` . $_ . $' for split /,/, $&; } else { print "Solution:\n\n$_"; exit; } }

        Outputs:

        Solution: 1 yellow fox drink Norwegian Kools 2 blue horse tea Ukrainian Chesterfields 3 red snails milk Englishman OldGold 4 ivory dog orangejuice Spaniard LuckyStrike 5 green spot coffee Japanese Parliaments

        The s/// are logical cell fillers.
        The // and next are validation.

        Update

        s/spot/zebra/; s/drink/water/;
Re^2: My first cpan module - App::ForKids::LogicalPuzzleGenerator
by LanX (Saint) on Feb 24, 2018 at 16:43 UTC
    testing if my approach also works here ...

    The difference is that you have positive clauses like The programmer likes cherries , which result in 12 zeroes instead of only 3:

    • 6 for (programmer)x(apples,pears)
    • 6 for (blacksmith,fisherman) x (cherries)

    That's why you fewer clauses than the OP to be decisive.

    Applying all clauses:

    FRUITS PROFESSIONS NAMES P B F cherries . 0 0 apples 0 0 . John pears 0 0 0 cherries 0 0 0 apples 0 . 0 Patrick pears 0 . 0 cherries . 0 0 apples 0 0 0 Edward pears 0 0 0
    • => (Edward,programmer,cherries)
    • => (fisherman,John, apples)
    • excluding other possibilities
    FRUITS PROFESSIONS NAMES P B F cherries 0 0 0 apples 0 0 1 John pears 0 0 0 cherries 0 0 0 apples 0 0 0 Patrick pears 0 . 0 cherries 1 0 0 apples 0 0 0 Edward pears 0 0 0
    • => (Patrick, blacksmith, pears)

    I'd say a bit too easy. :)

    But I think it's obvious now how we could use this "hyper-cube" solver for creating riddles in low dimensions.

    update

    Though I'm not sure if a "solvable" riddle (i.e. only one solution possible) is always as obvious as the examples given so far.

    For instance what if every cut has at least 2 undefined points, such that the first step is not obvious.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Wikisyntax for the Monastery

    update

    This riddle is even easier and already solved right away without eliminations. since there is only one possibility for pears after initially filling the matrix.

Re^2: My first cpan module - App::ForKids::LogicalPuzzleGenerator
by pawel.biernacki (Acolyte) on Feb 23, 2018 at 22:09 UTC

    I am pretty sure there is a solver for such puzzles in CPAN. But I do not remember its name.

    Pawel Biernacki
Re^2: My first cpan module - App::ForKids::LogicalPuzzleGenerator
by LanX (Saint) on Feb 24, 2018 at 17:03 UTC
    > I know it as Einstein's Puzzle

    But the constraints in an Einstein or Zebra puzzle have an additional quality of order!

    like: "John lives in the house right of the blacksmith."

    or

    "The Blend smoker has a neighbour who keeps cats."

    update

    For instance, I can't encode this last one in a hyper-cube, if there are 2 neighbours!

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Wikisyntax for the Monastery

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1209865]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2024-04-19 01:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found