I have written my very first Haskell module and I feel that the code can be improved based on the simplicity of the problem I am solving. Do you have any suggestions?
Problem statement:
You are given a String code containing a message composed entirely of decimal digits ('0'-'9'). Each digit consists of some number of dashes (see diagram below). A "check function" of a message is defined as the total number of dashes in the message. Return the value of the check function for the message represented in code.
Definition
Class: CheckFunction
Method: newFunction
Parameters: String
Returns: int
Method signature: int newFunction(String code)
(be sure your method is public)
Notes
- 0 consists of 6 dashes, 1 consists of 2 dashes, 2 consists of 5 dashes, 3 consists of 5 dashes, 4 consists of 4 dashes, 5 consists of 5 dashes, 6 consists of 6 dashes, 7 consists of 3 dashes, 8 consists of 7 dashes, 9 consists of 6 dashes.
Constraints
- code will contain between 1 and 50 characters, inclusive.
- Each character in code will be a digit ('0'-'9').
Solution:
module Main where
import System.IO()
import Data.Char
-- Problem statement: https://community.topcoder.com/stat?c=problem_statement&pm=4788
-- Method signature: int newFunction(String code)
newFunction :: String -> Int
newFunction input =
let arr = [6, 2, 5, 5, 4, 5, 6, 3, 7, 6]
x = [arr !! digitToInt (input !! x) | x <- [0..length input - 1]]
in sum x
assert :: String -> Int -> String
assert s i = if newFunction s == i
then "test passed" else "test failed"
main :: IO()
main = do
putStrLn $ show $ assert "13579" 21
putStrLn $ show $ assert "868177" 28
putStrLn $ show $ assert "8571" 17
putStrLn $ show $ assert "3" 5
putStrLn $ show $ assert "73254370932875002027963295052175" 157
-
\$\begingroup\$ Please include problem statement in the question (or your re-wording of it) \$\endgroup\$Caridorc– Caridorc2015年11月22日 13:56:21 +00:00Commented Nov 22, 2015 at 13:56
-
\$\begingroup\$ I have already included a link of the problem statement. Do you need more information? \$\endgroup\$Orestis– Orestis2015年11月22日 13:59:23 +00:00Commented Nov 22, 2015 at 13:59
-
\$\begingroup\$ it is a site policy we do not like relying on external website as they may go down and if they do our pages lose meaning Thanks \$\endgroup\$Caridorc– Caridorc2015年11月22日 14:05:01 +00:00Commented Nov 22, 2015 at 14:05
1 Answer 1
Take items directly from the thing, without indexing:
x = [arr !! digitToInt i | i <- input]
And prefer where
over let
: (where
is so much more common than let
, it is easier to read as you see the general picture before the details.)
newFunction input = sum [arr !! digitToInt i | i <- input]
where
arr = [6, 2, 5, 5, 4, 5, 6, 3, 7, 6]
arr
is a bad name, I would prefer dashesInDigits
assert
should be more general (take f
as argument) and written using guards.
-
\$\begingroup\$ Is it better to use " ^? element " from lens package instead of " !! "? \$\endgroup\$Orestis– Orestis2015年11月22日 16:28:54 +00:00Commented Nov 22, 2015 at 16:28
-
1\$\begingroup\$ @Orestis in this case you may consider
lookup
that also works for non-number keys \$\endgroup\$Caridorc– Caridorc2015年11月22日 16:37:47 +00:00Commented Nov 22, 2015 at 16:37