<?xml version="1.0"?>
<rss version="2.0"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:dcterms="http://purl.org/dc/terms/" >
<channel>
<title>log - Fabian Linzbergers weblog</title>
<link>http://lefant.net/log/</link>
<description>lefant.net/log - Fabian Linzbergers weblog</description>
<item>
	
	<title>2010-03-24---klarna programming contest 2010</title>
	
	
	  <guid>http://lefant.net/logposts/2010-03-24---klarna_programming_contest_2010/</guid>
	
	<link>http://lefant.net/logposts/2010-03-24---klarna_programming_contest_2010/</link>
	
	
	<category>code</category>
	
	<category>fp</category>
	
	<category>hacking</category>
	
	<category>haskell</category>
	
	<category>software</category>
	
	
	<pubDate>Wed, 24 Mar 2010 15:58:13 +0100</pubDate>
	<dcterms:modified>2010-04-19T05:22:05Z</dcterms:modified>
	
	<description>&lt;p&gt;At the beginning of this week the results of the &lt;a href=&quot;http://kpc2010.klarna.com/web/index&quot;&gt;Klarna Programming
Contest 2010&lt;/a&gt; were published.&lt;/p&gt;

&lt;p&gt;Most important news from my perspective:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Overall best solution:

Second prize: Fabian Linzberger (Apple iPhone)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yay, I made second place! Yay, I won a smartphone!&lt;/p&gt;

&lt;p&gt;Since I was asked about the problems I thought I would write up a bit
of my experience.&lt;/p&gt;

