Can you connect the dots? This challenge is based off of Flow Free.  An online version can be found here: http://www.moh97.us/

You will be given a puzzle, and you must return 1 if the puzzle is solvable, or 0 if it is not.

To solve a puzzle, the player must create a path to connect each pair of numbers using every empty square exactly once.

You are passed in the dimensions of the square, and then the x,y,c (where c is a number representing the color) of each dot.  For example:

If 5,5 0,0,0 3,0,1 1,1,2 1,2,2 4,2,1 4,4,0 was passed to you, it would represent:

0..1.
.2...
.2..1
....0


And should return 1.

Here are some more test problems:

5,2 2,0,1 0,1,2 4,1,2 represents:

..1..
2...2


and is not solvable because there is only 1 1.

4,2 0,0,0 3,0,0 0,1,0 3,1,0 represents:

0..0
0..0


and is not solvable because it includes more than 2 0s.

8,6 0,0,1 7,5,1 represents:

1.......
........
........
........
........
.......1


and is not solvable (as you can't use every square).

2,5 0,0,1 2,0,6 4,0,6 0,1,4 3,1,4 4,1,1 represents:

1.6.6
4..41


and is not solvable because you cannot connect the 1s.

6,3 1,0,4 5,0,1 0,1,4 1,1,3 5,1,3 0,2,2 3,2,2 5,2,1 represents:

.4...1
43...3
2..2.1


and is not solvable because you cannot connect the 1s (or the 3s), as the two paths must necessarily cross.

5,2 0,0,1 3,0,1 0,1,3 4,1,1 represents:

1..1.
3...3


and is not solvable because you cannot use all of the squares in building a path.

2,2 0,0,0 1,1,0 represents:

1.
.1


and is not solvable because you can't use all of the squares here either

Here are some more tests:

5,5 0,3,0 0,4,1 1,2,2 1,3,1 2,0,0 3,0,4 3,1,2 3,3,5 3,4,4 4,4,5 should return 1

13,13 1,1,0 9,1,1 10,1,2 11,1,3 1,2,4 2,2,5 5,2,6 7,2,7 3,3,0 5,4,6 6,4,1 9,6,3 4,7,8 5,8,9 12,8,8 11,9,10 2,10,4 4,10,2 9,10,5 11,10,7 1,11,9 12,12,10 should return 1

7,7 0,0,0 0,1,1 1,1,2 2,1,3 4,2,4 0,3,1 5,3,3 0,4,4 2,4,5 5,4,2 0,5,0 1,5,5 3,5,6 3,7,6 should return 0

This is a code golf, and the standard rules apply.
Haskell

import Data.List.Split
import qualified Data.Sequence as Q
import Data.List
import Control.Monad

data A a = S a | E a | P a | X deriving Eq

sc = foldr1 (Q.&gt;&lt;)
sp b x y p = Q.update y (Q.update x p $ b `Q.index` y) b
dt b c | S c `elem` sc b = E c
       | otherwise = S c
ad b [x, y, c] = sp b x y (dt b c)

ep b [x, y, c] = do
  let nps = filter ob [(x+1, y), (x-1, y), (x, y+1), (x, y-1)]
      ns = map gp nps
  [b | E c `elem` ns] ++ do
    (x', y') &lt;- filter ((== X) . gp) nps
    ep (sp b x' y' (P c)) [x', y', c]
  where ob (u, v) = 0 &lt;= u &amp;&amp; u &lt; length (b `Q.index` 0) &amp;&amp; 0 &lt;= v &amp;&amp; v &lt; length b
        gp (u, v) = b `Q.index` v `Q.index` u

rd i = let [c, r] : ps = (map read . splitOn ",") &lt;$&gt; words i :: [[Int]]
           e = Q.replicate r $ Q.replicate c X
           cs = map last ps
           ss = nubBy (\[_,_,c1] [_,_,c2] -&gt; c1 == c2) ps
           b = foldl ad e ps
           bs = foldM ep b ss
       in if even (length cs) &amp;&amp; length ss == length cs `div` 2 &amp;&amp;
             (all (\[j,k] -&gt; j==k) . chunksOf 2 . sort $ cs) &amp;&amp;
             any (null . Q.elemIndicesL X . sc) bs
           then 1
           else 0

main = rd &lt;$&gt; getContents &gt;&gt;= print


Key


sc: Seq concat
sp: set position
dt: dot type (ie, start or end of line)
ad: add dot
ep: extend path
rd: run dots (primary pure algorithm)