I have the following problem: given a max(max) apacity, and given a list of values(listOfValues) i need to return a list with values from the listOfValues. The sum of the elements must be <= max and i need to prioritize the higher values.
Example: typing solvingProblem 103 [15, 20, 5, 45, 34] i must get: [45, 45, 5, 5]
To solve the problem i create the following code:
solvingProblem max [] = 0
solvingProblem max listOfValues | max == 0 = 0
| otherwise = createList max listOfValues []
createList max [] result = -1
createList max listOfValues result | smaller listOfValues > max = -1
| higher listOfValues > max = createList max (remove (higher listOfValues) listOfValues) result
| otherwise = createList (max - higher listOfValues) listOfValues (insert (higher listOfValues) result)
higher [a] = a
higher (a:b:x) | a > b = higher (a:x)
| otherwise = higher (b:x)
smaller [a] = a
smaller (a:b:x) | a < b = smaller (a:x)
| otherwise = smaller (b:x)
remove x [] = []
remove x (h:t) | x == h = remove x t
| otherwise = h : remove x t
insert x (h:t) = x : h : t
In the two lines where i'll returning "-1" should be the parameter "result", but if i change "-1" to "result" the code don't load on ghci.
Can someone help me?
Thank you and sorry for my bad english.
If I may begin with a bit of a side note, some of your functions already exist in Haskell (now that I come to think of it you might have written them for an exercise, but just in case it wouldn't be the case, let's discuss that): your higher is maximum, your smaller is minimum and your insert is just (:), beacause like you write it yourself insert x list = x:list. Note that your version will fail if you give it the empty list because the pattern matching is non-exhaustive. Also you could write remove in terms of filter: remove x list = filter (== x) list.
Now why doesn't your code load properly? ghci tells you:
• Non type-variable argument in the constraint: Num [a]
(Use FlexibleContexts to permit this)
• When checking the inferred type
solvingProblem :: forall a.
(Ord a, Num [a], Num a) =>
a -> [a] -> [a]
Which I agree is pretty cryptic, but what it's saying is that the return type of solvingProblem is a list of a and for some reason it is also an instance of the Num type class. The reason why it says it's an instance of Num is because one of the return value of solvingProblem is 0 which is a number, which is a bit odd because it is also a list. Changing the 0 with [] makes the code compile and work (if you change insert with (:) otherwise you get the non-exhaustive pattern matching I was talking about earlier).
λ> solvingProblem 103 [15,20, 5, 45, 34]
[5,5,45,45]
it :: (Ord t, Num t) => [t]
The problem is with the last guard clause in createList.
The type you intended for createList seems to be:
createList :: Int -> [Int] -> Int -> Int
but if you look at the last guard clause you have:
| otherwise = createList (max - ...) listOfValues (insert ...)
^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^
Int [Int] [Int]
Even though GHC is very good at inferring types, always adding
type signatures to your code is a good way of catching these kinds
of errors early.
Related
I am trying to implement the following specification:
busca.v.xs = <Min i : 0 ≤ i < #xs ∧ xs.i = v : i>
I wrote something like the following.
busca :: Int -> [Int] -> Int
busca v [] = 1000000
busca v (x:xs) | x==v = min x (busca v xs)
| otherwise = busca v xs
When I was deriving, the case [] is infinity, so I tried making something that is somewhat similar. The expected result should be the minimun number in a list. For example, busca 2 [4,3,2,2,7] should return 2. Can i use Maybe and simulate that infinity in a way?
You could make a fresh type for which min did what you ask like this:
data PosInfty a = Finite a | Infinite deriving (Eq, Ord, Read, Show)
Derived Ord instances treat values made with earlier constructors as unconditionally smaller than values made with later constructors, so all Finite values will be less than Infinite.
This type is also available (with significantly more instances) from monoid-extras.
In SML is it possible to find the number of occurrences of the min number in a list?
I have code to find the number of occurrences of a number but i am stumped on how to find the min and use it to find how many of the minimum num there is.
fun occurrences(nil, n)=0
| occurrences(ls, n) =
if hd(ls)=n then occurrences(tl(ls),n) + 1
else occurrences(tl(ls),n) + 0;
Thank you!
You can write a function that keeps track of the min value and its count as you iterate through the list.
We can do this by implementing a tail-recursive function which helper, which maintains the value of the current minimum and a count of the number of times that item has appeared.
We can then wrap this in another function min_count via a let-in-end block.
For example:
fun min_count [] = 0 (* the empty list has zero items in it *)
| min_count (x :: xs) =
let
(* when we reach the end of the list, return the accumulated count *)
fun helper (_, n) [] = n
| helper (m, n) (y :: ys) =
(* if we find a new minimum, reset the count *)
if y < m then helper (y, 1) ys
(* if the current list item is larger than the min, ignore it *)
else if y > m then helper (m, n) ys
(* if we've found another instance of the min, add one to the count *)
else helper (m, n + 1) ys
in
(* first item appears once *)
helper (x, 1) xs (* first item appears once *)
end;
This problem is a good test for using folds on a list.
Finding the mininum
If we want to find the minimum in a list we need to iterate over the list checking each element against a predetermined starting minimum value. If that element is less than that known minimum, we continue to iterate using that value instead. When we're done, we have the minimum value.
If the list is empty, there is no minimum value. If only one value is in the list, the minimum is obviously that. If there are more values, the starting minimum value is the first element.
We can use foldl to handle the iteration in this last case.
fun min([]) = NONE
| min([x]) = SOME x
| min(first::rest) =
SOME (foldl (fn (x, min) => if x < min then x else min)
first rest)
Finding occurrences
You've already done this, but this can be done in terms of a fold as well.
fun occurrences(lst, v) =
foldl (fn (x, count) => if x = v then count + 1 else count)
0 lst
Putting this together
We could use these two functions to find the number of times the minimum occurs in a list.
let
val numbers = [1, 4, 7, 2, 9, 0, 1, 6, 0]
val min = min(numbers)
val occ = case min of
NONE => NONE
| SOME x => SOME (occurrences(numbers, x))
in
case (min, occ) of
(NONE, NONE) => print("No minimum found.")
| (SOME m, SOME t) => print("Min: " ^ Int.toString(m) ^ "; times: " ^ Int.toString(t))
end
Can we do it in a single pass?
Using the above approach, we have to iterate over the list twice. This is a more general, but less efficient way of getting both pieces of information the minimum and the number of occurrences of it. We can use foldl to get both pieces of information, and it's going to look at lot like the definition of min.
We just need to pass a function to foldl that keeps a running tally of the number of times it has found the minimum value, and we need to pass it a tuple with both an initial minimum value and an initial count of 1.
fun minCount([]) = NONE
| minCount([x]) = SOME (x, 1)
| minCount(first::rest) =
SOME (foldl (fn (x, init as (min, count)) =>
case Int.compare(x, min) of
EQUAL => (min, count + 1)
| LESS => (x, 1)
| _ => init)
(first, 1)
rest)
With this function defined, our previous code can be rewritten as:
let
val numbers = [1, 4, 7, 2, 9, 0, 1, 6, 0]
val mc = minCount(numbers)
in
case mc of
NONE => print("No minimum found.")
| SOME (m, t) => print("Min: " ^ Int.toString(m) ^ "; times: " ^ Int.toString(t))
end
Assuming that you are supposed to use your occurrences function in the solution, write a function that finds the minimum,
fun minimum [x] = x
| minimum (x::xs) = let
val min = minimum xs
in
if x < min then x else min
end
Note that this does not handle the empty list.
You need to decide whether to leave the missing pattern as a runtime error, or add it and handle the error, for instance by raising an exception or by changing the return type to int option.
If you're taking a course, use one of the methods you've learned so far.
Then you can use that function,
occurrences(the_list, minimum the_list)
type Googol = {
number : float
power : float
result : float
}
let generatePowers (n:float) : list<Googol> =
let rec powerInner (n:float) (p:float) (acc : list<Googol>) =
match n with
| p when p <= 1.0 -> acc
| p when p > 1.0 -> powerInner n (p-1.0) ([{ number=n; power=p; result=n**p}]#acc)
let rec numberInner (n:float) (acc : list<Googol>) =
match n with
| n when n <=1.0 -> acc
| n when n >1.0 -> numberInner (n-1.0) ((powerInner n [])#acc)
numberInner n []
ProjectEuler.fsx(311,50): error FS0001: This expression was expected to have type
'Googol list'
but here has type
'Googol list -> Googol list'
I am trying to solve this problem -> https://projecteuler.net/problem=56 | but for this I need to generate powers below n < 100. When I try to concatenate [{ number=n; power=p; result=n**p}]#acc
these lists I get the error above. Explain please why error says 'Googol list -> Googol list' is in the function, does I plug a function as a parameter to the function or I plug the actual list when just after concatenation. Is # a function?
This looks like homework or practice, so first I'll give some hints to move on. Finally I'll show a version that seems to work, and then tell how I would approach the problem.
The task is to find the number a ** b, for a and b less than 100, that has the highest sum of its own digits.
The first problem is that float won't give us all the digits of a ** b, so that type is useless to solve the problem. To fix that, we turn to the BigInteger type, and the BigInteger.Pow function. Then we get a 1 followed by 200 zeroes if we run the following snippet, just like it says in the problem description.
let x: bigint = BigInteger.Pow (100I, 100)
let x: string = string x
printfn "s=%s" x
To get useful results, change the Googol type so that it uses bigint, except for power that should be an int.
Why are the functions powerInner and numberInner inside the function generatePowers? This doesn't seem to have a specific purpose, so I suggest moving them out to make this clearer.
The function powerInner do a match on n, but then goes on to name the results p, which shadows the p parameter so that it is unused. Ok, the intention here is probably to match on p rather than n, so just fix that, and then the shadowing of the p parameter is perfectly fine.
The tests first on <= 1 and then on > 1 causes incomplete matches. If the first line checks that the number is less or equal to one, then it must the greater than one in the next line. So just use n -> without the when to fix that. I also suspect you want to test <= 0 instead of 1.
This
[{ number=n; power=p; result=n**p}]#acc
can be just
{ number=n; power=p; result=n**p } :: acc
and here
(powerInner n [])
I suspect you just need a starting value for the power, which would be 99
(powerInner n 99 [])
SPOILER WARNING
After a bit of tinkering, this is what I ended up with, and it seems to print out a useful list of numbers. Note that in order to not run through all 99 by 99 results with printouts, I've used low starting numbers 3 and 5 for the countdowns here, so we get some simple printout we can study for analysis.
type Googol = { number: bigint; power: int; result: bigint }
let rec powerInner (n: bigint) (p: int) (acc: Googol list) =
match p with
| p when p <= 0 -> acc
| p ->
let newNumber = { number = n; power = p; result = n ** p }
printfn "newNumber=%0A" newNumber
powerInner n (p - 1) (newNumber :: acc)
let rec numberInner (n: bigint) (acc: Googol list) =
match n with
| n when n <= 0I -> acc
| n -> numberInner (n - 1I) ((powerInner n 5 []) # acc)
let generatePowers (n: bigint) : Googol list =
numberInner n []
let powers = generatePowers 3I
I'm not sure if this solution is correct. I'd do it differently anyway.
I would simply loop through a and b in two loops, one inside the other. For each a ** b I would convert the result to a string, and then sum the digits of the string. Then I'd simply use a mutable to hold on to whichever result is the highest. The same could be achieved in a more functional way with one of those fancy List functions.
You're missing a parameter here:
| n when n >1.0 -> numberInner (n-1.0) ((powerInner n [])#acc)
^^^^^^^^^^^^^^^
here
powerInner is defined with three parameters, but you're only passing two.
In F# it is not technically illegal to pass fewer parameters than defined. If you do that, the result will be a function that "expects" the remaining parameters. For example:
let f : int -> int -> string
let x = f 42
// Here, x : int -> string
let y = x 5
// Here, y : string
So in your case omitting the last parameter makes the resulting type Googol list -> Googol list, which then turns out to be incompatible with the type Googol list expected by operator #. Which is what the compiler is telling you in the error message.
Not easy way to explain this, but I will try. I think i'm confusing my method with some C, but here it goes:
I want to check if a list is complete, like this:
main> check 1 [1,3,4,5]
False
main> check 1 [1,2,3,4]
True
It's a finite list, and the list doesn't have to be ordered. But inside the list there most be the number that misses to be True. In the first case it's the number 2.
This is my version, but it doesn't even compile.
check :: Eq a => a -> [a] -> Bool
check n [] = False
check n x | n/=(maximum x) = elem n x && check (n+1) x
| otherwise = False
So if I understand this correctly, you want to check to see that all the elements in a list form a sequence without gaps when sorted. Here's one way:
noGaps :: (Enum a, Ord a) => [a] -> Bool
noGaps xs = all (`elem` xs) [minimum xs .. maximum xs]
[minimum xs .. maximum xs] creates a sequential list of all values from the lowest to the highest value. Then you just check that they are all elements of the original list.
Your function doesn't compile because your type constraints are greater than what you declare them as. You say that a only needs to be an instance of Eq - but then you add something to it, which requires it to be an instance of Num. The way you use the function also doesn't make sense with the signature you declared - check [1,2,3,4] is a Bool in your example, but in the code you gave it would be Eq a => [[a]] -> Bool (if it compiled in the first place).
Do you only need this to work with integers? If not, give some example as to what "complete" means in that case. If yes, then do they always start with 1?
Here's another take on the problem, which uses a function that works on sorted lists, and use it with a sorted input.
The following will check that the provided list of n Int contains all values from 1 to n:
check :: (Num a, Ord a) => [a] -> Bool
import List
check l = check_ 1 (sort l)
where check_ n [] = True
check_ n [x] = n == x
check_ n (x:y:xs) = (x+1)==y && check_ (n+1) (y:xs)
Note the use of List.sort to prepare the list for the real check implemented in check_.
Scenario:
If there is an array of integers and I want to get array of integers in return that their total should not exceed 10.
I am a beginner in Haskell and tried below. If any one could correct me, would be greatly appreciated.
numbers :: [Int]
numbers = [1,2,3,4,5,6,7,8,9,10, 11, 12]
getUpTo :: [Int] -> Int -> [Int]
getUpTo (x:xs) max =
if max <= 10
then
max = max + x
getUpTo xs max
else
x
Input
getUpTo numbers 0
Output Expected
[1,2,3,4]
BEWARE: This is not a solution to the knapsack problem :)
A very fast solution I came up with is the following one. Of course solving the full knapsack problem would be harder, but if you only need a quick solution this should work:
import Data.List (sort)
getUpTo :: Int -> [Int] -> [Int]
getUpTo max xs = go (sort xs) 0 []
where
go [] sum acc = acc
go (x:xs) sum acc
| x + sum <= max = go xs (x + sum) (x:acc)
| otherwise = acc
By sorting out the array before everything else, I can take items from the top one after another, until the maximum is exceeded; the list built up to that point is then returned.
edit: as a side note, I swapped the order of the first two arguments because this way should be more useful for partial applications.
For educational purposes (and since I felt like explaining something :-), here's a different version, which uses more standard functions. As written it is slower, because it computes a number of sums, and doesn't keep a running total. On the other hand, I think it expresses quite well how to break the problem down.
getUpTo :: [Int] -> [Int]
getUpTo = last . filter (\xs -> sum xs <= 10) . Data.List.inits
I've written the solution as a 'pipeline' of functions; if you apply getUpTo to a list of numbers, Data.List.inits gets applied to the list first, then filter (\xs -> sum xs <= 10) gets applied to the result, and finally last gets applied to the result of that.
So, let's see what each of those three functions do. First off, Data.List.inits returns the initial segments of a list, in increasing order of length. For example, Data.List.inits [2,3,4,5,6] returns [[],[2],[2,3],[2,3,4],[2,3,4,5],[2,3,4,5,6]]. As you can see, this is a list of lists of integers.
Next up, filter (\xs -> sum xs <= 10) goes through these lists of integer in order, keeping them if their sum is less than 10, and discarding them otherwise. The first argument of filter is a predicate which given a list xs returns True if the sum of xs is less than 10. This may be a bit confusing at first, so an example with a simpler predicate is in order, I think. filter even [1,2,3,4,5,6,7] returns [2,4,6] because that are the even values in the original list. In the earlier example, the lists [], [2], [2,3], and [2,3,4] all have a sum less than 10, but [2,3,4,5] and [2,3,4,5,6] don't, so the result of filter (\xs -> sum xs <= 10) . Data.List.inits applied to [2,3,4,5,6] is [[],[2],[2,3],[2,3,4]], again a list of lists of integers.
The last step is the easiest: we just return the last element of the list of lists of integers. This is in principle unsafe, because what should the last element of an empty list be? In our case, we are good to go, since inits always returns the empty list [] first, which has sum 0, which is less than ten - so there's always at least one element in the list of lists we're taking the last element of. We apply last to a list which contains the initial segments of the original list which sum to less than 10, ordered by length. In other words: we return the longest initial segment which sums to less than 10 - which is what you wanted!
If there are negative numbers in your numbers list, this way of doing things can return something you don't expect: getUpTo [10,4,-5,20] returns [10,4,-5] because that is the longest initial segment of [10,4,-5,20] which sums to under 10; even though [10,4] is above 10. If this is not the behaviour you want, and expect [10], then you must replace filter by takeWhile - that essentially stops the filtering as soon as the first element for which the predicate returns False is encountered. E.g. takeWhile [2,4,1,3,6,8,5,7] evaluates to [2,4]. So in our case, using takeWhile stops the moment the sum goes over 10, not trying longer segments.
By writing getUpTo as a composition of functions, it becomes easy to change parts of your algorithm: if you want the longest initial segment that sums exactly to 10, you can use last . filter (\xs -> sum xs == 10) . Data.List.inits. Or if you want to look at the tail segments instead, use head . filter (\xs -> sum xs <= 10) . Data.List.tails; or to take all the possible sublists into account (i.e. an inefficient knapsack solution!): last . filter (\xs -> sum xs <= 10) . Data.List.sortBy (\xs ys -> length xscomparelength ys) . Control.Monad.filterM (const [False,True]) - but I'm not going to explain that here, I've been rambling long enough!
There is an answer with a fast version; however, I thought it might also be instructive to see the minimal change necessary to your code to make it work the way you expect.
numbers :: [Int]
numbers = [1,2,3,4,5,6,7,8,9,10, 11, 12]
getUpTo :: [Int] -> Int -> [Int]
getUpTo (x:xs) max =
if max < 10 -- (<), not (<=)
then
-- return a list that still contains x;
-- can't reassign to max, but can send a
-- different value on to the next
-- iteration of getUpTo
x : getUpTo xs (max + x)
else
[] -- don't want to return any more values here
I am fairly new to Haskell. I just started with it a few hours ago and as such I see in every question a challenge that helps me get out of the imperative way of thinking and a opportunity to practice my recursion thinking :)
I gave some thought to the question and I came up with this, perhaps, naive solution:
upToBound :: (Integral a) => [a] -> a -> [a]
upToBound (x:xs) bound =
let
summation _ [] = []
summation n (m:ms)
| n + m <= bound = m:summation (n + m) ms
| otherwise = []
in
summation 0 (x:xs)
I know there is already a better answer, I just did it for the fun of it.
I have the impression that I changed the signature of the original invocation, because I thought it was pointless to provide an initial zero to the outer function invocation, since I can only assume it can only be zero at first. As such, in my implementation I hid the seed from the caller and provided, instead, the maximum bound, which is more likely to change.
upToBound [1,2,3,4,5,6,7,8,9,0] 10
Which outputs: [1,2,3,4]