I want to create a function that keep the first n as well as the last n elements are, all other elements are dropped.
If there are less than or equal to 2n elements, all elements are kept.
dropTake 4 [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ] => [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ]
My idea was that:
dropTake :: Int -> [a] -> [a]
dropTake n [] = []
dropTake n (x:xs)
| n > 0 = take n (x:xs) ++ drop (length xs - n) xs
| n < 0 = error "Vorraussetzung nicht erfüllt"
Now the command If there are less than or equal to 2n elements, all elements are kept is missing, but how can I wirte it down?
One way would be to simply compare 2*n with the length of the list, and return the list as-is if appropriate.
dropTake :: Int -> [a] -> [a]
dropTake n xs | length xs <= 2*n = xs
dropTake n [] = []
dropTake n (x:xs)
| n > 0 = take n (x:xs) ++ drop (length xs - n) xs
| n < 0 = error "Vorraussetzung nicht erfüllt"
Related
Write a function sumdv that holds a list of integers and adds up all numbers in the list that are divisible by 3 or 4 but not by 6. The functions sum, filter, convolutions and list generators are forbidden.
sumdv :: [Integer] -> [a] -> [Integer]
sumdv = add
sumdv [] = 0
sumdv (x:xs)
| mod 3 x == 0 || mod 4 x == 0 = x + sumdv (x:xs)
| mod 6 x == 0 = sumdv (x:xs)
Hey guys again, I´m a little bit confused about the right type, because the system shows only "Variable not in scope: sumdv :: [Integer] -> t". My thoughs are that at first I have a list with Integer, because of the fact that it must be "whole numbers" then the gave me a list of different elements that must be add together for me it is: [Integer] -> [a] -> a but it didnt work :( –
I would say that there are multiple mistakes:
type is wrong (based on the description you should accept collection of elements and return one)
seems like sumdv = add should be just removed
sumdv (x:xs) calls lead to infinite recursion (you are calling function passing the same input without modification)
mod arguments are in the wrong order
mod x 6 == 0 pattern guard should be before mod x 3 == 0 || mod x 4 == 0 cause only first matching guard is evaluated, and you will not filter out number divisible by 6 if mod x 3 == 0 is placed first
you are missing pattern guard for otherwise case (when number is not divisible by 3,4 or 6)
Taking in account all the notes above sample implementation can look like this:
sumdv [] = 0
sumdv (x:xs)
| mod x 6 == 0 = sumdv (xs)
| mod x 3 == 0 || mod x 4 == 0 = x + sumdv (xs)
| otherwise = sumdv (xs)
I'm very new to Haskell and am trying to write a simple function that will take an array of integers as input, then return either the product of all the elements or the average, depending on whether the array is of odd or even length, respectively.
I understand how to set a base case for recursion, and how to set up boolean guards for different cases, but I don't understand how to do these in concert.
arrayFunc :: [Integer] -> Integer
arrayFunc [] = 1
arrayFunc array
| (length array) % 2 == 1 = arrayFunc (x:xs) = x * arrayFunc xs
| (length array) % 2 == 0 = ((arrayFunc (x:xs) = x + arrayFunc xs) - 1) `div` length xs
Currently I'm getting an error
"parse error on input '='
Perhaps you need a 'let' in a 'do' block?"
But I don't understand how I would use a let here.
The reason you have guards is because you are trying to determine the length of the list before you actually look at the values in the list.
Rather than make multiple passes (one to compute the length, another to compute the sum or product), just compute all of the values you might need, as you walk the list, and then at the end make the decision and return the appropriate value:
arrayFunc = go (0, 1, 0, True)
where go (s, p, len, parity) [] =
if parity then (if len /= 0 then s `div` len else 0)
else p
go (s, p, len, parity) (x:xs) =
go (s + x, p * x, len + 1, not parity) xs
There are various things you can do to reduce memory usage, and the recursion is just reimplementing a fold, but this gives you an idea of how to compute the answer in one pass.
Define an auxiliary inner function like that:
arrayFunc :: [Integer] -> Integer
arrayFunc [] = 1
arrayFunc array
| (length array) % 2 == 1 = go1 array
| (length array) % 2 == 0 = go2 array
where
go1 (x:xs) = x * go1 xs
go2 (x:xs) = ((x + go2 xs) - 1) `div` length xs
This deals only with the syntactical issues in your question. In particular, [Integer] is not an array -- it is a list of integers.
But of course the name of a variable doesn't influence a code's correctness.
Without focus on recursion this should be an acceptable solution:
arrayFunc :: (Integral a) => [a] -> a
arrayFunc ls
| n == 0 = 1
| even n = (sum ls) `div` (fromIntegral n)
| otherwise = product ls
where
n = length xs
I am new to Haskell and have an assignment. I have to write a
Int->Int->[u]->[u]
Function that is given input two Ints i and j and a list and returns the elements that are in possitions greater than i and smaller than j. What I have thought so far is:
fromTo :: Int->Int->[u]->[u]
fromTo i j (h:t)
|i == 1 && j == length(h:t)
= (h:t)
|i /= 1
fromTo (i-1) j t
|j /= length(h:t)
fromTo i j init(h:t)
However I get a syntax error for the second |. Also im unsure if my train of thought is correct here.
(init returns the list without its last element)
EDIT: Corrected
|i /= 1
fromTo (i-1) j (h:t)
to
|i /= 1
fromTo (i-1) j t
Fixed indentation, parenthesization, and missing =s. This reformation compiles, and works for ordinals and finite non-empty lists:
fromTo :: Int -> Int -> [u] -> [u]
fromTo i j (h : t)
| i == 1 && j == length (h : t) = h : t
| i /= 1 = fromTo (i - 1) j t
| j /= length (h : t) = fromTo i j (init (h : t))
I think you're looking for something like this pointfree, naturally indexing span:
take :: Int -> [a] -> [a]
take _ [] = []
take 0 _ = []
take n (x : xs) = x : take (n - 1) xs
drop :: Int -> [a] -> [a]
drop _ [] = []
drop 0 xs = xs
drop n (_ : xs) = drop (n - 1) xs
span :: Int -> Int -> [a] -> [a]
span i j = drop i . take (j + 1)
which
span 0 3 [0 .. 10] == [0,1,2,3]
Or, to fit the specification:
between :: Int -> Int -> [a] -> [a]
between i j = drop (i + 1) . take j
which
between 0 3 [0 .. 10] == [1,2]
You're missing = between the | guard clause and the body. The Haskell compiler thinks the whole thing is the guard, and gets confused when it runs into the next | guard because it expects a body first. This will compile (although it is still buggy):
fromTo :: Int -> Int -> [u] -> [u]
fromTo i j (h:t)
| i == 1 && j == length (h:t) =
(h:t)
| i /= 1 =
fromTo (i-1) j t
| j /= length (h:t) =
fromTo i j (init (h:t))
but I would say there are better ways of writing this function. For example, in principle a function like this should work on infinite lists, but your use of length makes that impossible.
Here is complete solution that use recursion:
fromTo :: Int -> Int -> [u] -> [u]
fromTo i j xs = go i j xs []
where go i j (x:xs) rs
| i < 0 || j < 0 = []
| i > length (x:xs) || j > length (x:xs) = []
| i /= 0 = go (i - 1) j t
| j /= 1 = goo i (j -1) (rs ++ [x])
| otherwise = rs
Notes:
go is standard Haskell idiom for recursive function that need extra parameters compared to main level function.
First clause make sure that negative indexes result in empty list. Second does the same for any index that exceed size of a list. Lists must be finite. Third "forgets" head of the array i times. Fourth will accumulate "next" (j - 1) heads into rs. Fifth clause will be triggered when all indexes are "spent" and rs contain result.
You could make it work on infinite lists. Drop second clause. Return rs if xs is empty before "exhausting" indexes. Then function will take "up to" (j-1) elements from i.
Im looking to factorise a number based on Head or Middle recursion in Erlang. The function is called fact and takes 1 parameter, fact/1. The result will return a list of the numbers that are factors of the number.
24 returns the following: [1,2,3,4,6,8,12,24]
Does anyone have any ideas how I would go about this?
I propose you this solution. I search first the decomposition in prime factors, and then build the list of divisors. I think it should be more efficient in average.
divlist(N) -> automult([1|decomp(N)]).
decomp(N) when is_integer(N), (N > 0) ->
lists:reverse(decomp(N,[],2)).
decomp(N,R,I) when I*I > N -> [N|R];
decomp(N,R,I) when (N rem I) =:= 0 -> decomp(N div I,[I|R],I);
decomp(N,R,2) -> decomp(N,R,3);
decomp(N,R,I) -> decomp(N,R,I+2).
automult(L=[H]) when is_number(H)-> L;
automult([H|Q]) when is_number(H)->
L1 = automult(Q),
L2 = [H*X || X <- L1],
lists:usort([H|L1]++L2).
The solutions proposed by #Zoukaye and #P_A and mine give the same result, but both of their solutions have a complexity of O(n). My proposal is more complex to evaluate since it is divided in 2 parts. The search or prime decomposition is majored by 0(log(n)), and the second part depend of the result of the first one, the interesting point is that it cannot be the worse case for both part:
if a number has many prime factor, the search of them is fast, and the composition of all divider takes longer.
if a number has few (1) prime factor, the search take longer, but the composition is short.
Last remark, #Zoukaye uses an intermediate list of integer. if you intend to use this for looooong integer, it is a bad idea since you will crash for lack of memory just building this list.
I made a performance test comparing the solutions where I create a list of N random numbers less than Max, evaluate the whole execution time for each solution, verify that they are equivalent and return times. The result is
10 000 tests for number less than 10 000:
mine: 63ms, P_A: 788ms, Zoukaye: 1383ms
10 000 tests for number less than 100 000:
mine: 80ms, P_A: 9240ms, Zoukaye: 13594ms
10 000 tests for number less than 1000 000:
mine: 105ms, P_A: 101001ms, Zoukaye: 137145ms
Here is the code I used:
-module (test).
-compile((export_all)).
test(Nbtest,Max) ->
random:seed(erlang:now()),
L = [random:uniform(Max) || _ <- lists:seq(1,Nbtest)],
F1 = fun() -> [{X,divlist(X)} || X <- L] end,
F2 = fun() -> [{X,fact_comp(X)} || X <- L] end,
F3 = fun() -> [{X,fact_rec(X)} || X <- L] end,
{T1,R} = timer:tc(F1),
{T2,R} = timer:tc(F2),
{T3,R} = timer:tc(F3),
{T1,T2,T3}.
% Method1
divlist(N) -> automult([1|decomp(N)]).
decomp(N) when is_integer(N), (N > 0) ->
lists:reverse(decomp(N,[],2)).
decomp(N,R,I) when I*I > N -> [N|R];
decomp(N,R,I) when (N rem I) =:= 0 -> decomp(N div I,[I|R],I);
decomp(N,R,2) -> decomp(N,R,3);
decomp(N,R,I) -> decomp(N,R,I+2).
automult(L=[H]) when is_number(H)-> L;
automult([H|Q]) when is_number(H)->
L1 = automult(Q),
L2 = [H*X || X <- L1],
lists:usort([H|L1]++L2).
% Method 2
fact_comp(N) ->
if N > 0 ->
[ V || V <- lists:seq(1, N div 2), N rem V =:= 0 ] ++ [ N ];
N < 0 ->
Na = 0 - N,
[ V || V <- lists:seq(1, Na div 2), Na rem V =:= 0 ] ++ [ Na ];
N =:= 0 -> []
end.
% Method 3
fact_rec(N) ->
fact_rec(N, 1, []).
fact_rec(N, I, Acc) when I =< trunc(N/2) ->
case N rem I of
0 -> fact_rec(N, I+1, [I | Acc]);
_ -> fact_rec(N, I+1, Acc)
end;
fact_rec(N, _I, Acc) -> lists:reverse(Acc) ++ [N].
Something like this?
-module(fact).
-export([fact_rec/1]).
fact_rec(N) ->
fact_rec(N, 1, []).
fact_rec(N, I, Acc) when I =< trunc(N/2) ->
case N rem I of
0 -> fact_rec(N, I+1, [I | Acc]);
_ -> fact_rec(N, I+1, Acc)
end;
fact_rec(N, _I, Acc) -> lists:reverse(Acc) ++ [N].
Using list comprehension
fact_comp(N) ->
if N > 0 ->
[ V || V <- lists:seq(1, N div 2), N rem V =:= 0 ] ++ [ N ];
N < 0 ->
Na = 0 - N,
[ V || V <- lists:seq(1, Na div 2), Na rem V =:= 0 ] ++ [ Na ];
N =:= 0 -> []
end.
I'm a noob in Haskell, but some experience with ActionScript 3.0 Object Orientated. Thus working on a major programming transition. I've read the basic knowledge about Haskel, like arithmetics. And I can write simple functions.
As a practical assignment I have to generate the Thue-Morse sequence called tms1 by computer in Haskell. So it should be like this:
>tms1 0
0
>tms1 1
1
>tms1 2
10
>tms1 3
1001
>tms1 4
10010110
and so on... According to wikipedia I should use the formula.
t0 = 0
t2n = tn
t2n + 1 = 1 − tn
I have no idea how I can implement this formula in Haskell. Can you guide me to create one?
This is what I got so far:
module ThueMorse where
tms1 :: Int -> Int
tms1 0 = 0
tms1 1 = 1
tms1 2 = 10
tms1 3 = 1001
tms1 x = tms1 ((x-1)) --if x = 4 the output will be 1001, i don't know how to make this in a recursion function
I did some research on the internet and found this code.
Source:
http://pastebin.com/Humyf6Kp
Code:
module ThueMorse where
tms1 :: [Int]
tms1 = buildtms1 [0] 1
where buildtms1 x n
|(n `rem` 2 == 0) = buildtms1 (x++[(x !! (n `div` 2))]) (n+1)
|(n `rem` 2 == 1) = buildtms1 (x++[1- (x !! ((n-1) `div` 2))]) (n+1)
custinv [] = []
custinv x = (1-head x):(custinv (tail x))
tms3 :: [Int]
tms3 = buildtms3 [0] 1
where buildtms3 x n = buildtms3 (x++(custinv x)) (n*2)
intToBinary :: Int -> [Bool]
intToBinary n | (n==0) = []
| (n `rem` 2 ==0) = intToBinary (n `div` 2) ++ [False]
| (n `rem` 2 ==1) = intToBinary (n `div` 2) ++ [True]
amountTrue :: [Bool] -> Int
amountTrue [] = 0
amountTrue (x:xs) | (x==True) = 1+amountTrue(xs)
| (x==False) = amountTrue(xs)
tms4 :: [Int]
tms4= buildtms4 0
where buildtms4 n
|(amountTrue (intToBinary n) `rem` 2 ==0) = 0:(buildtms4 (n+1))
|(amountTrue (intToBinary n) `rem` 2 ==1) = 1:(buildtms4 (n+1))
But this code doesn't give the desired result. Any help is well appreciated.
I would suggest using a list of booleans for your code; then you don't need to explicitly convert the numbers. I use the sequence defined like this:
0
01
0110
01101001
0110100110010110
01101001100101101001011001101001
...
Notice that the leading zeros are quite important!
A recursive definition is now easy:
morse = [False] : map step morse where step a = a ++ map not a
This works because we never access an element that is not yet defined. Printing the list is left as an excercise to the reader.
Here is another definition, using the fact that one can get the next step by replacing 1 with 10 and 0 with 01:
morse = [False] : map (concatMap step) morse where step x = [x,not x]
Edit
Here are easier definitions by sdcvvc using the function iterate. iterate f x returns a list of repeated applications of f to x, starting with no application:
iterate f x = [x,f x,f (f x),f (f (f x)),...]
And here are the definitions:
morse = iterate (\a -> a ++ map not a) [False]
morse = iterate (>>= \x -> [x,not x]) [False]
Your definition of the sequence seems to be as a sequence of bit sequences:
0 1 10 1001 10010110 ... etc.
t0 t1 t2 t3 t4
but the wikipedia page defines it as a single bit sequence:
0 1 1 0 1 ... etc
t0 t1 t2 t3 t4
This is the formulation that the definitions in Wikipedia refer to. With this knowledge, the definition of the recurrence relation that you mentioned is easier to understand:
t0 = 0
t2n = tn
t2n + 1 = 1 − tn
In English, this can be stated as:
The zeroth bit is zero.
For an even, non-zero index, the bit is the same as the bit at half the index.
For an odd index, the bit is 1 minus the bit at half the (index minus one).
The tricky part is going from subscripts 2n and 2n+1 to odd and even, and understanding what n means in each case. Once that is done, it is straightforward to write a function that computes the *n*th bit of the sequence:
lookupMorse :: Int -> Int
lookupMorse 0 = 0;
lookupMorse n | even n = lookupMorse (div n 2)
| otherwise = 1 - lookupMorse (div (n-1) 2)
If you want the whole sequence, map lookupMorse over the non-negative integers:
morse :: [Int]
morse = map lookupMorse [0..]
This is the infinite Thue-Morse sequence. To show it, take a few of them, turn them into strings, and concatenate the resulting sequence:
>concatMap show $ take 10 morse
"0110100110"
Finally, if you want to use the "sequence of bit sequences" definition, you need to first drop some bits from the sequence, and then take some. The number to drop is the same as the number to take, except for the zero-index case:
lookupMorseAlternate :: Int -> [Int]
lookupMorseAlternate 0 = take 1 morse
lookupMorseAlternate n = take len $ drop len morse
where
len = 2 ^ (n-1)
This gives rise to the alternative sequence definition:
morseAlternate :: [[Int]]
morseAlternate = map lookupMorseAlternate [0..]
which you can use like this:
>concatMap show $ lookupMorseAlternate 4
"10010110"
>map (concatMap show) $ take 5 morseAlternate
["0", "1", "10", "1001", "10010110"]
Easy like this:
invertList :: [Integer] -> [Integer]
invertList [] = []
invertList (h:t)
|h == 1 = 0:invertList t
|h == 0 = 1:invertList t
|otherwise = error "Wrong Parameters: Should be 0 or 1"
thueMorse :: Integer -> [Integer]
thueMorse 1 = [0]
thueMorse n = thueMorse (n - 1) ++ invertList (thueMorse (n - 1))