haskell - Handling complicated input (with nested values) -


there following task:

  1. first line number of cases
  2. for each case there line number of numbers add
  3. for each case there line numbers
  4. for each case have print summed numbers

example:

input: 2 5 1 2 3 4 5 2 -100 100  output: 15 0 

this implementation

import control.monad  main =      linescount <- readln :: io int     numbers <- replicatem linescount getcase     mapm_ putstrln $ map (show.sum) numbers  getcase :: io [int] getcase =     numberscount <- readln :: io int -- don't need variable     numbersstring <- getline     let numbers = map read $ words numbersstring     return numbers 

it looks lot of code parsing input. there tricks "compress" it? :)

if merely want make code shorter check out stack exchange community code golfing. fun , games.

if thinking there code may not need make shorter rather need make clearer. achieving matter of experience , practice. want isolate simple concepts correct , combine them in correct ways. methodologies include top-down design (break solution smaller pieces) , bottom-up design (from smaller pieces build solution) , mixes thereof.

a bottom-up piece hits me straight away task of summing list of numbers. has definition in haskell's prelude called sum :: (num a, foldable t) => t -> a. somewhere in final solution going use this.

another method simplify problem. can lead astray way problem phrased. upon closer inspection might find equivalent , simpler phrasing.

what information need input? lists of numbers. simplest way obtain lists of numbers? number of lists seems irrelevant because there no need have information before start looking @ lists. drop first line , left with:

5 1 2 3 4 5 2 -100 100 

then, length of each list irrelevant because not need information before summing list. therefore lets drop every other line point:

1 2 3 4 5 -100 100 

now have lists of numbers separated line returns each number separated space.

at point have clear way break apart solution in top-down manner. first simplify input. secondly parse lists of numbers. thirdly sum lists. fourthly print sums. therefore skeleton of our solution:

simplifyinput :: string -> [string]  parsenumberlist :: string -> [integer]  -- note can use `sum` prelude sum number lists.  printsums :: [integer] -> io ()  main :: io () main = getcontents >>= printsums . fmap (sum . parsenumberlist) . simplifyinput 

now matter of implementing each obvious piece of solution.

simplifyinput :: string -> [string] simplifyinput = dropeveryother . drop 1 . lines     dropeveryother :: [a] -> [a] 

in writing simplifyinput discovered dropping every other line requires more work. okay, can break solution apart again.

dropeveryother :: [a] -> [a] dropeveryother [] = [] dropeveryother (x:y:xs) = y : dropeveryother xs 

then continuing...

parsenumberlist :: string -> [integer] parsenumberlist = fmap read . words  printsums :: [integer] -> io () printsums = putstr . unlines . fmap show 

therefore, in totality:

simplifyinput :: string -> [string] simplifyinput = dropeveryother . drop 1 . lines     dropeveryother :: [a] -> [a]   dropeveryother [] = []   dropeveryother (_:y:xs) = y : dropeveryother xs  parsenumberlist :: string -> [integer] parsenumberlist = fmap read . words  printsums :: [integer] -> io () printsums = putstr . unlines . fmap show  main :: io () main = getcontents >>= printsums . fmap (sum . parsenumberlist) . simplifyinput 

the amount of code have has gone (compared first solution) in exchange code made obvious. should add documentation comments not forget our explanation solution.


Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -