Clip up numbers bigger than maximum - list

I have this function:
fun min x y = if x >= y then y else x
and I need to use this function (as a partial application) and make function clipupdown with arguments number and list, where number represents the minimal number that should exist in that list and all numbers lower than min should be set to that minimal number. For example when I call:
clipdown 10 [1,11,21,4,6,7,12]
I should get
[10,11,21,10,10,10,12]
Any hints?

Any hints?
What do you get when you call min (edit: or, actually max) with only one element?
min 10
how do you map a function over a list?

fun clipdown lowest numbers = map (max lowest) numbers
You have to use max, instead of min. Whenever the program finds a number below the minimum, it should choose the minimum (which is greater than the encountered number). So you need to choose the max value.

Since Int.min and Int.max already exist, but take tuples, you could write a function
fun curry f x y = f (x, y)
and use this like map o curry Int.max to get clipdown.
Similarly you could get clipup with map o curry Int.min.
You might also get clipupdown by composing both like
fun clipupdown lower higher = clipdown lower o clipup higher
But you could also use that (map f) ∘ (map g) = map (f ∘ g):
fun clipupdown lower higher = map (curry Int.max lower o curry Int.min higher)
This is called map fusion.

Related

Power function using multiplication and iteration in Standard ML

I am having trouble understanding a method to implement a power function in SML using only iteration and multiplication.
my iteration is the following:
fun iterate 0 f x = x
| iterate n f x = iterate (n-1) f (f x);
while my multiplication is basically iterating recursively
fun multiply 0 f = 0
| multiply f x = iterate x (fn x => x + 1) (multiply x (f-1));
Power function would basically be an iteration of the multiplication of the same base but I don't know which value to decrement
power n f = iterate (mult n n) (fn x => x + 1) (power (n) (f-1))
which is definately wrong
power n f = iterate (mult n n) (fn x => x + 1) (power (n) (f-1))
So, when it comes to naming, I might definitely write power x y or power i j or power x n or some such, since x, y, i, j or n look like they're numbers or integers, whereas f looks like it's a function. So right off the bat you have:
fun power x y = iterate (...a...) (...b...) (...c...)
As for what goes into each of these three parts, ...a..., ...b... and ...c...:
a. The thing iterate calls n, which is the number of times to iterate.
b. The thing iterate calls f, which is the function to apply each time.
c. The thing iterate calls x, which is what is applied each time.
As elaborated on in How to make a multiplication function using just addition function and iterate function in SML, there is no point in making power call itself; the point of using iterate is to hand over recursion to this list-combinator rather than use explicit recursion (where power has a reference to itself somewhere in its definition).

Standard ML: How to compute x to the power of i?

I am new to Standard ML. I am trying to compute x squared i, where x is a real and i is an non-negative integer. The function should take two parameters, x and i
Here is what I have so far:
fun square x i = if (i<0) then 1 else x*i;
The error that I am getting is that the case object and rules do not agree
The unary negation operator in SML is not - as it is in most languages, but instead ~. That is likely what is causing the specific error you cite.
That said, there are some other issues with this code. L is not bound in the example you post for instance.
I think you may want your function to look more like
fun square (x : real) 0 = 1
| square x i = x * (square x (i - 1))
You'll want to recurse in order to compute the square.

Ocaml Product of two polynomials

