module Main (main) where import Lib import qualified Data.Set as Set import qualified Data.Map as Map import Data.Either (rights, lefts) import Data.List (intercalate) parseInputLine :: Int -> String -> Either ParseError Expression parseInputLine n s = parseFullString ("stdin:" ++ show n) s title :: [String] -> String title ns = " " ++ intercalate " | " ns header :: [Int] -> String header ws = intercalate "|" . map (flip replicate '-' . (+2) ) $ ws row :: [Int] -> [Bool] -> String row ws rs = intercalate "|" $ (zipWith row' ws rs) where row' :: Int -> Bool -> String row' w b = replicate (left+1) ' ' ++ (if b then "1" else "0") ++ replicate (right+1) ' ' where left = (w-1) `div` 2 right = (w-1) - left main :: IO () main = do equation_strings <- fmap lines getContents let equation_expressions = zipWith parseInputLine [0..] equation_strings -- TODO: Show proper error messages _ <- mapM putStrLn . map show . lefts $ equation_expressions let variable_names = Set.toAscList . Set.unions . map collectVariableNames . rights $ equation_expressions let value_combinations = mapM (const [True, False]) [1..length variable_names] let value_maps = map Map.fromList $ zipWith (zipWith (,)) (cycle [variable_names]) value_combinations let expression_strings = variable_names ++ equation_strings let column_widths = map length expression_strings putStrLn . title $ expression_strings putStrLn . header $ column_widths let expressions = rights $ map (parseFullString "") variable_names ++ equation_expressions let results = map (\m -> map (evaluate m) expressions) value_maps mapM_ putStrLn . map (row column_widths) $ results