&lt;h1&gt;Problem 1&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;http://lefant.net/log/./media/2010-03-24---klarna_programming_contest_2010/klarna.png&quot;&gt;&lt;img src=&quot;http://lefant.net/log/./media/2010-03-24---klarna_programming_contest_2010/klarna.png&quot; width=&quot;453&quot; height=&quot;458&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(picture converted to png for the webbrowser. original PPM &lt;a href=&quot;http://lefant.net/log/media/2010-03-24---klarna_programming_contest_2010/klarna.ppm&quot;&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;A picture in PPM format
(http://en.wikipedia.org/wiki/Netpbm_format#PPM_example), was given,
that contained a hidden message.&lt;/p&gt;

&lt;p&gt;I was totally mislead by the hint &quot;what may seem red and insignificant
is not&quot;. I thought it referred to the red text in the picture, when
(obviously, in retrospect, haha!) it was in fact referring to the
&lt;a href=&quot;http://en.wikipedia.org/wiki/Least_significant_bit&quot;&gt;least significant
bit&lt;/a&gt; of the red
part of the pixels in the picture. I spent quite some time filtering
the shades of grey around the text before I finally realized I was
looking in the wrong place.&lt;/p&gt;

&lt;p&gt;Basically some of the first 60 or so pixels would appear white to the
eye just like the others around them, but in reality about half of
them were just a tiny, tiny bit less red. Decode the white pixels to
0s and the less red pixels to 1s in bits, translate to letters and you
had the secret message.&lt;/p&gt;

&lt;h1&gt;Problem 2&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;http://lefant.net/log/./media/2010-03-24---klarna_programming_contest_2010/key.png&quot;&gt;&lt;img src=&quot;http://lefant.net/log/./media/2010-03-24---klarna_programming_contest_2010/key.png&quot; width=&quot;453&quot; height=&quot;458&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(picture converted to png for the webbrowser. original PPM &lt;a href=&quot;http://lefant.net/log/media/2010-03-24---klarna_programming_contest_2010/key.ppm&quot;&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Another picture, another hidden message. Using the solution program
from problem 1 gave a hint: &quot;iccanobiF&quot;.&lt;/p&gt;

&lt;p&gt;Clearly &quot;Fibonacci&quot;, just backwards. Now it came in handy that I had
actually programmed a decoder for the picture file for problem
one. Searching around for suspicious pixel values, quickly revealed
around 10 or so which were just a little less red, this time
distributed somewhere among the blue of the tulip.&lt;/p&gt;

&lt;p&gt;Turns out if you make a list of all blue and slightly less blue
pixels in the picture, reverse it and use the &lt;a href=&quot;http://en.wikipedia.org/wiki/Fibonacci_number&quot;&gt;Fibonacci
sequence&lt;/a&gt; as indices
you again get a list of bits that decode to letters. Reverse that once
again and you had the second keyword. Phew.&lt;/p&gt;

&lt;h1&gt;Problem 3&lt;/h1&gt;

&lt;p&gt;A variant of the &lt;a href=&quot;http://en.wikipedia.org/wiki/Conway&#39;s_Game_of_Life&quot;&gt;Game of Life&lt;/a&gt;.
An encoding of letters to a start configurations of cells on a matrix
and the other way round was specified. The solution program had to use
this on a keyword, run a certain number of iterations and afterwards
decode the resulting configuration of cells to another keyword.&lt;/p&gt;

&lt;p&gt;This was a bit of work to implement, but overall I found it a lot
easier than the previous two picture puzzles: at least the objective
was clear.&lt;/p&gt;

&lt;h1&gt;Problem 4&lt;/h1&gt;

&lt;p&gt;A hex encoded and
&lt;a href=&quot;http://en.wikipedia.org/wiki/Vigenère_cipher&quot;&gt;Vigenère&lt;/a&gt; encrypted
message was given. The task was to decode it. The encryption key could
be obtained by running another simulation on the solution program for
problem 3. Again a bit of coding, but more straightforward than 1 and
2.&lt;/p&gt;

&lt;p&gt;All my coding was done in Haskell. Overall experience was quiet
pleasant. Converting bits to text felt like taking a bit too much
effort, maybe because I am not used to the libraries. As always:
Quickcheck rocks!&lt;/p&gt;
</description>
	
	
</item>
<item>
	
	<title>2010-02-28---tronbot-google ai challenge</title>
	
	
	  <guid>http://lefant.net/logposts/2010-02-28---tronbot-google_ai_challenge/</guid>
	
	<link>http://lefant.net/logposts/2010-02-28---tronbot-google_ai_challenge/</link>
	
	
	<category>code</category>
	
	<category>fp</category>
	
	<category>hacking</category>
	
	<category>haskell</category>
	
	<category>software</category>
	
	
	<pubDate>Tue, 02 Mar 2010 10:01:13 +0100</pubDate>
	<dcterms:modified>2010-03-02T09:06:58Z</dcterms:modified>
	
	<description>&lt;p&gt;I participated in the &lt;a href=&quot;http://csclub.uwaterloo.ca/contest/&quot;&gt;google ai challenge&lt;/a&gt;. In the end I was placed 134 out of 708: &lt;a href=&quot;http://csclub.uwaterloo.ca/contest/profile.php?user_id=2637&quot;&gt;My profile url&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since I am working on a Monte Carlo tree search based Computer Go program, I figured I would try to use that as a basis for my bot.&lt;/p&gt;

&lt;p&gt;In general it worked quiet ok. Especially in close range combat it is often able to play quite well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://csclub.uwaterloo.ca/contest/visualizer.php?game_id=4156724&quot;&gt;example 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://csclub.uwaterloo.ca/contest/visualizer.php?game_id=4156775&quot;&gt;example 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://csclub.uwaterloo.ca/contest/visualizer.php?game_id=4155561&quot;&gt;example 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://csclub.uwaterloo.ca/contest/visualizer.php?game_id=4152251&quot;&gt;example 4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At longer range and when looking for the longest path in endgame situations lack of depth in the tree search shows and quiet many mistakes are made.&lt;/p&gt;

&lt;p&gt;I also experimented with using the distance between the players as a heuristic to bias the tree search into deeper branches, this was only mildly successful however. It seemed to be very hard to strike a balance between the heuristic not making a difference and turning my bot into a chaser.&lt;/p&gt;

&lt;p&gt;In the final version my bots strategy is as follows:&lt;/p&gt;

&lt;p&gt;Test if there is a path reaching the opponent using the a* pathfinding algorithm.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#         ###############
        ##        ...   #
      ##          .#1   #
    ##      #     .###  #
   #        #     .     #
  #         #     .     #
 #          # ..... #   #
#           # .####     #
# ###       # .         #
#     ####  # .         #
#           # .  #      #
#     #       .  #      #
#     #    ###.  #      #
#     #    ....  #      #
#     #    .#           #
#         ..#  ###      #
#         . #      ###  #
#     ####. #           #
#   #  .... #          # 
#     ..    #         #  
#     .     #        #   
#  ###.     #      ##    
#   2#.          ##      
#   ...        ##        
###############

a* found shortest path between players
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In case there is not, enter special endgame mode: the value of nodes in tree search is number of moves divided by flood fill size. I am unhappy with the endgame, this should make less mistakes.&lt;/p&gt;

&lt;p&gt;In case opponents can still reach each other, use a biased tree search:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;p and P are nodes searched for player 1
e and E are nodes searched for player 2 (enemy)
1 is the principal variation for player 1
1 is the principal variation for player 2

###############
#1PPPPPPP     #
#111PPPPP     #
#1111PPP     e#
#PPP1PP     eE#
#PPPPPPP   eEE#
#PPPPPPPe eEEE#
#PPPPPPEEEeEEE#
#PPP p EEEEEEE#
#PPp   EEEEEEE#
#Pp    EEE2EEE#
#      EEE2222#
#     EEEEEE22#
#    EEEEEEE22#
###############
nodes evaluated for each player in tree search at long range
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;At long range nodes closing in to the opponent are preferred.&lt;/p&gt;

&lt;p&gt;Nodes are evaluated using flood fill if they divide opponents into separate areas.&lt;/p&gt;

&lt;p&gt;Otherwise random playouts until either player crashes are used.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;###############
##     PPP  e #
#### pPPPPWEEE#
#  #PPPP111222#
#  #PPP11W22E2#
#  #PPP11W2EEE#
#  #####1W2EEE#
#    ##1122EEE#
#    PPPW#EEE #
#     PP ##E  #
#         #   #
#         #####
#          ####
#          ####
###############
nodes evaluated for each player in tree search at closer range
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Tree search terminates as soon as 0.9 seconds are spent and return the best move found so far.&lt;/p&gt;

&lt;p&gt;After reading a little about strategies other people have used, it may also have been a bad heuristic to just approach the other bot. &quot;Voronoi territory&quot; - the number of points that can be reached by each bot first - may have been a better choice. In general a good heuristic is key for Monte Carlo tree search to be able to deeply explore the tree without missing the wrong branches, so this could have helped a lot.&lt;/p&gt;

&lt;p&gt;Further links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://git.lefant.net/cgi-bin/gitweb.cgi?p=tronbot-google_ai_challenge.git;a=summary&quot;&gt;Haskell code and some testmaps are online&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://csclub.uwaterloo.ca/contest/forums/viewtopic.php?f=8&amp;amp;t=361&quot;&gt;Forum thread on &quot;tronte carlo&quot;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://www.benzedrine.cx/tron/&quot;&gt;Unofficial game server continuing to run after the contest has closed&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
	
	
</item>
<item>
	
	<title>2010-01-07---sudoku</title>
	
	
	  <guid>http://lefant.net/logposts/2010-01-07---sudoku/</guid>
	
	<link>http://lefant.net/logposts/2010-01-07---sudoku/</link>
	
	<pubDate>Thu, 07 Jan 2010 14:49:17 +0100</pubDate>
	<dcterms:modified>2010-01-07T14:13:12Z</dcterms:modified>
	
	<description>&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Lefants haskell sudoku solver&lt;/title&gt;
&lt;link type=&#39;text/css&#39; rel=&#39;stylesheet&#39; href=&#39;../../css/hscolour.css&#39; /&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;p&gt;Sometime in autumn 2009 i created a sudoku solver in haskell as a
programming exercise for myself. I am pretty happy with the result, it
took no more than an afternoon to implement and has been able to solve
everything I tried in a couple of seconds. Now I can happily smile to
myself whenever I see someone solving sudokus from the newspaper
&lt;img src=&quot;http://lefant.net/log/../smileys/smile4.png&quot; alt=&quot;;)&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Below is a commented and syntax highlighted version
of the main module, the
&lt;a href=&quot;http://git.lefant.net/cgi-bin/gitweb.cgi?p=sudoku-lefant.git;a=summary&quot;&gt;complete
code in git&lt;/a&gt; is also online.&lt;/p&gt;

&lt;p&gt;If you are interested in more haskell solutions to the sudoku
problem, make sure to check out
the &lt;a href=&quot;http://www.haskell.org/haskellwiki/Sudoku&quot;&gt;Sudoku page on
haskellwiki&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;span class=&#39;hs-comment&#39;&gt;-- Lefants haskell sudoku solver&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- -----------------------------&lt;/span&gt;

&lt;span class=&#39;hs-comment&#39;&gt;{-# OPTIONS -O2 -Wall -Werror -Wwarn #-}&lt;/span&gt;

&lt;span class=&#39;hs-comment&#39;&gt;-- This is the main module, containing the actual logic.&lt;/span&gt;

&lt;span class=&#39;hs-keyword&#39;&gt;module&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Sudoku&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;
               &lt;span class=&#39;hs-varid&#39;&gt;solveOne&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt;
              &lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;where&lt;/span&gt;
&lt;span class=&#39;hs-keyword&#39;&gt;import&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Data&lt;/span&gt;&lt;span class=&#39;hs-varop&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;List&lt;/span&gt;


&lt;span class=&#39;hs-comment&#39;&gt;{-
There are two helpers:

 * sudoku-test runs some (very very basic) tests.
 * sudoku-run is the binary for normal invocation, it will read from
   stdin and output to stdout. use it like this:

$ cat &amp;lt;&amp;lt;EOF | ./sudoku-run
.98......
....7....
....15...
1........
...2....9
...9.6.82
.......3.
5.1......
...4...2.
EOF

798624315
315879246
264315978
129587463
683241759
457936182
942158637
531762894
876493521
-}&lt;/span&gt;




&lt;span class=&#39;hs-comment&#39;&gt;{-
The Coord type is a three-dimensional coordinate, the 3rd one is the
box the field is in, like indicated here:

+-----------+
|111|222|333|
|111|222|333|
|111|222|333|
+-----------+
|444|555|666|
|444|555|666|
|444|555|666|
+-----------+
|777|888|999|
|777|888|999|
|777|888|999|
+-----------+
-}&lt;/span&gt;

&lt;span class=&#39;hs-keyword&#39;&gt;type&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Coord&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;



&lt;span class=&#39;hs-comment&#39;&gt;-- Value holds a solution value or a list of remaining valid&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- candidates for the field.&lt;/span&gt;

&lt;span class=&#39;hs-keyword&#39;&gt;data&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Value&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Element&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;|&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Options&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt;
           &lt;span class=&#39;hs-keyword&#39;&gt;deriving&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Show&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;

&lt;span class=&#39;hs-comment&#39;&gt;-- An actual field consists of a coordinate and a Value (as described&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- above).&lt;/span&gt;

&lt;span class=&#39;hs-keyword&#39;&gt;type&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Pair&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Coord&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Value&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;



&lt;span class=&#39;hs-comment&#39;&gt;-- This is the main exported function. It will read in a string of&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- digits or . and feed it to the solve&#39; function which will find a&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- solution using solve and then return a prettified string&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- representation.&lt;/span&gt;

&lt;span class=&#39;hs-definition&#39;&gt;solveOne&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;String&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;String&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;solveOne&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;ls&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt;
    &lt;span class=&#39;hs-varid&#39;&gt;concatMap&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;pretty&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;$&lt;/span&gt;
    &lt;span class=&#39;hs-varid&#39;&gt;sortBy&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;compareC&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;$&lt;/span&gt;
    &lt;span class=&#39;hs-varid&#39;&gt;solve&#39;&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;$&lt;/span&gt;
    &lt;span class=&#39;hs-varid&#39;&gt;zip&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;triples&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;$&lt;/span&gt;
    &lt;span class=&#39;hs-varid&#39;&gt;map&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;readOne&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;ls&lt;/span&gt;


&lt;span class=&#39;hs-comment&#39;&gt;-- This will return a list of three-dimensional coordinates as&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- explained with the Coord type above.&lt;/span&gt;

&lt;span class=&#39;hs-definition&#39;&gt;triples&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Coord&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;triples&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; 
    &lt;span class=&#39;hs-varid&#39;&gt;zip3&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;a&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;b&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;$&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;map&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;z&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;pairs&lt;/span&gt;
    &lt;span class=&#39;hs-keyword&#39;&gt;where&lt;/span&gt;
      &lt;span class=&#39;hs-varid&#39;&gt;pairs&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;a&#39;&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;b&#39;&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;|&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;b&#39;&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-num&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;..&lt;/span&gt;&lt;span class=&#39;hs-num&#39;&gt;9&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;a&#39;&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-num&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;..&lt;/span&gt;&lt;span class=&#39;hs-num&#39;&gt;9&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt;
      &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;b&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;unzip&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;pairs&lt;/span&gt;

      &lt;span class=&#39;hs-varid&#39;&gt;z&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt;
      &lt;span class=&#39;hs-varid&#39;&gt;z&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;x&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;y&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt;
          &lt;span class=&#39;hs-varid&#39;&gt;x2z&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;+&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;y2z&lt;/span&gt;
          &lt;span class=&#39;hs-keyword&#39;&gt;where&lt;/span&gt;
            &lt;span class=&#39;hs-varid&#39;&gt;x2z&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;x&lt;/span&gt; &lt;span class=&#39;hs-comment&#39;&gt;-&lt;/span&gt; &lt;span class=&#39;hs-num&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;`div`&lt;/span&gt; &lt;span class=&#39;hs-num&#39;&gt;3&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;+&lt;/span&gt; &lt;span class=&#39;hs-num&#39;&gt;1&lt;/span&gt;
            &lt;span class=&#39;hs-varid&#39;&gt;y2z&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;y&lt;/span&gt; &lt;span class=&#39;hs-comment&#39;&gt;-&lt;/span&gt; &lt;span class=&#39;hs-num&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;`div`&lt;/span&gt; &lt;span class=&#39;hs-num&#39;&gt;3&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;*&lt;/span&gt; &lt;span class=&#39;hs-num&#39;&gt;3&lt;/span&gt;


&lt;span class=&#39;hs-comment&#39;&gt;-- Pretty representation of field values&lt;/span&gt;

&lt;span class=&#39;hs-definition&#39;&gt;pretty&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;t&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Value&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;String&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;pretty&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Element&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;e&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;show&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;e&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;pretty&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Options&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-str&#39;&gt;&quot;&quot;&lt;/span&gt;


&lt;span class=&#39;hs-comment&#39;&gt;-- Used for sorting coordinates from left to right and top to bottom.&lt;/span&gt;

&lt;span class=&#39;hs-definition&#39;&gt;compareC&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Ord&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;t2&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Ord&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;t3&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;t2&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;t3&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;t4&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;t&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;t2&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;t3&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;t5&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;t1&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Ordering&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;compareC&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;c1&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;c2&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt;
    &lt;span class=&#39;hs-varid&#39;&gt;compareT&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;c1&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;c2&lt;/span&gt;
    &lt;span class=&#39;hs-keyword&#39;&gt;where&lt;/span&gt;
      &lt;span class=&#39;hs-varid&#39;&gt;compareT&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;a1&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;b1&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;a2&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;b2&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;
          &lt;span class=&#39;hs-keyglyph&#39;&gt;|&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;b1&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;==&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;b2&lt;/span&gt;  &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;compare&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;a1&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;a2&lt;/span&gt;
          &lt;span class=&#39;hs-keyglyph&#39;&gt;|&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;otherwise&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;compare&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;b1&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;b2&lt;/span&gt;



&lt;span class=&#39;hs-comment&#39;&gt;-- Read in a predefined single value or failing that initialize the&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- list of options.&lt;/span&gt;

&lt;span class=&#39;hs-definition&#39;&gt;readOne&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Char&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Value&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;readOne&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;c&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt;
    &lt;span class=&#39;hs-keyword&#39;&gt;case&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;c&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;`elem`&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;map&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;head&lt;/span&gt;&lt;span class=&#39;hs-varop&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;show&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-num&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;..&lt;/span&gt;&lt;span class=&#39;hs-num&#39;&gt;9&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;of&lt;/span&gt;
      &lt;span class=&#39;hs-conid&#39;&gt;True&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Element&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;read&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;c&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;hs-conid&#39;&gt;False&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Options&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-num&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;..&lt;/span&gt;&lt;span class=&#39;hs-num&#39;&gt;9&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt;



&lt;span class=&#39;hs-comment&#39;&gt;-- solve&#39; and solve contain the actual solving logic. solve&#39; will&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- partition the initial list of fields into ones containing single&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- elements (already defined / solved) and those containing a list of&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- remaining options.&lt;/span&gt;

&lt;span class=&#39;hs-definition&#39;&gt;solve&#39;&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Pair&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Pair&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;solve&#39;&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;ls&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt;
    &lt;span class=&#39;hs-varid&#39;&gt;solution&lt;/span&gt;
    &lt;span class=&#39;hs-keyword&#39;&gt;where&lt;/span&gt;
      &lt;span class=&#39;hs-conid&#39;&gt;Just&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;solution&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;solve&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;done&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;todo&lt;/span&gt;
      &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;done&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;todo&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;partition&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;isElement&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;ls&lt;/span&gt;
      &lt;span class=&#39;hs-varid&#39;&gt;isElement&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;t&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Value&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Bool&lt;/span&gt;
      &lt;span class=&#39;hs-varid&#39;&gt;isElement&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Element&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;True&lt;/span&gt;
      &lt;span class=&#39;hs-varid&#39;&gt;isElement&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Options&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;False&lt;/span&gt;


&lt;span class=&#39;hs-comment&#39;&gt;-- solve takes two lists of coordinate / value pairs as parameters:&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- the first one contains solved single element fields, the second all&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- the lists with remaining options.&lt;/span&gt;

&lt;span class=&#39;hs-definition&#39;&gt;solve&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Pair&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Pair&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Maybe&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;hs-conid&#39;&gt;Pair&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;]&lt;/span&gt;
&lt;span class=&#39;hs-comment&#39;&gt;-- if all the fields have one element we are done.&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;solve&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;es&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;[]&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Just&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;es&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;solve&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;es&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;os&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt;
    &lt;span class=&#39;hs-keyword&#39;&gt;case&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;as&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;of&lt;/span&gt;
      &lt;span class=&#39;hs-comment&#39;&gt;-- no more Options, no solutions possible&lt;/span&gt;
      &lt;span class=&#39;hs-conid&#39;&gt;[]&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Nothing&lt;/span&gt;
      &lt;span class=&#39;hs-comment&#39;&gt;-- try first option&lt;/span&gt;
      &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;a&lt;/span&gt; &lt;span class=&#39;hs-conop&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;as&#39;&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt;
          &lt;span class=&#39;hs-comment&#39;&gt;-- recurse using backtracking, if we can solve it&lt;/span&gt;
          &lt;span class=&#39;hs-keyword&#39;&gt;case&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;solve&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;c&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Element&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-conop&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;es&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;os&#39;&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;of&lt;/span&gt;
            &lt;span class=&#39;hs-comment&#39;&gt;-- we are done&lt;/span&gt;
            &lt;span class=&#39;hs-conid&#39;&gt;Just&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;es&#39;&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt;
                &lt;span class=&#39;hs-conid&#39;&gt;Just&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;es&#39;&lt;/span&gt;
            &lt;span class=&#39;hs-comment&#39;&gt;-- this branch contains no solutions, retry without it&lt;/span&gt;
            &lt;span class=&#39;hs-conid&#39;&gt;Nothing&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt;
                &lt;span class=&#39;hs-varid&#39;&gt;solve&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;es&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;c&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Options&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;as&#39;&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-conop&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;os&#39;&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;

    &lt;span class=&#39;hs-keyword&#39;&gt;where&lt;/span&gt;
      &lt;span class=&#39;hs-comment&#39;&gt;-- first prune all Options list at the current level, then order&lt;/span&gt;
      &lt;span class=&#39;hs-comment&#39;&gt;-- branches with *few* options first&lt;/span&gt;
      &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;c&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Options&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;as&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-conop&#39;&gt;:&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;os&#39;&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;sortBy&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;lessOptions&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;$&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;map&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;revaluate&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;os&lt;/span&gt;

      &lt;span class=&#39;hs-varid&#39;&gt;lessOptions&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Options&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;xs&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Options&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;ys&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt;
          &lt;span class=&#39;hs-varid&#39;&gt;compare&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;length&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;xs&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;length&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;ys&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;hs-varid&#39;&gt;lessOptions&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Element&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt;
          &lt;span class=&#39;hs-varid&#39;&gt;error&lt;/span&gt; &lt;span class=&#39;hs-str&#39;&gt;&quot;illegal lessOptions call&quot;&lt;/span&gt;
      &lt;span class=&#39;hs-varid&#39;&gt;lessOptions&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Options&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Element&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt;
          &lt;span class=&#39;hs-varid&#39;&gt;error&lt;/span&gt; &lt;span class=&#39;hs-str&#39;&gt;&quot;illegal lessOptions call&quot;&lt;/span&gt;

      &lt;span class=&#39;hs-comment&#39;&gt;-- filter out other Options from list that are made impossible&lt;/span&gt;
      &lt;span class=&#39;hs-comment&#39;&gt;-- by choosing a certain one&lt;/span&gt;
      &lt;span class=&#39;hs-varid&#39;&gt;revaluate&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Pair&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Pair&lt;/span&gt;
      &lt;span class=&#39;hs-varid&#39;&gt;revaluate&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;c&#39;&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;@&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;x&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;y&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;z&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Options&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;aas&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt;
          &lt;span class=&#39;hs-comment&#39;&gt;{-# SCC &quot;revaluate&quot; #-}&lt;/span&gt;
          &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;c&#39;&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Options&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;aas&#39;&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;
          &lt;span class=&#39;hs-keyword&#39;&gt;where&lt;/span&gt;
            &lt;span class=&#39;hs-varid&#39;&gt;aas&#39;&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;aas&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;\\&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;otherValues&lt;/span&gt;
            &lt;span class=&#39;hs-varid&#39;&gt;otherValues&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;map&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;\&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Element&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;e&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;e&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;
                          &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;filter&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;\&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;e&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;x&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;==&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;px&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;e&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;es&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;++&lt;/span&gt; 
                           &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;filter&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;\&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;e&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;y&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;==&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;py&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;e&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;es&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;++&lt;/span&gt;
                           &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;filter&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyglyph&#39;&gt;\&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;e&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;z&lt;/span&gt; &lt;span class=&#39;hs-varop&#39;&gt;==&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;pz&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;e&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;es&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;hs-varid&#39;&gt;revaluate&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Element&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt;
          &lt;span class=&#39;hs-varid&#39;&gt;error&lt;/span&gt; &lt;span class=&#39;hs-str&#39;&gt;&quot;illegal revaluate call&quot;&lt;/span&gt;


&lt;span class=&#39;hs-comment&#39;&gt;-- helper functions to project a single coordinate from a Pair&lt;/span&gt;

&lt;span class=&#39;hs-definition&#39;&gt;px&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Pair&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;px&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-varid&#39;&gt;x&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;x&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;py&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Pair&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;py&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;y&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;y&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;pz&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Pair&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#39;hs-conid&#39;&gt;Int&lt;/span&gt;
&lt;span class=&#39;hs-definition&#39;&gt;pz&lt;/span&gt; &lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;z&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;hs-keyword&#39;&gt;_&lt;/span&gt;&lt;span class=&#39;hs-layout&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;hs-keyglyph&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;hs-varid&#39;&gt;z&lt;/span&gt;
&lt;/pre&gt;&lt;/body&gt;
&lt;/html&gt;
</description>
	
	
</item>
<item>
	
	<title>2010-01-07---laby-programming-intro</title>
	
	
	  <guid>http://lefant.net/logposts/2010-01-07---laby-programming-intro/</guid>
	
	<link>http://lefant.net/logposts/2010-01-07---laby-programming-intro/</link>
	
	
	<category>code</category>
	
	<category>hacking</category>
	
	<category>ocaml</category>
	
	<category>software</category>
	
	
	<pubDate>Thu, 07 Jan 2010 11:27:15 +0100</pubDate>
	<dcterms:modified>2010-01-07T10:42:50Z</dcterms:modified>
	
	<description>&lt;p&gt;The other day I was playing a little bit with
&lt;a href=&quot;http://www.pps.jussieu.fr/~gimenez/laby/&quot;&gt;laby&lt;/a&gt;, a small program to
help in understanding basic programming concepts for kids, but maybe
grown ups too.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://lefant.net/log/./media/2010-01-07---laby-programming-intro/screenshot-0.png&quot;&gt;&lt;img src=&quot;http://lefant.net/log/./media/2010-01-07---laby-programming-intro/screenshot-0.png&quot; width=&quot;618&quot; height=&quot;512&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is available in Ubuntu in the laby package from karmic (9.10) on. I
can highly recommend it, it is always fun to watch a graphical
representation of a programmed creature do its job after the coding. I
have created a general solution in ocaml that will successfully solve
at least all the levels included in 0.5.0.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(* ocaml wall hugger for laby *)
let ant =
  (* go straight ahead til we hit something *)
  while (Robot.look () = `Void) do
    Robot.forward ();
  done;

  (* main wall hugin&#39; loop *)
  while not (Robot.look () = `Exit) do

    if (Robot.look () == `Void)
    then (
      Robot.forward ();
      Robot.right ();
    );

    if (Robot.look () == `Rock)
    then (
      Robot.take ();
      Robot.forward ();
      Robot.left ();
      Robot.left ();
      Robot.drop ();
      Robot.left ();
    );

    if (Robot.look () == `Wall) or (Robot.look () == `Web)
    then
      Robot.left ();

  done;

  Robot.door_open ();
;;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;http://lefant.net/log/media/2010-01-07---laby-programming-intro/laby.ml&quot;&gt;download source file: laby.ml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go little robot ant!&lt;/p&gt;
</description>
	
	
</item>
<item>
	
	<title>2007-11-25---some-backports</title>
	
	
	  <guid>http://lefant.net/logposts/2007-11-25---some-backports/</guid>
	
	<link>http://lefant.net/logposts/2007-11-25---some-backports/</link>
	
	
	<category>debienna</category>
	
	<category>hacking</category>
	
	<category>software</category>
	
	
	<pubDate>Fri, 20 Nov 2009 17:43:42 +0100</pubDate>
	<dcterms:modified>2009-11-20T16:43:42Z</dcterms:modified>
	
	<description>&lt;p&gt;i have created debian backports to etch of current versions of mpd,
rtorrent and mt-daapd and the dependencies needed to build / install
them.&lt;/p&gt;

&lt;p&gt;add&lt;/p&gt;

&lt;p&gt;deb http://lefant.net/debian/ etch-backports main&lt;/p&gt;

&lt;p&gt;to your /etc/apt/sources.list in case you are interested.&lt;/p&gt;

&lt;p&gt;mt-daapd and rhythmbox are a great pair to store music on one computer
and play on another, with little configuration on the server and none
on the client, by the magic of zeroconf! highly recommended. should
also work with itunes and other stuff from apple.&lt;/p&gt;
</description>
	
	
</item>
<item>
	
	<title>2007-10-11---ipv6 at debienna</title>
	
	
	  <guid>http://lefant.net/logposts/2007-10-11---ipv6_at_debienna/</guid>
	
	<link>http://lefant.net/logposts/2007-10-11---ipv6_at_debienna/</link>
	
	
	<category>debienna</category>
	
	
	<pubDate>Fri, 20 Nov 2009 17:43:42 +0100</pubDate>
	<dcterms:modified>2009-11-20T16:43:42Z</dcterms:modified>
	
	<description>&lt;p&gt;yesterday at &lt;a href=&quot;http://debienna.at/&quot;&gt;debienna&lt;/a&gt; i gave a talk about
computer networking in general, ipv6 and vpn in particular. afterwards
we had some nice further discussion.&lt;/p&gt;

&lt;p&gt;i have also created a page in the wiki with some links in case you are interested: &lt;a href=&quot;http://debienna.at/NetzwerkenConnectYourDevices&quot;&gt;NetzwerkenConnectYourDevices&lt;/a&gt;&lt;/p&gt;
</description>
	
	
</item>
<item>
	
	<title>2007-11-25---voip-hacking-at-deepsec</title>
	
	
	  <guid>http://lefant.net/logposts/2007-11-25---voip-hacking-at-deepsec/</guid>
	
	<link>http://lefant.net/logposts/2007-11-25---voip-hacking-at-deepsec/</link>
	
	
	<category>hacking</category>
	
	<category>security</category>
	
	<category>voip</category>
	
	
	<pubDate>Fri, 20 Nov 2009 17:43:42 +0100</pubDate>
	<dcterms:modified>2009-11-20T16:43:42Z</dcterms:modified>
	
	<description>&lt;p&gt;tuesday and wednesday i attended a training titled &quot;Practical VOIP/SIP
Hacking&quot; at the premiere of the future annual security conference
deepsec in vienna. &lt;a href=&quot;https://deepsec.net/speakers/#darilion-1&quot;&gt;official
site&lt;/a&gt;. the organisation was
pretty professional, as to be expected for the business oriented
pricing. the hotels network occassionally was a bit laggy, but that&#39;s
probably not too surprising considering the demands of a bunch of
workshops full of hackers doing network security stuff.&lt;/p&gt;

