<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
		>
<channel>
	<title>Comments on: Who Owns The Zebra?</title>
	<atom:link href="http://programmingpraxis.com/2009/06/16/who-owns-the-zebra/feed/" rel="self" type="application/rss+xml" />
	<link>http://programmingpraxis.com/2009/06/16/who-owns-the-zebra/</link>
	<description>A collection of etudes, updated weekly, for the education and enjoyment of the savvy programmer</description>
	<lastBuildDate>Mon, 28 May 2012 03:30:45 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
	<item>
		<title>By: RFH</title>
		<link>http://programmingpraxis.com/2009/06/16/who-owns-the-zebra/#comment-200</link>
		<dc:creator><![CDATA[RFH]]></dc:creator>
		<pubDate>Tue, 23 Jun 2009 16:47:35 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=754#comment-200</guid>
		<description><![CDATA[Here&#039;s the pastebin:

http://pastebin.com/f41c6cbf8]]></description>
		<content:encoded><![CDATA[<p>Here&#8217;s the pastebin:</p>
<p><a href="http://pastebin.com/f41c6cbf8" rel="nofollow">http://pastebin.com/f41c6cbf8</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: RFH</title>
		<link>http://programmingpraxis.com/2009/06/16/who-owns-the-zebra/#comment-199</link>
		<dc:creator><![CDATA[RFH]]></dc:creator>
		<pubDate>Tue, 23 Jun 2009 16:46:27 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=754#comment-199</guid>
		<description><![CDATA[One I did in Python 3.0.1, using the stadard library&#039;s itertools module for the permutations:

&lt;a href=&quot;//pastebin.com/f41c6cbf8”&quot; rel=&quot;nofollow&quot;&gt;]]></description>
		<content:encoded><![CDATA[<p>One I did in Python 3.0.1, using the stadard library&#8217;s itertools module for the permutations:</p>
<p><a href="//pastebin.com/f41c6cbf8”" rel="nofollow"></a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Remco Niemeijer</title>
		<link>http://programmingpraxis.com/2009/06/16/who-owns-the-zebra/#comment-187</link>
		<dc:creator><![CDATA[Remco Niemeijer]]></dc:creator>
		<pubDate>Mon, 22 Jun 2009 12:16:09 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=754#comment-187</guid>
		<description><![CDATA[A more elegant solution (see http://bonsaicode.wordpress.com/2009/06/22/who-owns-the-zebra-reloaded/ for more detail):

[sourcecode lang=&#039;css&#039;]
import Data.List

indexOf :: (Eq a) =&gt; [a] -&gt; a -&gt; Int
indexOf xs x = head $ elemIndices x xs

nextTo :: Int -&gt; Int -&gt; Bool
nextTo a b = abs (a - b) == 1

rightOf :: Int -&gt; Int -&gt; Bool
rightOf a b = a == b + 1

options :: String -&gt; [[String]]
options = permutations . words

solution :: [[String]]
solution = head [transpose [cs, os, ds, ss, ps] &#124;
    cs &lt;- options &quot;red green ivory yellow blue&quot;,
    let color = indexOf cs,
    color &quot;green&quot; `rightOf` color &quot;ivory&quot;,
    os &lt;- options &quot;english spaniard ukranian norwegian japanese&quot;,
    let owner = indexOf os,
    owner &quot;norwegian&quot; == 0,
    owner &quot;english&quot; == color &quot;red&quot;,
    owner &quot;norwegian&quot; `nextTo` color &quot;blue&quot;,
    ds &lt;- options &quot;coffee tea milk juice water&quot;,
    let drinks = indexOf ds,
    drinks &quot;milk&quot; == 2,
    drinks &quot;coffee&quot; == color &quot;green&quot;,
    owner &quot;ukranian&quot; == drinks &quot;tea&quot;,
    ss &lt;- options &quot;old_gold kools chesterfields parliaments lucky_strike&quot;,
    let smokes = indexOf ss,
    smokes &quot;kools&quot; == color &quot;yellow&quot;,
    smokes &quot;lucky_strike&quot; == drinks &quot;juice&quot;,
    owner &quot;japanese&quot; == smokes &quot;parliaments&quot;,
    ps &lt;- options &quot;dog snails fox horse zebra&quot;,
    let pet = indexOf ps,
    owner &quot;spaniard&quot; == pet &quot;dog&quot;,
    smokes &quot;old_gold&quot; == pet &quot;snails&quot;,
    smokes &quot;chesterfields&quot; `nextTo` pet &quot;fox&quot;,
    smokes &quot;kools&quot; `nextTo` pet &quot;horse&quot;]

main :: IO ()
main = mapM_ print solution
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>A more elegant solution (see <a href="http://bonsaicode.wordpress.com/2009/06/22/who-owns-the-zebra-reloaded/" rel="nofollow">http://bonsaicode.wordpress.com/2009/06/22/who-owns-the-zebra-reloaded/</a> for more detail):</p>
<pre class="brush: css;">
import Data.List

indexOf :: (Eq a) =&gt; [a] -&gt; a -&gt; Int
indexOf xs x = head $ elemIndices x xs

nextTo :: Int -&gt; Int -&gt; Bool
nextTo a b = abs (a - b) == 1

rightOf :: Int -&gt; Int -&gt; Bool
rightOf a b = a == b + 1

options :: String -&gt; [[String]]
options = permutations . words

solution :: [[String]]
solution = head [transpose [cs, os, ds, ss, ps] |
    cs &lt;- options &quot;red green ivory yellow blue&quot;,
    let color = indexOf cs,
    color &quot;green&quot; `rightOf` color &quot;ivory&quot;,
    os &lt;- options &quot;english spaniard ukranian norwegian japanese&quot;,
    let owner = indexOf os,
    owner &quot;norwegian&quot; == 0,
    owner &quot;english&quot; == color &quot;red&quot;,
    owner &quot;norwegian&quot; `nextTo` color &quot;blue&quot;,
    ds &lt;- options &quot;coffee tea milk juice water&quot;,
    let drinks = indexOf ds,
    drinks &quot;milk&quot; == 2,
    drinks &quot;coffee&quot; == color &quot;green&quot;,
    owner &quot;ukranian&quot; == drinks &quot;tea&quot;,
    ss &lt;- options &quot;old_gold kools chesterfields parliaments lucky_strike&quot;,
    let smokes = indexOf ss,
    smokes &quot;kools&quot; == color &quot;yellow&quot;,
    smokes &quot;lucky_strike&quot; == drinks &quot;juice&quot;,
    owner &quot;japanese&quot; == smokes &quot;parliaments&quot;,
    ps &lt;- options &quot;dog snails fox horse zebra&quot;,
    let pet = indexOf ps,
    owner &quot;spaniard&quot; == pet &quot;dog&quot;,
    smokes &quot;old_gold&quot; == pet &quot;snails&quot;,
    smokes &quot;chesterfields&quot; `nextTo` pet &quot;fox&quot;,
    smokes &quot;kools&quot; `nextTo` pet &quot;horse&quot;]

main :: IO ()
main = mapM_ print solution
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Remco Niemeijer</title>
		<link>http://programmingpraxis.com/2009/06/16/who-owns-the-zebra/#comment-175</link>
		<dc:creator><![CDATA[Remco Niemeijer]]></dc:creator>
		<pubDate>Tue, 16 Jun 2009 22:17:31 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=754#comment-175</guid>
		<description><![CDATA[My Haskell solution (see http://bonsaicode.wordpress.com/2009/06/16/programming-praxis-who-owns-the-zebra/ for a version with comments):

[sourcecode lang=&#039;css&#039;]
import Data.List
import qualified Data.Map as M

type Grid = M.Map String (M.Map Int [String])

data Constraint = Link (String, String) (String, String)
                &#124; PosLink (String, String) Int
                &#124; NextTo (String, String) (String, String)
                &#124; RightOf (String, String) (String, String)
                deriving Eq

type Solver = ([Constraint], Grid)

addConstraint :: Constraint -&gt; Solver -&gt; Solver
addConstraint c (cs, g) = (c : cs, g)

removeIf :: (String, String) -&gt; (String, String) -&gt;
    [String -&gt; String -&gt; Int -&gt; Grid -&gt; Bool] -&gt; Grid -&gt; Grid
removeIf (f1, v1) (f2, v2) cs g = M.adjust (M.mapWithKey (\k -&gt;
    if and [c f1 v1 k g &#124; c &lt;- cs] then delete v2 else id)) f2 g

notAt :: (Int -&gt; Int) -&gt; String -&gt; String -&gt; Int -&gt; Grid -&gt; Bool
notAt f f1 v1 i g = M.notMember (f i) (g M.! f1) &#124;&#124;
                    notElem v1 (g M.! f1 M.! (f i))

runConstraint :: Constraint -&gt; Grid -&gt; Grid
runConstraint (Link a b) = removeIf a b conds . removeIf b a conds
    where conds = [(\f1 v1 k -&gt; notElem v1 . (M.! k) . (M.! f1))]
runConstraint (PosLink (f1,v1) i) =
    M.adjust (M.update (const $ Just [v1]) i) f1
runConstraint (NextTo a b)  = removeIf a b [notAt pred, notAt succ]
runConstraint (RightOf a b) = removeIf a b [notAt pred] .
                              removeIf b a [notAt succ]

adjustOthers :: Eq k =&gt; (v -&gt; v) -&gt; k -&gt; M.Map k v -&gt; M.Map k v
adjustOthers f k = M.mapWithKey (\k&#039; v -&gt; if k&#039; == k then v else f v)

simplify :: Grid -&gt; Grid
simplify g = foldr ($) (M.mapWithKey (\_ v -&gt;
    M.mapWithKey (\i x -&gt; let d = x \\ concat (M.elems $ M.delete i v)
                          in if length d == 1 then d else x) v) g)
    [ M.adjust (adjustOthers (\\ take 1 x) i) f
    &#124; (f, v) &lt;- M.assocs g, (i, x) &lt;- M.assocs v, length x == 1]

run :: Solver -&gt; Solver
run (cs, g) = (cs, simplify $ foldr runConstraint g cs)

apply :: Solver -&gt; Solver
apply = head . head . dropWhile (null . tail) . group . iterate run

solved :: M.Map k (M.Map k&#039; [v]) -&gt; Bool
solved g = and [False &#124; (_, v)  &lt;- M.assocs g,
                        (_, xs) &lt;- M.assocs v, length xs /= 1]

solve :: Solver -&gt; [String]
solve s = map (unwords . map head) . transpose . map (M.elems) .
          M.elems $ head [ r &#124; let (cs, g) = apply s,
          (f, v) &lt;- M.assocs $ g, (i, xs) &lt;- M.assocs v, x &lt;- xs,
          let (_, r) = apply (cs, M.adjust (M.adjust (const [x]) i) f g),
          solved r ]

grid :: Grid
grid = M.fromList . zip (words &quot;owner brand drink pet color&quot;) $
    map (M.fromList . zip [1..] . replicate 5)
    [words &quot;Englishman Ukranian Norwegian Japanese Spaniard&quot;,
     words &quot;Old_Gold Kools Chesterfields Lucky_Strike Parliaments&quot;,
     words &quot;Coffee Tea Milk Orange_Juice Water&quot;,
     words &quot;Dog Snails Horse Fox Zebra&quot;,
     words &quot;Red Green Ivory Yellow Blue&quot;]

problem :: Solver
problem = foldr addConstraint ([], grid)
    [Link    (&quot;owner&quot;, &quot;Englishman&quot;)    (&quot;color&quot;, &quot;Red&quot;),
     Link    (&quot;owner&quot;, &quot;Spaniard&quot;)      (&quot;pet&quot;,   &quot;Dog&quot;),
     Link    (&quot;drink&quot;, &quot;Coffee&quot;)        (&quot;color&quot;, &quot;Green&quot;),
     Link    (&quot;owner&quot;, &quot;Ukranian&quot;)      (&quot;drink&quot;, &quot;Tea&quot;),
     RightOf (&quot;color&quot;, &quot;Ivory&quot;)         (&quot;color&quot;, &quot;Green&quot;),
     Link    (&quot;brand&quot;, &quot;Old_Gold&quot;)      (&quot;pet&quot;,   &quot;Snails&quot;),
     Link    (&quot;brand&quot;, &quot;Kools&quot;)         (&quot;color&quot;, &quot;Yellow&quot;),
     PosLink (&quot;drink&quot;, &quot;Milk&quot;)          3,
     PosLink (&quot;owner&quot;, &quot;Norwegian&quot;)     1,
     NextTo  (&quot;brand&quot;, &quot;Chesterfields&quot;) (&quot;pet&quot;,   &quot;Fox&quot;),
     NextTo  (&quot;brand&quot;, &quot;Kools&quot;)         (&quot;pet&quot;,   &quot;Horse&quot;),
     Link    (&quot;brand&quot;, &quot;Lucky_Strike&quot;)  (&quot;drink&quot;, &quot;Orange_Juice&quot;),
     Link    (&quot;owner&quot;, &quot;Japanese&quot;)      (&quot;brand&quot;, &quot;Parliaments&quot;),
     NextTo  (&quot;owner&quot;, &quot;Norwegian&quot;)     (&quot;color&quot;, &quot;Blue&quot;)]

main :: IO ()
main = mapM_ putStrLn $ solve problem
[/sourcecode]]]></description>
		<content:encoded><![CDATA[<p>My Haskell solution (see <a href="http://bonsaicode.wordpress.com/2009/06/16/programming-praxis-who-owns-the-zebra/" rel="nofollow">http://bonsaicode.wordpress.com/2009/06/16/programming-praxis-who-owns-the-zebra/</a> for a version with comments):</p>
<pre class="brush: css;">
import Data.List
import qualified Data.Map as M

type Grid = M.Map String (M.Map Int [String])

data Constraint = Link (String, String) (String, String)
                | PosLink (String, String) Int
                | NextTo (String, String) (String, String)
                | RightOf (String, String) (String, String)
                deriving Eq

type Solver = ([Constraint], Grid)

addConstraint :: Constraint -&gt; Solver -&gt; Solver
addConstraint c (cs, g) = (c : cs, g)

removeIf :: (String, String) -&gt; (String, String) -&gt;
    [String -&gt; String -&gt; Int -&gt; Grid -&gt; Bool] -&gt; Grid -&gt; Grid
removeIf (f1, v1) (f2, v2) cs g = M.adjust (M.mapWithKey (\k -&gt;
    if and [c f1 v1 k g | c &lt;- cs] then delete v2 else id)) f2 g

notAt :: (Int -&gt; Int) -&gt; String -&gt; String -&gt; Int -&gt; Grid -&gt; Bool
notAt f f1 v1 i g = M.notMember (f i) (g M.! f1) ||
                    notElem v1 (g M.! f1 M.! (f i))

runConstraint :: Constraint -&gt; Grid -&gt; Grid
runConstraint (Link a b) = removeIf a b conds . removeIf b a conds
    where conds = [(\f1 v1 k -&gt; notElem v1 . (M.! k) . (M.! f1))]
runConstraint (PosLink (f1,v1) i) =
    M.adjust (M.update (const $ Just [v1]) i) f1
runConstraint (NextTo a b)  = removeIf a b [notAt pred, notAt succ]
runConstraint (RightOf a b) = removeIf a b [notAt pred] .
                              removeIf b a [notAt succ]

adjustOthers :: Eq k =&gt; (v -&gt; v) -&gt; k -&gt; M.Map k v -&gt; M.Map k v
adjustOthers f k = M.mapWithKey (\k' v -&gt; if k' == k then v else f v)

simplify :: Grid -&gt; Grid
simplify g = foldr ($) (M.mapWithKey (\_ v -&gt;
    M.mapWithKey (\i x -&gt; let d = x \\ concat (M.elems $ M.delete i v)
                          in if length d == 1 then d else x) v) g)
    [ M.adjust (adjustOthers (\\ take 1 x) i) f
    | (f, v) &lt;- M.assocs g, (i, x) &lt;- M.assocs v, length x == 1]

run :: Solver -&gt; Solver
run (cs, g) = (cs, simplify $ foldr runConstraint g cs)

apply :: Solver -&gt; Solver
apply = head . head . dropWhile (null . tail) . group . iterate run

solved :: M.Map k (M.Map k' [v]) -&gt; Bool
solved g = and [False | (_, v)  &lt;- M.assocs g,
                        (_, xs) &lt;- M.assocs v, length xs /= 1]

solve :: Solver -&gt; [String]
solve s = map (unwords . map head) . transpose . map (M.elems) .
          M.elems $ head [ r | let (cs, g) = apply s,
          (f, v) &lt;- M.assocs $ g, (i, xs) &lt;- M.assocs v, x &lt;- xs,
          let (_, r) = apply (cs, M.adjust (M.adjust (const [x]) i) f g),
          solved r ]

grid :: Grid
grid = M.fromList . zip (words &quot;owner brand drink pet color&quot;) $
    map (M.fromList . zip [1..] . replicate 5)
    [words &quot;Englishman Ukranian Norwegian Japanese Spaniard&quot;,
     words &quot;Old_Gold Kools Chesterfields Lucky_Strike Parliaments&quot;,
     words &quot;Coffee Tea Milk Orange_Juice Water&quot;,
     words &quot;Dog Snails Horse Fox Zebra&quot;,
     words &quot;Red Green Ivory Yellow Blue&quot;]

problem :: Solver
problem = foldr addConstraint ([], grid)
    [Link    (&quot;owner&quot;, &quot;Englishman&quot;)    (&quot;color&quot;, &quot;Red&quot;),
     Link    (&quot;owner&quot;, &quot;Spaniard&quot;)      (&quot;pet&quot;,   &quot;Dog&quot;),
     Link    (&quot;drink&quot;, &quot;Coffee&quot;)        (&quot;color&quot;, &quot;Green&quot;),
     Link    (&quot;owner&quot;, &quot;Ukranian&quot;)      (&quot;drink&quot;, &quot;Tea&quot;),
     RightOf (&quot;color&quot;, &quot;Ivory&quot;)         (&quot;color&quot;, &quot;Green&quot;),
     Link    (&quot;brand&quot;, &quot;Old_Gold&quot;)      (&quot;pet&quot;,   &quot;Snails&quot;),
     Link    (&quot;brand&quot;, &quot;Kools&quot;)         (&quot;color&quot;, &quot;Yellow&quot;),
     PosLink (&quot;drink&quot;, &quot;Milk&quot;)          3,
     PosLink (&quot;owner&quot;, &quot;Norwegian&quot;)     1,
     NextTo  (&quot;brand&quot;, &quot;Chesterfields&quot;) (&quot;pet&quot;,   &quot;Fox&quot;),
     NextTo  (&quot;brand&quot;, &quot;Kools&quot;)         (&quot;pet&quot;,   &quot;Horse&quot;),
     Link    (&quot;brand&quot;, &quot;Lucky_Strike&quot;)  (&quot;drink&quot;, &quot;Orange_Juice&quot;),
     Link    (&quot;owner&quot;, &quot;Japanese&quot;)      (&quot;brand&quot;, &quot;Parliaments&quot;),
     NextTo  (&quot;owner&quot;, &quot;Norwegian&quot;)     (&quot;color&quot;, &quot;Blue&quot;)]

main :: IO ()
main = mapM_ putStrLn $ solve problem
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Programming Praxis &#8211; Who Owns The Zebra? &#171; Bonsai Code</title>
		<link>http://programmingpraxis.com/2009/06/16/who-owns-the-zebra/#comment-174</link>
		<dc:creator><![CDATA[Programming Praxis &#8211; Who Owns The Zebra? &#171; Bonsai Code]]></dc:creator>
		<pubDate>Tue, 16 Jun 2009 22:17:17 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=754#comment-174</guid>
		<description><![CDATA[[...] Praxis &#8211; Who Owns The&#160;Zebra? By Remco Niemeijer  In Today’s Programming Praxis problem we have to solve a logic puzzle. The provided solution uses a 182-line [...]]]></description>
		<content:encoded><![CDATA[<p>[...] Praxis &#8211; Who Owns The&nbsp;Zebra? By Remco Niemeijer  In Today’s Programming Praxis problem we have to solve a logic puzzle. The provided solution uses a 182-line [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Remco Niemeijer</title>
		<link>http://programmingpraxis.com/2009/06/16/who-owns-the-zebra/#comment-173</link>
		<dc:creator><![CDATA[Remco Niemeijer]]></dc:creator>
		<pubDate>Tue, 16 Jun 2009 22:16:37 +0000</pubDate>
		<guid isPermaLink="false">http://programmingpraxis.wordpress.com/?p=754#comment-173</guid>
		<description><![CDATA[There&#039;s a slight error in your code: you have the ivory house to the right of the green house instead of the other way round. Flipping the constraint for number 6 around should fix it.]]></description>
		<content:encoded><![CDATA[<p>There&#8217;s a slight error in your code: you have the ivory house to the right of the green house instead of the other way round. Flipping the constraint for number 6 around should fix it.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

