import Data.List import Data.Ord import Text.Printf main = do putStrLn $ unlines [printf "%d/%d\t%.5f\t%.5f\t%d\t%s" p q (fromIntegral p / fromIntegral q :: Double) (sqrt 3 / (1 + 2*fromIntegral q/fromIntegral p) :: Double) (length w) w | ((p,q),w) <- wordlist, length w <= 100] wordlist = nub $ sortBy (comparing sl) [((p `div` gcd p q, q `div` gcd p q), slopeWord p q) | p <- [0..50], q <- [1..50], p <= q] where sl ((p,q),_) = fromIntegral p / fromIntegral q -- only allows slopes 0 <= p/q <= 1 slopeWord :: Int -> Int -> String slopeWord p q = concat $ map word $ zipWith step list (tail list) where p_ = p `div` gcd p q q_ = q `div` gcd p q xmax = if (p_ - q_) `mod` 3 == 0 then q_ else 3*q_ list = [(x,y) | x <- ([0..xmax] :: [Int]), let y = floor (fromIntegral x*fromIntegral p/fromIntegral q)] step :: (Int,Int) -> (Int,Int) -> (Int,Int) step (x1,y1) (x2,y2) = ((x1-y1) `mod` 3, y2 - y1) word :: (Int,Int) -> String word (0,0) = "bc" word (1,0) = "ab" word (2,0) = "ca" word (0,1) = "baca" word (1,1) = "acbc" word (2,1) = "cbab"