How to compute the product of two polynomials ?
For example: x^3 + 3x^2 +0.2x and 2x^4 + 3
First I made a type
Type term = {coefficient:int; name:string; exponent:int};;
Type polynomials = term list;;
then I made a function calculate coefficient
let product l l' =
List.concat (List.map (fun e -> List.map (fun e' -> (e*e')) l'.coefficient)
l.coefficient);;
This is where I get stuck. I guess I can use the same function for exponent as well,but the question is asking writing a polynomials function with one param, which means two polynomials will be in the same variable
Can someone help me out here
You seem to be saying that you're asked to write a function to multiply two polynomials, but the function is supposed to have just one parameter. This, indeed, doesn't make a lot of sense.
You can always use a tuple to bundle any number of values into a single value, but there's no reason to do this (that I can see), and it's not idiomatic for OCaml.
Here's a function with one parameter (a pair) that multiplies two ints:
# let multiply (a, b) = a * b;;
val multiply : int * int -> int = <fun>
# multiply (8, 7);;
- : int = 56
(As a separate comment, the code you give doesn't compile.)

How to get integers from list where sum of them is less than X?

Sorry for the mess that was here.
I wanted a classic greedy algorithm for knapsack problem in haskell for integers.
But there was other question - how to refer to list in list comprehension?
There are several approaches to this:
Generate all lists which are smaller. Take the longest
For every n <= X, generate [1..n] and check whether its sum is lesser x. Take the longest of those sets:
allLists x = takeWhile ( (<=x) . sum) $ inits [1..]
theList = last . allLists
where inits is from Data.List
Alternatively, we remember mathematics
We know that the sum of [1..n] is n*(n+1)/2. We want x >= n * (n+1)/2. We solve for n and get that n should be 0.5 * (sqrt (8 * x + 1) - 1). Since that's not a natural number, we floor it:
theList x = [1..n]
where n = floor $ 0.5 * (sqrt (8 * (fromIntegral x) + 1) - 1)
This will give all the lists that its sum is not greater than 100:
takeWhile (\l -> sum l <= 100) $ inits [1..]

elem function of no limit list

list comprehension haskell
paar = [(a,b) | a<-[a | a<-[1..], mod a 3 == 0], b<-[b*b | b<-[1..]]]
a = divisor 3
b = square
The Elements must be constructed by equitable order.
the test >elem (9, 9801) must be True
my Error
Main> elem (9, 9801) test
ERROR - Garbage collection fails to reclaim sufficient space
How can I implement this with Cantor's diagonal argument?
thx
Not quite sure what your goal is here, but here's the reason why your code blows up.
Prelude> let paar = [(a,b) | a<-[a | a<-[1..], mod a 3 == 0], b<-[b*b | b<-[1..]]]
Prelude> take 10 paar
[(3,1),(3,4),(3,9),(3,16),(3,25),(3,36),(3,49),(3,64),(3,81),(3,100)]
Notice you're generating all the (3, ?) pairs before any other. The elem function works by searching this list linearly from the beginning. As there are an infinite number of (3, ?) pairs, you will never reach the (9, ?) ones.
In addition, your code is probably holding on to paar somewhere, preventing it from being garbage collected. This results in elem (9, 9801) paar taking not only infinite time but also infinite space, leading to the crash you described.
Ultimately, you probably need to take another approach to solving your problem. For example, something like this:
elemPaar :: (Integer, Integer) -> Bool
elemPaar (a, b) = mod a 3 == 0 && isSquare b
where isSquare = ...
Or alternatively figure out some other search strategy than straight up linear search through an infinite list.
Here's an alternate ordering of the same list (by hammar's suggestion):
-- the integer points along the diagonals of slope -1 on the cartesian plane,
-- organized by x-intercept
-- diagonals = [ (0,0), (1,0), (0,1), (2,0), (1,1), (0,2), ...
diagonals = [ (n-i, i) | n <- [0..], i <- [0..n] ]
-- the multiples of three paired with the squares
paar = [ (3*x, y^2) | (x,y) <- diagonals ]
and in action:
ghci> take 10 diagonals
[(0,0),(1,0),(0,1),(2,0),(1,1),(0,2),(3,0),(2,1),(1,2),(0,3)]
ghci> take 10 paar
[(0,0),(3,0),(0,1),(6,0),(3,1),(0,4),(9,0),(6,1),(3,4),(0,9)]
ghci> elem (9, 9801) paar
True
By using a diagonal path to iterate through all the possible values, we guarantee that we reach each finite point in finite time (though some points are still outside the bounds of memory).
As hammar points out in his comment, though, this isn't sufficient, as it will still take
an infinite amount of time to get a False answer.
However, we have an order on the elements of paar, namely (3*a,b^2) comes before (3*c,d^2) when
a + b < c + d. So to determine whether a given pair (x,y) is in paar, we only have to check
pairs (p,q) while p/3 + sqrt q <= x/3 + sqrt y.
To avoid using Floating numbers, we can use a slightly looser condition, that p <= x || q <= y.
Certainly p > x && q > y implies p/3 + sqrt q > x/3 + sqrt y, so this will still include any possible solutions, and it's guaranteed to terminate.
So we can build this check in
-- check only a finite number of elements so we can get a False result as well
isElem (p, q) = elem (p,q) $ takeWhile (\(a,b) -> a <= p || b <= q) paar
And use it:
ghci> isElem (9,9801)
True
ghci> isElem (9,9802)
False
ghci> isElem (10,9801)
False