Haskell list of int tuples to string - string

I'm trying to write out my list of tuples from:
[(8,7),(5,6),(3,3),(9,4),(5,4)]
to:
8 7 5 6 3 3 9 4 5 4
this is how far i've come:
(Updated)
showTuples :: Board -> String
showTuples = unwords . fmap show . concatMap (\(x,y) -> [x,y])
I know i'm suppose to map this function to all elements of my list but i can't seem to get it right.
(UPDATE)
It worked, still having problems with the quotation marks though
also type of Board is:
type Board = [(Int,Int)]

Using pattern matching:
type Board = [(Int, Int)]
showTuples :: Board -> String
showTuples [] = ""
showTuples (x:[]) = show(fst(x)) ++ " " ++ show(snd(x))
showTuples (x:xs) = show(fst(x)) ++ " " ++ show(snd(x)) ++ " " ++ showTuples xs
main :: IO ()
main = putStrLn . showTuples $ [(8, 7), (5, 6), (3, 3), (9, 4), (5, 4)] -- 8 7 5 6 3 3 9 4 5 4

This can be done by a foldl too.
Prelude> foldl (\r (x,y) -> r ++ " " ++ show x ++ " " ++ show y) "" [(8,7),(5,6),(3,3),(9,4),(5,4)]
" 8 7 5 6 3 3 9 4 5 4"
If you don't want the preceding whitespace then just do like tail $ foldl (\r (x,y) -> ...

Related

Suggestion on the hackerRank solution about alphabets and weight

I have solved the designer pdf question with haskell. The code works. I am posting the code here to know how I could have done it better.
First line contains the weight of each alphabet
Second line contains the word.
Sample input
1 3 1 3 1 4 1 3 2 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 7
zaba
Output
28
explanation each character would take 1 space and multiply it with the max weight
4 characters * 1 space * 7 weight = 28
'z' has the max weight of 7.
Code
import Data.List
import Data.Maybe
getintval::(Maybe Int) -> Int
getintval Nothing = 1
getintval (Just x) = x
solve'::[Char]->[(Char, Int)] -> Int
solve' ch lst = k $ map getintval $ map (\x -> finder' x) ch
where
k::[Int] -> Int
k fb = (*) (length ch) $ foldl (\acc x -> max acc x) 1 fb
finder'::Char -> Maybe Int
finder' g = case i of
Just(x1,x2) -> Just x2
Nothing -> Just 1
where i = find(\(val1, val2) -> val1 == g) lst
solve::[Char] -> [Char] -> Int
solve wght val = solve' val rec
where
rec::[(Char, Int)]
rec = zipWith (\x y -> (x, y)) ['a'..'z'] word1
word1::[Int]
word1 = map(read::String->Int) $ words wght
main::IO()
main = do
weight <- getLine
pdfstr <- getLine
putStr . show $ solve weight pdfstr
All the test on HackerRank are success

Haskell - 2D List of Ints to String

I'm looking to convert a 2D list to a formatted string.
table :: [[Int]] -> String
Input: [[11,2,30],[4,555,9]]
Output: " 11 2 30 \n 4 555 6 \n"
11 2 30
4 555 9
Basically would need to be able to print out in a grid-shape and maintain formatting to account for the max value.
I know for simple lists I can map show [1,2,3,4] -> ["1","2","3","4"] according to ghci. That seems to keep it as a list though?
Not sure how I can traverse the 2D and keep concatenating as a string and adding \n as needed.
Playing at the REPL can help.
> :t '1'
'1' :: Char
> :t "1"
"1" :: [Char]
> ['1','2']
"12" :: [Char]
> :t concat
concat :: [[a]] -> [a]
> concat ( map show [1,2,3,4] )
.....
> concat [ show x | x <- [1,2,3,4] ]
.....
> concat [ " " ++ ( ensureWidth 9 (show x) ) | x <- [1,2,3,4] ]
.....
> :t replicate
replicate :: Int -> a -> [a]
> replicate 2 '1'
"11" :: [Char]
Now you need to write the function
ensureWidth w s = replicate n ' ' ++ s
but what n to use? You will need to know the length of s, for that. Function length can help.

rotate a string in haskell with some exceptions

I want to rotate a string in haskell, so if I give "Now I want to scream" to rotate [[want to scream now I],[scream now I want to]] , if the string start with "I" or "to" then must eliminate it. Till now I still have problems with the rotation.
reverseWords :: String -> String
reverseWords = unwords . reverse . words
shiftt :: [a] -> Int -> [a]
shiftt l n = drop n l ++ take n l
rot::String->[String]
rot l = [ reverseWords l i | i <- [0 .. (length l) -1]]
create a list of all rotations, then filter out based on your predicate. For example,
rotations x = take (length x) $ iterate rot1 x
where rot1 = drop 1 x ++ take 1 x
filteredRots = map unwords . filter (\x -> length (head x) > 2) . rotations . words
and use as
> filteredRots "Now I want to scream"
["Now I want to scream","want to scream Now I","scream Now I want to"]
Prelude>

Foldr issues (Haskell)

I'm trying to convert from a table which is of type ([Char, Int]) to a string tab2str :: Table -> String (that follows some specific formatting patterns.)
I'm using foldr (as the title implies) but I'm having some issues getting the exact function to work - i.e. It errors. My function looks like this:
tab2str xs = foldr (++) ' ' $ map (\char count -> show char ++ ':' ++ show count ++ '\n') xs
The output should be each letter in the table, a colon, then \n. So a test might be:
tab2str test1 == "F: 1\no: 1\nl: 1\nd: 1\nr: 1\n"
where
test1 == [(F, 1), (o, 1), (l, 1), (d, 1), (r, 1)]
Any help gratefully received.
After minimal corrections this typechecks:
tab2str xs = foldr (++) " " $ map (\(char, count) -> show char ++ ":" ++ show count ++ "\n") xs
– but produces not quite what you want.
You'll probably like this better:
tab2str table = concat $ map formatRow table
where formatRow (char, count) = [char] ++ ": " ++ show count ++ "\n"
Then your test example:
ghci> let test1 = [('F', 1), ('o', 1), ('l', 1), ('d', 1), ('r', 1)]
ghci> tab2str test1
"F: 1\no: 1\nl: 1\nd: 1\nr: 1\n"
ghci> putStr $ tab2str test1
F: 1
o: 1
l: 1
d: 1
r: 1
ghci>

Haskell Printing a List with some formatting

Just started learning Haskell a few days ago and I've come across a few issues. The first issue deals with printing a list of numbers. The desired behavior is as follows:
input: [1,2,3,4,5,6]
output: 1 2 3 | 4 5 6
So its a simple concept, I just need to output the elements of a list with the "|" symbol inserted between every three numbers, but I can't for the life of me figure it out. It seems like most of the stuff I've tried involves strings and even if I were able to get the list to strings such as ["1", "2", "3", ...] all the methods I've tried print the numbers each on their own line which is not what I need.
Any help would be greatly appreciated.
Using the split package (recently added to the Haskell Platform):
> import Data.List -- for intercalate
> import Data.List.Split -- for chunksOf
> intercalate " | " . map unwords . chunksOf 3 $ map show [1..7]
"1 2 3 | 4 5 6 | 7"
Relevant documentation: chunksOf, unwords, intercalate.
Here's one way.
import Data.List (cycle)
format :: Show a => [a] -> String
format = concat . zipWith (++) ("" : cycle [" ", " ", " | "]) . map show
This does has the drawback that the grouping into groups of three is hard-coded, but it is not too difficult to generalise.
You could do
threes [] = ""
threes xs = let (front,rest) = splitAt 3 xs in
unwords (map show front) ++
if null rest then "" else " | " ++ threes rest
giving
*Main> threes [1..10]
"1 2 3 | 4 5 6 | 7 8 9 | 10"
Functions I used:
splitAt :: Int -> [a] -> ([a], [a])
-- splitAt 2 "Hello Mum" = ("He","llo Mum")
unwords :: [String] -> String
-- unwords ["Hello","there","everyone"]
-- = "Hello there everyone"
null :: [a] -> Bool
null [] = True
null _ = False
The first part is the easiest, you need to convert the numbers to Strings,
format :: (Num a, Show a) => [a] -> String
format xs = result
where
strings = map show xs
does that. Then we need to split any list into chunks of three (more general, n) elements. splitAt splits a list into a front part of the desired number of elements - if the list is long enough - and a remainder. Iterating the procedure on the remainder, while that is not empty leads to the desired result.
chunk :: Int -> [a] -> [[a]]
chunk _ [] = []
chunk n xs = ys : chunk n zs
where
(ys, zs) = splitAt n xs
That is a recurring pattern, so there is a combinator for that, and we could also write
import Data.List (unfoldr)
chunk :: Int -> [a] -> [[a]]
chunk n = unfoldr split
where
split [] = Nothing
split xs = Just $ splitAt n xs
So we can continue our format,
format :: (Num a, Show a) => [a] -> String
format xs = result
where
strings = map show xs
chunks = chunk 3 strings
Then we need to insert a "|" between all chunks, that is done by intercalate from Data.List, and finally, concatenate all strings with spaces between them, that's what unwords does, so
format :: (Num a, Show a) => [a] -> String
format xs = result
where
strings = map show xs
chunks = chunk 3 strings
result = unwords $ intercalate "|" chunks
Or
format = unwords . intercalate "|" . chunk 3 . map show

Resources