&lt;p&gt;i really enjoyed it a lot. klaus really knows his sip and he addressed
quite a range of typical configuration problems, possible exploits and
how to fix them.&lt;/p&gt;

&lt;p&gt;small hint for starters: never put openser on the internet in its
default config, unless you want people to make free calls - you may be
the one to pay the bill. other software of course mostly isn&#39;t much
better, but default openser is literally configured as an open
relay. cisco gateways are not much better, but since they are so
expensive, will only ever be operated by &lt;em&gt;real experts&lt;/em&gt; - haha &lt;img src=&quot;http://lefant.net/log/../smileys/smile4.png&quot; alt=&quot;;)&quot; /&gt;&lt;/p&gt;

&lt;p&gt;an excellent resource if you are interested in this field is also
&lt;a href=&quot;http://www.pernau.at/kd/voip/&quot;&gt;klaus&#39;s voip link collection&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;i was definetely able to profit a lot for the system i am designing at
work. stay tuned for some config samples as it becomes more and more
production proofed.&lt;/p&gt;
</description>
	
	
</item>
<item>
	
	<title>2007-08-23---debienna</title>
	
	
	  <guid>http://lefant.net/logposts/2007-08-23---debienna/</guid>
	
	<link>http://lefant.net/logposts/2007-08-23---debienna/</link>
	
	
	<category>debienna</category>
	
	
	<pubDate>Fri, 20 Nov 2009 17:43:42 +0100</pubDate>
	<dcterms:modified>2009-11-20T16:43:42Z</dcterms:modified>
	
	<description>&lt;p&gt;highlights and random thoughts:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=2032&amp;amp;tags=7&amp;amp;from_date=1187820000&amp;amp;to_date=1187906400&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=2032&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=2033&amp;amp;tags=7&amp;amp;from_date=1187820000&amp;amp;to_date=1187906400&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=2033&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=2034&amp;amp;tags=7&amp;amp;from_date=1187820000&amp;amp;to_date=1187906400&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=2034&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=2035&amp;amp;tags=7&amp;amp;from_date=1187820000&amp;amp;to_date=1187906400&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=2035&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=2036&amp;amp;tags=7&amp;amp;from_date=1187820000&amp;amp;to_date=1187906400&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=2036&amp;amp;width=150&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;present at some point in the evening or another: lefant, harald, karl, andreas, maks, rotty, markus, gregor&lt;/p&gt;

