Skip to content

Instantly share code, notes, and snippets.

@PkmX
Last active December 18, 2015 05:09
Show Gist options
  • Save PkmX/5730947 to your computer and use it in GitHub Desktop.
Save PkmX/5730947 to your computer and use it in GitHub Desktop.
import Control.Applicative ((<$>))
import Data.Function (on)
import Data.List (find, nubBy)
import Data.List.Utils (split)
import Data.Maybe (fromMaybe)
import Data.Ord (comparing)
import System.Environment (getArgs)
import System.IO (stdin, hGetContents, openFile, IOMode(ReadMode))
data SetOp = SetRow { row :: Int, val :: Int } | SetCol { col :: Int, val :: Int }
isSetRow (SetRow _ _) = True
isSetRow _ = False
isSetCol (SetCol _ _) = True
isSetCol _ = False
index (SetRow r _) = r
index (SetCol c _) = c
query isSetAll isSetOne ops which =
let base = fromMaybe 0 $ val <$> find (isSetAll which) ops
cols = nubBy (on (==) index) . filter isSetOne . takeWhile (not . isSetAll which) $ ops
in base * (256 - length cols) + sum (map val cols)
queryRow = query (\r -> \op -> isSetRow op && row op == r) isSetCol
queryCol = query (\c -> \op -> isSetCol op && col op == c) isSetRow
process = reverse . fst . foldl f ([],[]) . lines
where f (res, acc) cmd =
case split " " cmd of
"SetRow" : row : val : [] -> (res, SetRow (read row) (read val) : acc)
"SetCol" : col : val : [] -> (res, SetCol (read col) (read val) : acc)
"QueryRow" : row : [] -> (queryRow acc (read row) : res, acc)
"QueryCol" : col : [] -> (queryCol acc (read col) : res, acc)
_ -> error "Invalid command"
main = getArgs >>= getHandle >>= hGetContents >>= (mapM_ print . process)
where getHandle args = if null args then return stdin else openFile (head args) ReadMode
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment