diff 7-Haskell/day2.hs @ 93:39084e2b8744

Add a function for word-aware text wrapping Potentially hugely inefficient because we iterate through the string character by character, but then splitting it first and iterating over words still needs to iterate over the string to know where to split.
author IBBoard <dev@ibboard.co.uk>
date Tue, 18 Jun 2019 21:05:00 +0100
parents 6f650dd96685
children
line wrap: on
line diff
--- a/7-Haskell/day2.hs	Mon Jun 17 20:50:43 2019 +0100
+++ b/7-Haskell/day2.hs	Tue Jun 18 21:05:00 2019 +0100
@@ -55,4 +55,23 @@
     -- Wilson's theorem seems easiest: https://en.wikipedia.org/wiki/Wilson%27s_theorem
     primes :: [Integer]
     -- Primes after 2 have to be odd (or else they're a multiple of 2!), so increment up the odd numbers
-    primes = 2 : [x | x <- [3, 5 ..], (mod ((product [1 .. x-1]) + 1) x) == 0]
\ No newline at end of file
+    primes = 2 : [x | x <- [3, 5 ..], (mod ((product [1 .. x-1]) + 1) x) == 0]
+
+    break_lines :: String -> Int -> [String]
+    break_lines str len = break_lines' str "" "" len []
+
+    break_lines' :: String -> String -> String -> Int -> [String] -> [String]
+    break_lines' "" "" "" _ strings = strings
+    break_lines' "" next_word line len strings = break_lines' "" "" "" len (strings ++ [line ++ next_word])
+    break_lines' (char:rest) next_word line len strings
+        | char == ' ' && candidate_length == len = break_lines' rest "" "" len (strings ++ [line ++ next_word]) -- if we've got a space at the right place, add the word but not the space
+        | char == ' ' = break_lines' rest "" (line ++ next_word ++ " ") len strings -- else we've got a break so add the word and the space to the line
+        -- Then, for non-space characters…
+        | candidate_length < len = break_lines' rest (next_word ++ [char]) line len strings -- if we're not at the line length then add the character
+        | candidate_length == len && line /= "" = break_lines' rest (next_word ++ [char]) "" len (strings ++ [line]) -- if we've got a partial line and our next word is getting too long then add the line as-is
+        | length next_word == len = break_lines' rest ("-" ++ [char]) "" len (strings ++ [next_word]) -- if our candidate is more than our length and we've got a blank line then add our N characters of this word, and hyphenate the word
+        | otherwise = break_lines' rest (next_word ++ [char]) line len strings -- otherwise we're within limits and can keep going
+        where candidate_length = (length next_word + length line)
+
+-- > break_lines "hello 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345 lorem ipsum bibbety bobbety boo once upon a time there was a cat and it sat on a mat while the quick brown fox jumped over the lazy dog" 80
+--   ["hello ","12345678901234567890123456789012345678901234567890123456789012345678901234567890","-12345 lorem ipsum bibbety bobbety boo once upon a time there was a cat and it ","sat on a mat while the quick brown fox jumped over the lazy dog"]--