&lt;p&gt;i play around with the new &lt;a href=&quot;http://soup.io/&quot;&gt;metalab 2.0 soup.io&lt;/a&gt;,
there is now &lt;a href=&quot;http://soup.lefant.net/&quot;&gt;soup.lefant.net&lt;/a&gt;. also there is
a &lt;a href=&quot;http://ikiwiki.info/plugins/aggregate/&quot;&gt;aggregate plugin of
ikiwiki&lt;/a&gt; resulting in &lt;a href=&quot;http://lefant.net/soup/&quot;&gt;lefants
soup on ikiwiki&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;looking at the quintessenz backup server in the office i find that
backuppc is slow and &lt;a href=&quot;http://bbdev.fluffy.co.uk/trac/wiki&quot;&gt;boxbackup&lt;/a&gt;
is quick and efficient. i also run a boxbackup server at home on my
nslu2 (32mb ram for those who don&#39;t know it), it is also in debian sid
and there is an etch version on
&lt;a href=&quot;http://backports.org/&quot;&gt;backports.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;it seems an official darcs.debian.org is being planned. i was
contacted as the debian maintainer for darcsweb and hurried to finally
reply to two of the open bugs. of course i hope darcs.debian.org will
feature darcsweb &lt;img src=&quot;http://lefant.net/log/../smileys/smile4.png&quot; alt=&quot;;)&quot; /&gt;&lt;/p&gt;

&lt;p&gt;checking out &lt;a href=&quot;http://firehol.sf.net/&quot;&gt;firehol&lt;/a&gt;. default config works
good enough for my laptop &lt;img src=&quot;http://lefant.net/log/../smileys/smile4.png&quot; alt=&quot;;)&quot; /&gt;&lt;/p&gt;

&lt;p&gt;after about a week of use
&lt;a href=&quot;http://rss2imap.sourceforge.net/en/index.html&quot;&gt;rss2imap&lt;/a&gt; seems to be
good enough as a google reader replacement. a little of my privacy
returns &lt;img src=&quot;http://lefant.net/log/../smileys/smile4.png&quot; alt=&quot;;)&quot; /&gt;&lt;/p&gt;

&lt;p&gt;http://www.mozart-oz.org/features.html is surely interesting for the
functionally inclined.&lt;/p&gt;

&lt;p&gt;at a later time we also discussed some further topics we would like to
talk about in the future.&lt;/p&gt;
</description>
	
	
</item>
<item>
	
	<title>cheap voip at voipcheap</title>
	
	
	  <guid>http://lefant.net/logposts/cheap_voip_at_voipcheap/</guid>
	
	<link>http://lefant.net/logposts/cheap_voip_at_voipcheap/</link>
	
	
	<category>voip</category>
	
	
	<pubDate>Fri, 20 Nov 2009 17:43:42 +0100</pubDate>
	<dcterms:modified>2009-11-20T16:43:42Z</dcterms:modified>
	
	<description>&lt;h1&gt;2007-06-02&lt;/h1&gt;

&lt;p&gt;since i am implementing a voice over ip project at work, i naturally am also investigating options at home. for now i am running an asterisk server on my webserver and use it to call out to PSTN (mostly my girlfriend to her brother who is doing his civil service in sierra leone). fellow debian hacker klaus ita recommended a call by call provider: &lt;a href=&quot;http://www.voipcheap.com/&quot;&gt;voipcheap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;they seem to live up to their name and offer really nice rates. also austrian land lines are free as in free beer. you have to download a windows client to complete the registration which really sucks, but after delaying for more than two weeks i finally got around to do it today. 5 minutes later i am successfully placing my first free call to an austrian landline after adding something like the following to my asterisks sip.conf:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[voipcheap]
realm=sip.voipcheap.com
host=sip.voipcheap.com
username=&amp;lt;myname&amp;gt;
secret= &amp;lt;mypassword&amp;gt;
type=peer
qualify=no
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(instructions found on &lt;a href=&quot;http://www.voip-info.org/wiki/view/voipcheap&quot;&gt;here&lt;/a&gt;)&lt;/p&gt;
</description>
	
	
</item>
<item>
	
	<title>2007-07-22---phpfspot</title>
	
	
	  <guid>http://lefant.net/logposts/2007-07-22---phpfspot/</guid>
	
	<link>http://lefant.net/logposts/2007-07-22---phpfspot/</link>
	
	
	<category>debienna</category>
	
	<category>software</category>
	
	
	<pubDate>Fri, 20 Nov 2009 17:43:42 +0100</pubDate>
	<dcterms:modified>2009-11-20T16:43:42Z</dcterms:modified>
	
	<description>&lt;h1&gt;2007-07-22&lt;/h1&gt;

&lt;p&gt;for some time now i have been using f-spot (website:
&lt;a href=&quot;http://f-spot.org/&quot;&gt;http://f-spot.org/&lt;/a&gt;, which is a nice photo
organization software for gnome. above all f-spot has great support
for tagging, which in my opinion is a very important feature. you can
also automatically create a static html thumbnail gallery for your
website or export to flickr or gallery (the php thing many people seem
to be using). however this way either you loose your tags (static
html, gallery) or you handover your pictures and control over the url
to flickr (which limits you to 200 pictures in their free plan
anyway).&lt;/p&gt;

&lt;p&gt;phpfspot (website:
&lt;a href=&quot;http://oss.netshadow.at/oss/phpfspot/Project&quot;&gt;http://oss.netshadow.at/oss/phpfspot/Project&lt;/a&gt;,
freshmeat:
&lt;a href=&quot;http://freshmeat.net/projects/phpfspot/&quot;&gt;http://freshmeat.net/projects/phpfspot/&lt;/a&gt;)
to the rescue!&lt;/p&gt;

&lt;p&gt;after some whining on my part at work my colleague at work andreas
unterkircher started looking for a better webfrontend solution
(foremost including good support for the tags) himself and, finding
none, started coding. for reference there is pennave with a similar
goal (website:
[http://pennave.sourceforge.net/](http://pennave.sourceforge. net/)),
however speed was really lacking and development very slow).&lt;/p&gt;

&lt;p&gt;i am now happily running phpfspot myself (link:
&lt;a href=&quot;http://gallery.lefant.net/&quot;&gt;http://gallery.lefant.net/&lt;/a&gt;). i also use
the thumbnail export feature to create thumbnail galleries for use in
the debienna wiki (link:
&lt;a href=&quot;http://debienna.at/&quot;&gt;http://debienna.at/&lt;/a&gt;). the thumbnails on the
starting page are created dynamically for each page visit (try
reloading, see
&lt;a href=&quot;http://debienna.at/?action=raw&quot;&gt;http://debienna.at/?action=raw&lt;/a&gt; for
the page source and the &lt;span class=&quot;createlink&quot;&gt;&lt;a href=&quot;http://lefant.net/cgi-bin/ikiwiki.cgi?page=randomquote&amp;amp;from=logposts%2F2007-07-22---phpfspot&amp;amp;do=create&quot; rel=&quot;nofollow&quot;&gt;?&lt;/a&gt;RandomQuote&lt;/span&gt; hack) which uses the
&lt;a href=&quot;http://debienna.at/FotoFortunes&quot;&gt;FotoFortunes&lt;/a&gt; wiki page as its
source (warning, huge page). using phpfspots export feature i can now
create the content of the &lt;span class=&quot;createlink&quot;&gt;&lt;a href=&quot;http://lefant.net/cgi-bin/ikiwiki.cgi?page=fotofortunes&amp;amp;from=logposts%2F2007-07-22---phpfspot&amp;amp;do=create&quot; rel=&quot;nofollow&quot;&gt;?&lt;/a&gt;FotoFortunes&lt;/span&gt; page automatically after
selecting all pictures with the debienna tag.&lt;/p&gt;

&lt;p&gt;the same works with literal html for blog entries like this one. find
a thumbnail gallery of all my images tagged with &quot;screens&quot; below:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=573&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=573&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=578&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=578&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=894&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=894&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=895&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=895&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=896&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=896&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=897&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=897&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1044&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1044&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1046&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1046&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1050&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1050&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1061&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1061&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1062&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1062&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1063&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1063&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1830&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1830&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1831&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1831&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1832&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1832&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1833&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1833&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1834&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1834&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1835&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1835&amp;amp;width=150&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;http://gallery.lefant.net/phpfspot/index.php?mode=showp&amp;amp;id=1836&amp;amp;tags=74&quot;&gt;&lt;img src=&quot;http://gallery.lefant.net/phpfspot/phpfspot_img.php?idx=1836&amp;amp;width=150&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;i am happy, thanks unki!&lt;/p&gt;
</description>
	
	
</item>

</channel>
</rss>
