Define a function nohundred :: Int -> Int such that for a positive number n nohundred n is the nth positive number such that "100" does not occur as a substring in its binary expansion.
decToBin :: Int -> [Int]
decToBin x = reverse $ decToBin' x
where
decToBin' :: Int -> [Int]
decToBin' 0 = []
decToBin' y = let (a,b) = quotRem y 2 in [b] ++ decToBin' a
check :: [Int] -> Bool
check (z:zs)
|((z == 1) && (head (zs) == 0) && (head (tail zs) == 0)) = True
| otherwise = check zs
binToDec :: [Int] -> Int
binToDec l = sumlist (zipWith (*) (iterate f 1) (reverse l))
where
sumlist :: [Int] -> Int
sumlist [] = 0
sumlist (x:xs) = x + (sumlist xs)
f :: Int -> Int
f j = (2 * j)
nohundred :: Int -> Int
nohundred n = if ((check fun) == True) then (binToDec (fun)) else (nohundred (n+1))
where
fun = decToBin n
The above code gives error :-
*Main> nohundred 10
*** Exception: Prelude.head: empty list...
The desired output is 14.
*Main> nohundred 100
100
The desired output is 367...
Can anyone suggest the cause of error?
This function is partial:
check (z:zs)
|((z == 1) && (head (zs) == 0) && (head (tail zs) == 0)) = True
| otherwise = check zs
When called with a one- or two-element list, the first check will call head on an empty list. Additionally, it does not cover the empty-list case. The idiomatic way to write this is:
check (1:0:0:zs) = True
check (z:zs) = check zs
check [] = False
Additionally, your nohundred function takes a number and finds the next higher non-hundred number; but you want the nth non-hundred number, which is a very different thing.
the problem is to check whether parentheses in a string is properly closed or not. For Haskell implementation, so far I have following. It looks quite awkward. I am looking for a more "Haskell-style" or more elegant implementation.
import Data.List
isValidParentheses :: String -> Bool
isValidParentheses = isValidHelper . (filter isParenthese)
getIndex :: (Eq a) => a -> [a] -> Int
getIndex c xs = getOut (elemIndex c xs)
where getOut (Just x) = x
getOut Nothing = -1
isLeftParenthese :: Char -> Bool
isLeftParenthese c = (getIndex c "{[(") /= -1
isRightParenthese :: Char -> Bool
isRightParenthese c = (getIndex c "}])") /= -1
isParenthese :: Char -> Bool
isParenthese c = isLeftParenthese c || isRightParenthese c
isValidHelper :: String -> Bool
isValidHelper xs = helper xs []
where helper (x:xs) [] | isRightParenthese x = False
| otherwise = helper xs [x]
helper [] st = null st
helper (x:xs) (s:ss) | isLeftParenthese x = helper xs (x:s:ss)
| ((getIndex x "}])") /= (getIndex s "{[(")) = False
| otherwise = helper xs ss
Thanks
Loop through the string
Store opening parentheses in stack
Pop matching parentheses out of the stack
Check if stack is empty at the end
isValid = loop []
where
match '(' ')' = True
match '{' '}' = True
match '[' ']' = True
match _ _ = False
loop st [] = null st
loop st (x:xs)
| x `elem` "([{" = loop (x:st) xs
| x `elem` ")]}" = case st of
open : st' | match open x -> loop st' xs
_ -> False -- unmatched close
| otherwise = loop st xs
Given a list such as [1,0,0,0,3,0,0,0,0,2,4,0,0] and an index, how can I extract consecutive patterns of 0 in Haskell. For example if the given index is between 1 and 3 inclusive, the result is [0,0,0] if it is between 5 and 8 [0,0,0,0] and so on
First, build a list where run lengths are stored for each number:
runs :: (Eq a) => [a] -> [(a, Int)]
runs = map (head &&& length) . group
so e.g.
runs [1,0,0,0,1,0,0,0,0,1,1,0,0] == [(1,1),(0,3),(1,1),(0,4),(1,2),(0,2)]
Then, index into this list by walking it in run length-sized steps:
indexRuns :: Int -> [(a, Int)] -> [a]
indexRuns i [] = error "Index out of bounds"
indexRuns i ((x, l):rs)
| i < l = replicate l x
| otherwise = indexRuns (i - l) rs
You can do this in O(n) time:
extract :: Eq a => Int -> [a] -> [a]
extract _ [] = []
extract idx (x:xs) = extract' x [x] 1 xs
where
extract' _ _ _ [] = [] -- Index out of bounds
extract' v vs n (r : rest)
| idx == n = vs ++ (takeWhile (== v) rest)
| (v == r) = extract' v (r:vs) (n+1) rest
| otherwise = extract' r [r] (n+1) rest
This will count the number of zeros around the index
numZeros::Int->[Int]->Int
numZeros 0 (1:_) = 0
numZeros i (1:rest) = numZeros (i-1) rest
numZeros i theList
| i < zeroLen = zeroLen
| otherwise = numZeros (i-zeroLen) $ drop zeroLen theList
where
zeroLen = length (takeWhile (==0) theList)
You can replicate 0 the appropriate number of times to get the final list.
f = f' (takeWhile (== 0)) where
f' c n xs | n < 0 || null xs = []
f' c n (1:xs) = f (n - 1) xs
f' c 0 xs = c xs
f' c n (0:xs) = f' ((0:) . c) (n - 1) xs
Or even more obfuscated
f n xs = g (splitAt n xs) >>= takeWhile (== 0) where
g (xs, ys#(0:_)) = [reverse xs, ys]
g _ = []
Some tests:
main = mapM_ (\i -> print $ (i, f i [1,0,0,0,1,0,0,0,0,1,1,0,0])) [-1..13]
prints
(-1,[])
(0,[])
(1,[0,0,0])
(2,[0,0,0])
(3,[0,0,0])
(4,[])
(5,[0,0,0,0])
(6,[0,0,0,0])
(7,[0,0,0,0])
(8,[0,0,0,0])
(9,[])
(10,[])
(11,[0,0])
(12,[0,0])
(13,[])
implementing getReturnList and getReturnList2
getReturnList is for calculating return a/b in once
getReturnList2 is for advanced version using divide and conquer in parallel to increase
the speed to calculate return a/b that means it want to calculate in parallel in different
sublist of whole list
First error I do not understand that i pass x : [] to parameter [String]
compiler return this error
error for getReturnList
readcsv.hs:108:20:
Couldn't match type `Char' with `[Char]'
Expected type: [String]
Actual type: String
In the return type of a call of `getClose'
In the first argument of `(:)', namely `(getClose (x : []))'
In the expression:
(getClose (x : [])) : getReturnList (n - 1) total xs
readcsv.hs:108:30:
Couldn't match type `[Char]' with `Char'
Expected type: String
Actual type: [String]
In the first argument of `(:)', namely `x'
In the first argument of `getClose', namely `(x : [])'
In the first argument of `(:)', namely `(getClose (x : []))'
code:
import Control.Monad.Par
import Text.ParserCombinators.Parsec
import Data.Either.Unwrap
import System.IO
{- A CSV file contains 0 or more lines, each of which is terminated
by the end-of-line character (eol). -}
csvFile :: GenParser Char st [[String]]
csvFile =
do result <- many line
eof
return result
-- Each line contains 1 or more cells, separated by a comma
line :: GenParser Char st [String]
line =
do result <- cells
eol -- end of line
return result
-- Build up a list of cells. Try to parse the first cell, then figure out
-- what ends the cell.
cells :: GenParser Char st [String]
cells =
do first <- cellContent
next <- remainingCells
return (first : next)
-- The cell either ends with a comma, indicating that 1 or more cells follow,
-- or it doesn't, indicating that we're at the end of the cells for this line
remainingCells :: GenParser Char st [String]
remainingCells =
(char ',' >> cells) -- Found comma? More cells coming
<|> (return []) -- No comma? Return [], no more cells
-- Each cell contains 0 or more characters, which must not be a comma or
-- EOL
cellContent :: GenParser Char st String
cellContent =
many (noneOf ",\n")
-- The end of line character is \n
eol :: GenParser Char st Char
eol = char '\n'
parseCSV :: String -> Either ParseError [[String]]
--parseCSV :: String -> [[String]]
--parseCSV input = parse csvFile input
parseCSV input = parse csvFile "(unknown)" input
take3 :: Int ->[[String]] -> [String]
take3 0 _ = []
take3 _ [] = []
take3 n (x:xs)
| n == 1 = x
| n > 0 = take3 (n-1) xs
take3 _ _ = error "preludelist.take: negative argument"
returnlimiters = ['\n']
realtake2 :: Int -> [[String]] -> [String]
realtake2 x y = take3 x y
takeelem3 :: Int -> [String] -> String
takeelem3 0 _ = []
takeelem3 _ [] = []
takeelem3 n (x:xs)
| n == 1 = x
| n > 0 = takeelem3 (n-1) xs
takeelem3 _ _ = error "preludelist.take: negative argument"
realtakeelem2 :: Int -> [String] -> String
realtakeelem2 x y = takeelem3 x y
getOpen :: [String] -> String
getOpen x = realtakeelem2 2 x
getHigh :: [String] -> String
getHigh x = realtakeelem2 3 x
getLow :: [String] -> String
getLow x = realtakeelem2 4 x
getClose :: [String] -> String
getClose x = realtakeelem2 5 x
whitespace :: String
whitespace = ['\n','\t',' ']
forloop3 0 f = return()
forloop3 n f =
do
f n
forloop3 (n-1) f
getReturnList :: Int -> Int -> [[String]] -> [[String]]
getReturnList 0 _ _ = []
getReturnList _ _ [] = []
getReturnList n total (x:xs)
| n == total = getReturnList (n-1) total xs
| n > 0 = (getClose (x : [])) : getReturnList (n-1) total xs
getReturnList _ _ _ = error "preludelist.take: negative argument"
getReturnList2 :: Int -> Int -> [[String]] -> [[String]]
getReturnList2 0 _ _ = []
getReturnList2 _ _ [] = []
getReturnList2 n total (x:xs)
| n == total = getReturnList2 (n-1) total xs
| n > 0 =
do
p1 <- spawn (getReturnList2 n-1 total (filter (<x) xs))
p2 <- spawn (getReturnList2 n-1 total (filter (>=x) xs))
left <- get p1
right <- get p2
return $ left ++ (x:right)
getReturnList2 _ _ _ = error "preludelist.take: negative argument"
main = do
csvstring <- readFile "C:\\Users\\martin.lee\\Downloads\\0388.HK.csv"
let afterparse = parseCSV csvstring
let afterparse2 = fromRight afterparse
--putStrLn(show afterparse2)
let getline3 = realtake2 3 afterparse2
putStrLn(show getline3)
--putStrLn(getOpen getline3)
--putStrLn(getHigh getline3)
--putStrLn(getLow getline3)
putStrLn(getClose getline3)
--forloop3 5 (\c -> putStrLn(show (5-c)))
--putStrLn(show (take2b 3 2 3 afterparse2))
--let (as,bs) = splitAt (length grids `div` 2) afterparse2
let num = 5
putStrLn("begin getReturnList")
putStrLn(show ( "a" : []))
putStrLn(show (getReturnList 3 3 afterparse2))
putStrLn("end getReturnList")
--putStrLn(show (1 :: Float))
--putStrLn(show (getlines2 csvstring))
--putStrLn(show (take 1 (getlines2 csvstring)))
putStrLn("a")
update:
F# non-parallel version
let rec test2(xs : float list) =
if xs.Length > 3 then
let (list1, list2) = split1 (xs.Length/2) xs
let (list3, list4) = split1 (xs.Length/2-1) xs
let b1 = test2(list1) // would like to parallel these two function
let b2 = test2(list4) // would like to parallel these two function
b1 # b2
else
let b1 = xs |> Seq.windowed 2
|> PSeq.map (fun x -> x.[0]/x.[1])
|> PSeq.toList
b1
i have this code, it's the formulae of combination without repetitions:
combinaciones :: Int ->[Int]->[[Int]]
combinaciones 0 _ = [[]]
combinaciones _ [] = []
combinaciones k (x:xs) = [x:ys | ys <- combinaciones (k - 1) xs] ++ combinaciones k xs
combinationsN :: Int ->Int->[[Int]]
combinationsN n k = combinaciones k [1..n]
My problem is that i want return a list of lists with the number of lists in the list, a couple: ([[Int]], Int). How can i do that?
Here is the simple version - it's probably possible to do it more efficiently by counting along, but this is what I can come up with at 1am.
combinationsWithCount :: Int -> [Int] -> ([[Int]], Int)
combinationsWithCount n xs = let cs = combinaciones n xs
in (cs, length cs)
Edit: OK, let me try to write the smart version too.
combinaciones :: Int -> [Int] -> ([[Int]], Int)
combinaciones 0 _ = ([[]], 1)
combinaciones _ [] = ([], 0)
combinaciones k (x:xs) =
let (first, firstN) = combinaciones (k - 1) xs
(second, secondN) = combinaciones k xs
in ([x:ys | ys <- first] ++ second, firstN + secondN)
Absolutely no guarantees that this does the right thing, I'm half-asleep. ;-)