tables-hs

import System.Environment (getArgs)

showIntAtBase :: Int -> (Int -> String) -> Int -> String
showIntAtBase b rep i
  | n == 0 = rep r
  | otherwise = showIntAtBase b rep n ++ rep r
  where
    (n,r) = quotRem i b

showBase :: Int -> Int -> String
showBase b i =
  let r = showIntAtBase b repr i
      pad = 2
      in
        if length r < pad
          then replicate (pad-length r) ' ' ++ r
          else r

table :: (Int -> Int -> Int) -> Int -> Int -> String
table op base start
  | start<base = "| " ++ showBase base start ++ " " ++ row op base 0 start ++ "\n" ++ table op base (start+1)
  | otherwise  = "\n"

row :: (Int -> Int -> Int) -> Int -> Int -> Int -> String
row op base start i
  | start<base = "| " ++ showBase base (op start i) ++ " " ++ row op base (start+1) i
  | otherwise  = "|"

repr :: Int -> String
repr i
  | i<length rs = [rs !! i]
  | otherwise = "[" ++ show i ++ "]"
  where rs = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

mdTable :: (Int -> Int -> Int) -> Int -> String
mdTable op base =
   "|    " ++ row (*) base 0 1 ++ "\n" ++
   "|" ++ concat (replicate (base+1) ":--:|") ++ "\n" ++
   table op base 0

main :: IO ()
main = do
  args <- getArgs
  let base = (read $ head args) :: Int
  putStrLn $ mdTable (+) base
  putStrLn $ mdTable (*) base