module Main where

import Control.Arrow
import Control.Monad
import Data.Char
import Data.List
import Data.Maybe   (mapMaybe)
import System.IO
import System.Environment


type Word = String
type Pair = (Word, Word)

testdata :: [Word]
testdata = words "joan john jan ian jon eon join"

-- Number of letters difference between two words.
difference :: Word -> Word -> Int
difference w = length . filter id . zipWith (/=) w

-- Take N pairs of words which are the same
-- length and differ by at most one letter.
wordpairs :: [Word] -> [Pair]
wordpairs ws = [(w,v)| (w:vs) <- tails ws, v <- vs, difference w v < 2]

fingerspell :: Int -> Int -> IO ()
fingerspell wl p = do
    wordfile <- words `liftM` readFile "/usr/share/dict/words"
    let ws = map (map toLower) $ filter (requirements) wordfile
    mapM_ pretty $ take p $ wordpairs ws
  where requirements w = length w == wl && all (isAlpha) w

pretty :: Pair -> IO ()
pretty (x,y) = putStrLn $ x ++ ", " ++ y

main = do
    args <- getArgs
    case args of
        [wl, p] -> fingerspell (read wl) (read p)
        _       -> putStrLn "Usage: fingerspell <word length> <number of words>"


