Skip to content

Instantly share code, notes, and snippets.

@squidarth
Created April 9, 2018 01:43
Show Gist options
  • Save squidarth/6b5daf35c80800d9d4a05245b4fa1f0d to your computer and use it in GitHub Desktop.
Save squidarth/6b5daf35c80800d9d4a05245b4fa1f0d to your computer and use it in GitHub Desktop.
Haskell program to consistently print lines
import System.Environment
import Data.List.Split
import Data.List
import Data.List.Utils (replace)
import Data.String.Utils (strip)
getStringList :: String -> [String]
getStringList str = splitOn " " str
-- costAtJ is the cost incurred by placing a newline
-- after j.
costAtJ :: [String] -> Int -> Int -> Int -> Int
costAtJ list max_line_length i j
| lineLength > max_line_length = (maxBound :: Int)
| otherwise = previous_cost + extra_space ^ 2
where lineLength = length (intercalate " " (drop j (take i list)))
previous_cost :: Int
previous_cost
| j == 0 = 0
| otherwise = costOf j list max_line_length
extra_space = max_line_length - lineLength
-- costOf i refers to the minimum cost if linebreak
-- is placed after the ith word.
costOf :: Int -> [String] -> Int -> Int
costOf i list max_line_length
| i == 0 = 0
| otherwise = minimum costAtEachJ
where costAtEachJ = map (costAtJ list max_line_length i) [0..i-1]
minExtraSpaceCost :: [String] -> Int -> Int
minExtraSpaceCost list max_line_length =
costOf (length list) list max_line_length
main = do
[lineLengthRaw, fileName] <- getArgs
contents <- readFile fileName
let maxLineLength = read lineLengthRaw :: Int
let strippedString = replace "\n" " " (strip contents)
putStr (show (minExtraSpaceCost (getStringList strippedString) maxLineLength))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment