Write a function allLessThan. It takes two list of integers and test if all integers in the first list are less than all integers in the second list.
For example allLessThan([2,4], [6,7,8]) would return true
I've tried to set up the function in terms of letting the sets equal xx and yy so that if every element in xx is less than every element in yy then the function would return true, but if not would return false.
- fun allLessThan([], yy) = true
= | allLessThan(xx, []) = false
= | allLessThan(x::xRest, y::yRest)
Related
SML is a challenging language for me to learn. I'm trying to find a way to screen an undetermined list and return a boolean based on whether two elements adjacent on a list are the same value or not. What I've tried and think is close to correct is below.
fun repeatE nil = false
| repeatE (first::last) = first = last orelse repeatsE(last);
Obviously, this results in an error. I based my answer on this code, which tells me if a value is an element in the list.
fun member (e, nil) = false
| member (e, first::last) = e = first orelse member(e, last);
Why does the first one not work, but the last one does? It tells me that the operator and the operand don't agree, and maybe I'm thick-headed, but I don't quite understand why they don't?
Thank you in advance!
first=last tries to compare the first element of a list with the tail of that list, and you can only compare things of the same (comparable) type.
The working code works because it doesn't try to compare a list element to an entire list.
You need to compare the first element to the second element, and you need to handle the case of a singleton list.
Something like this:
fun repeats nil = false
| repeats (first::rest) = case rest of
(x::xs) => first = x orelse repeats rest
| _ => false
or
fun repeats nil = false
| repeats (first::rest) = not (null rest)
andalso (first = (hd rest) orelse repeats rest)
It's actually possible to use as to clean up #molbdnilo's answer a fair bit.
Ask yourself: An empty list is false, but so is a list with a single element, right?
fun repeats([]) = false
| repeats([_]) = false
Now, we need to match a list with at least two elements, and compare those. If they're not equal, we'll check everything but the first element.
fun repeats([]) = false
| repeats([_]) = false
| repeats(a::b::tail) =
a = b orelse repeats(b::tail)
But we don't need to use b::tail.
fun repeats([]) = false
| repeats([_]) = false
| repeats(a::(tail as b::_)) =
a = b orelse repeats(tail)
If we want, we can recognize that the empty list and the single element list are just the "other" when the last pattern doesn't match, and we'll rewrite it to reflect that.
fun repeats(a::(tail as b::_)) =
a = b orelse repeats(tail)
| repeats(_) = false
If we have a given predicate p :: [Bool] -> Bool that take an infinite list as parameter and return True or False based on some unknown conditions, and we have no idea what this predicate is.
Can we work out a function f :: ([Bool] -> Bool) -> [Bool] that take such predicate and return an infinite list l where p l == True, assuming that the predicate is satisfiable.
You can think of an infinite list [Bool] as being a binary number with the least significant bit first:
0 = repeat False
1 = True : repeat False
2 = False : True : repeat False
3 = True : True : repeat False
and so on to infinity.
So if you construct a function like this:
intToBools :: Integer -> [Bool]
then you can write
f p = head $ filter p $ map intToBools [0..]
Will this work for every predicate p? Well, if we restrict ourselves to total functions then the p must inspect a finite prefix of its argument, and if any finite prefix is acceptable then that prefix must be reached eventually.
If p is not total but can return True for at least one argument (e.g. the predicate "argument contains at least one True"), then this problem cannot be solved as written because we can't know if p x will ever terminate. However if p could be expressed as a state machine:
newtype BoolPredicate = BoolPredicate (Bool -> Either Bool BoolPredicate)
then you could enumerate every possible input by recursively applying True and False to the output of the previous step in a breadth-first search until you find Left True.
I want to create a predicate same_position(B,X,Y) that is true if element X and element Y have the same position within their respective nested lists.
For example,
same_position([[b,c,f],[a,d,g],[h,e]],c,d) would return true.
same_position(L,E1,E2):-
position(L,E1,N),
position(L,E2,N).
position(LL,E,N):-
member(L,LL),
nth0(N,L,E).
?- same_position([[b,c,f],[a,d,g],[h,e]],c,d).
true
?- same_position([[b,c,f],[a,d,g],[h,e]],b,N).
N = b ;
N = a ;
N = h ;
false.
So using the predicates from your other question this is pretty simple.
Here's my approach:
1. position predicate checks the positions of two elements.
2. It then compares the values.
position([H|T],Element1,Element2):-
checkElement([H|T],Element1,P1),
checkElement([H|T],Element2,P2),
P1=P2.
checkElement([],_,_).
checkElement([H|T],Element,P):-
( member(Element,H)->
nth0(P,H,Element);checkElement(T,Element,P)).
Example:-
?-position([[b,c,f],[a,d,g],[h,e]],b,g).
false
?-position([[b,c,f],[a,d,g],[h,e]],b,a).
true
false
I wrote a function that is giving me a syntax error, not exactly sure why. You can skip to the bottom of this and read the code and error, the rest of the stuff in here is just more information that might not be needed.
I have to make a multiply numbers function that multiplies two lists of numbers and returns the result as a list.
let bigMul l1 l2 =
let f a x = failwith "to be implemented" in
let base = failwith "to be implemented" in
let args = failwith "to be implemented" in
let (_, res) = List.fold_left f base args in
res
It multiplies by pretending representing big ints as lists so 1234x24 is [1;2;3;4] x[2;4] It uses several functions that I already wrote and tested. One is mulByDigit which multiplies each int in a list by an int and returns a list such as [2;3;4;5] 1 would return [2;3;4;5]. It also uses padZero which takes 2 lists of ints and makes them equal in length by adding zeroes to the shorter one and returns a tuple with both lists ex [1;2;3] and [1] would return a tuple with ([1;2;3],[0;0;1]). The last function bigAdd takes 2 lists and adds them and returns the result so like for [1;2;3] [1;2;3] it would give [2;4;6]. All of those functions have been tested and work correctly so Im not gonna provide the code for them.
I wrote a function which follows the logic of taking list l1, multiplying it by every digit of l2 with trailing zeroes depending on the digit and maintaining the sum. Ex if list 1 is [1;2;3;4] and l2 is [2;4] i take the second list and reverse it first of all to get [4;2] and then i multiply 1234 by 4 and get the result. I add this result to the current value in the accumulator which is nothing at first and increment the i to let me know to have a trailing zero for the next one. Then i take the 2 remaining and multiply it by 1234 and have a trailing zero so 24680. I add this to my old accumulator to get the final value and return the value when there are no more numbers left in l2. So 1234+24680=25914. Here is the function that I wrote. a is the accumulator in it, i is for keeping track of how many zeroes I need
let bigMul l1 l2 =
let f (i,a) x =
let sum = padZero ( (mulByDigit x l1)#(clone 0 i) ) a in
in let (first,second) = match sum with
| (y,z)->(y,z) in
( i+1, ( bigAdd first second ) ) in
let base = (0,[]) in
let args = List.rev ( l2 ) in
let (_, res) = List.fold_left f base args in
res
im getting a syntax error when i run it that says unbound value l2. Not sure why so any thoughts.
Here's what I see:
let sum = padZero ( (mulByDigit x l1)#(clone 0 i) ) a in
in let (first,second) = match sum with
There are two in keywords in a row there.
For what it's worth, this:
let (first,second) = match sum with
| (y,z)->(y,z)
in
Is equivalent to:
let (first, second) = sum in
Found it : I wrote in twice
let sum = padZero ( (mulByDigit x l1)#(clone 0 i) ) a in
in let (first,second) = match sum with
write a curried function f1 which takes a list and a positive number n as inputs
and checks whether any element occurs exactly n times in it.
eg.- f1 [1,2,1,3] 2;
val it = true : bool
- f1 [1,2,1,3] 3;
val it = false : bool
You need to count occurrences of each element in your list. You'll need a function which will count occurrences, and a function that will check each element of a list against list itself.
fun isThereCeratinNumberOfOccurences(lst, count) =
let
fun countOccurences(lst, what) =
if null lst
then 0
else if hd lst = what
then 1 + countOccurences(tl lst,what)
else countOccurences(tl lst,what)
fun checkEachElement(lst, elements, number) =
if null elements
then false
else if countOccurences(lst, hd elements) = count
then true
else checkEachElement(lst, tl elements, count)
in
checkEachElement(lst, lst, count)
end