CodeEval FizzBuzz
Quick Description:
Take 1 command line argument of a file-path. This file will contain test cases formatted as such 3 space separated numbers per line. For numbers
X
,Y
andZ
you must print out all numbers between 1 and Z, space separated, replacing all numbers divisible byX
with 'F
' and all numbers divisible byY
with 'B
'.
I am entirely new to Functional programming, and my Haskell knowledge is from a single Pluralsight class, so I am looking for any amount of feedback, particularly for best practices. I also feel like the actual fizzBuzzSingle
function can be solved in a list comprehension instead, but I'm still uncomfortable with the syntax so I didn't use one.
If my code is reading too object-oriented please let me know. I also did look up the other FizzBuzz questions on this site, but they all seem to not being handling file input, which seemed the hardest part to me, so it seemed worth posting this.
import System.Environment
fizzBuzzSingle :: Int -> Int -> Int -> String
fizzBuzzSingle f b n
| n `mod` f == 0 && n `mod` b == 0 = "FB"
| n `mod` f == 0 = "F"
| n `mod` b == 0 = "B"
| otherwise = show n
fizzBuzz :: (Int, Int, Int) -> [String]
fizzBuzz (f,b,end) = map (fizzBuzzSingle f b) [1..end]
convertInputLine :: String -> (Int, Int, Int)
convertInputLine x = packageInputs ((map read . words) x :: [Int])
packageInputs :: [Int] -> (Int, Int, Int)
packageInputs [f,b,end] = (f, b, end)
concatOutput :: [String] -> String
concatOutput (x : xs) =
foldl (\x y -> x ++ " " ++ y) x xs
handleFizzBuzz :: [String] -> [String]
handleFizzBuzz [] = []
handleFizzBuzz (x : xs) =
(concatOutput . fizzBuzz . convertInputLine $ x) : handleFizzBuzz xs
main :: IO ()
main = do
args <- getArgs
let path = args !! 0
file <- readFile path
putStrLn . unlines . handleFizzBuzz . lines $ file