How can I modify this code to accept lists of different lengths?
Modify the function rippleCarryAdder to accept lists of different lengths. For example, the call (rippleCarryAdder [true] [false; true]) should evaluate to ([true; false], false), i.e., 1 + 01 evaluates to 2 with no overflow.
let xor a b = (a || b) && (not (a && b))
(* fullAdder : bool -> bool -> bool -> (bool * bool)
*
* The call (fullAdder a b carryIn) adds the bits a, b and carryIn
* producing the sum and the carry out.
*)
let fullAdder a b cin =
let c = xor a b in
let sum = xor c cin in
let carryOut = (c && cin) || (a && b)
in
(sum, carryOut)
(* rippleCarryAdder : bool list -> bool list -> bool -> (bool list * bool)
*
* The call (rippleCarryAdder ms ns carryIn) implements a ripple carry
* adder.
*)
let rippleCarryAdder ms ns =
let rec repeat ms ns carryIn acc =
match (ms, ns) with
| ([], []) -> (acc, carryIn)
| (m::ms, n::ns) -> let (sum, carryOut) = fullAdder m n carryIn
in
repeat ms ns carryOut (sum::acc)
in
repeat (List.rev ms) (List.rev ns) false []
let fill_in a (ms,ns) =
let rec fill_left a = function
([],[]) -> []
| ([],_::ns) -> a::fill_left a ([],ns)
| (m::ms,[]) -> m::fill_left a (ms,[])
| (m::ms,_::ns) -> m::fill_left a (ms,ns)
in
let rec fill_right a = function
([],[]) -> []
| (_::ms,[]) -> a::fill_right a (ms,[])
| ([],n::ns) -> n::fill_right a ([],ns)
| (_::ms,n::ns) -> n::fill_right a (ms,ns)
in
(fill_left a (ms,ns),fill_right a (ms,ns))
let rippleCarryAdder2 ms ns =
let (ms,ns)=fill_in false (List.rev ms,List.rev ns) in
rippleCarryAdder (List.rev ms) (List.rev ns)
Test:
# fill_in false ([true;false],[true;false;true;true]);;
- : bool list * bool list =
([true; false; false; false], [true; false; true; true])
# fill_in 0 ([1;1;0;1],[2;3]);;
- : int list * int list = ([1; 1; 0; 1], [2; 3; 0; 0])
# rippleCarryAdder2 [true] [false;true];;
- : bool list * bool = ([true; false], false)
Related
Write with OCaml Longest Common Sottosequence (Deep Search)
Consider a finite set S of strings and an integer K. Determine, if it exists, a string x of length greater than or equal to K subsequence of each string s∈S. The problem is solved by using an in-depth search.
I tried it with two strings without k, it works!
this bellow is my code:
(*trasfmorm string in list char*)
let explode s =
let rec exp i l =
if i < 0 then l
else exp (i - 1) (s.[i] :: l)
in
exp (String.length s - 1) []
(*print list of strings*)
let rec print_list_strings = function
| [] -> ()
| e::l ->
print_string e;
print_string "\n";
print_list_strings l
(*print list of char*)
let rec print_list_char = function
| [] -> print_string "\n"
| e::l ->
print_char e;
print_string " ";
print_list_char l
(*between the lists tell me which one is longer*)
let longest xs ys =
if List.length xs > List.length ys then xs
else ys
(*lcs deep*)
let rec lcs a b =
match a, b with
| [], _ | _, [] -> []
| x::xs, y::ys ->
if x = y then
x :: lcs xs ys
else
longest (lcs a ys) (lcs xs b)
(*
On input: "ABCBDAB", "ABCBDAB"
The LCS returned is "BDAB"
*)
let a = "ABCBDAB";;
let b = "ABCBDAB";;
let a = explode a;;
let b = explode b;;
print_list_char (lcs a b);;
But when I start to find the solution for s strings it seems impossible.
For the moment i write the code bellow:
(* function return n-elemt of a list *)
exception Nth
let rec nth n lista =
match (n, lista) with
| (_, []) -> raise Nth
| (0, t::_) -> t
| (n, t::c) -> nth (n-1) c;;
(* functione given input list of char output string *)
let rendi_stringa s =
String.of_seq (List.to_seq s)
(* delete first n-element of a string *)
let rec drop n = function
| [] -> []
| x::xs ->
if n <= 0 then x::xs
else drop (n-1) xs ;;
(*string into a char list*)
let explode s =
let rec exp i l =
if i < 0 then l
else exp (i - 1) (s.[i] :: l)
in
exp (String.length s - 1) []
(*read k-elemt and return a list*)
let rec leggi k =
if k=0 then []
else
let x = read_line() in
(x) :: leggi (k-1)
(*print element list*)
let rec print_list = function
| [] -> ()
| e::l ->
print_string e;
print_string "\n";
print_list l
(*funzione lista string esplosa--> lista di lista*)
let rec explode_list n lista =
if n = 0 then []
else
let x = List.hd lista in
[(explode x)] # explode_list (n-1) (List.tl lista)
(*n-esima raw e m-column of matrix*)
let pos tabla n m =
let lista = (List.nth tabla n) in
List.nth lista m;;
let subset tabella n =
let rec aux solution tot = function
| [] ->
if tot > 0 then raise NotFound
else solution
| x::rest ->
print_string x;
print_string "\n";
aux (x::solution) (tot-1) rest
in
aux [] n tabella
let subset tabella n =
let rec aux solution = function
| [] ->
if List.length solution < n then raise NotFound
else solution
| x::rest -> nuova_funzione (explode x) rest n
in
aux [] n tabella
let nuova_funzione lista_char lista_string n = function
| _, [] -> print_string "non posso piu fare niente, stringhe finite\n"
| [], _ -> print_string "ho finito confronto con la lista\n"
| [] , x::lt ->
if (lcs lista_char (explode x)) > n then
else
let longest xs ys =
if List.length xs > List.length ys then xs
else ys
(*lcs profonda*)
let rec lcs a b =
match a, b with
| [], _ | _, [] -> []
| x::xs, y::ys ->
if x = y then
x :: lcs xs ys
else
longest (lcs a ys) (lcs xs b)
(**)
(*let rec lcs stringhe num = function
| []
| List.length stringhe < num -> []
| *)
(*------------------------main--------------*)
print_string "how many strings?\n";;
let m = read_int();;
print_string "please write your strings\n";;
let lista = leggi m;;
print_string "strings wrote\n";;
print_list lista;;
explode (nth 0 c);;
let a = "ABCBDAB";;
let a = explode a;;
let b = "BDCABA";;
let b = explode b;;
let c = "BADACB";;
let c = explode c;;
My idea was to use Backtracking, but i'm stuck with logical idea, I have no idea to implement it even with pseudocode!
Any idea or advise?
Why my merge function complains about its type ?
Isn't my x a type 'a seq ?
type 'a seq = Stop | Cons of 'a * (unit -> 'a seq)
let rec linear start step= (*builds a seq starting with 'start'*)
Cons (start, fun () -> linear (start+step) step)
let rec take n seq = match seq with (*take first n elem from seq*)
| Stop -> []
| Cons (a, f) -> if n < 1 then [] else a::(take (n-1) (f ()))
let rec merge seq1 seq2 = match seq1, seq2 with
| Stop, _ -> seq2
| _, Stop -> seq1
| Cons(h1, tf1), _ as x ->
Cons(h1, fun () -> merge (x) (tf1 ()))
let l1 = linear 1 1
let l2 = linear 100 100
let l3 = interleave l1 l2
I would like to see the right result for
take 10 l3
int list = [1; 100; 2; 200; 3; 300; 4; 400; 5; 500]
Another way to write my function (which works) would be
let rec merge seq1 seq2 = match seq1 with
| Stop -> Stop
| Cons (h, tf) -> Cons(h, fun () -> merge seq2 (tf ()))
but I don't get it , why the first merge doesn't work.
Thanks.
Just write (_ as x) because here, your as x catches the whole pattern.
So, what you see as :
| Cons(h1, tf1), (_ as x) -> ...
is actually parsed as
| (Cons(h1, tf1), _) as x -> ...
And you could actually write :
| Cons(h1, tf1), x -> ...
Which is far better ;-)
Or even
| Cons(h1, tf1), _ -> Cons(h1, fun () -> merge seq2 (tf1 ()))
So here is what I have so far. It feels close but im not sure how to fix the problems in line 84 (2nd to last line: elif List.append(isolate(a),isolate(b)) != [] then List.append(isolate(a),isolate(b))).
(* val isolate : l:'a list -> 'a list when 'a : equality *)
let rec isolate (l:'a list) =
match l with
| [] -> []
| x::xs ->
if memberof(x,xs)
then
let xs = remove (x,l)
isolate xs
else isolate xs
( * val common : 'a list * 'a list -> 'a list when 'a : equality *)
let rec common (k: 'a list, l:'a list) =
match ((k:'a list),(l:'a list)) with
| (a, b) ->
if a=[] then []
elif b=[] then []
elif List.append(isolate(a),isolate(b)) != [] then List.append(isolate(a),isolate(b))
else []
edit:
asked to post whole code:
(* val sumlist : l:float list -> float *)
let rec sumlist l =
match (l:float list) with
| [] -> 0.0
| a::x -> (sumlist x) + a
(* :: creates a list. *)
sumlist([1.0;2.0;3.0])
(* val squarelist : l:float list -> float list *)
let rec squarelist l =
match (l:float list) with
| [] -> []
| a::x -> (a*a)::(squarelist x)
(* val mean : l:float list -> float *)
let mean l =
match (l:float list) with
| [] -> 0.0
| l -> (sumlist l)/(float)l.Length
mean([1.0;2.0;3.0])
(* val mean_diffs : l:float list -> float list *)
let mean_diffs l =
match l with
set a = mean(l)
| [] -> []
let rec diffs (a,l)=
match l with
| x::xs -> (x-(mean(l))::diffs(xs)
| [] -> l
mean_diffs([1.0;2.0;3.0])
(* val variance : l:float list -> float *)
let variance l =
match (l:float list) with
| [] -> 0.0
| l -> (sumlist (squarelist (mean_diffs l)))/(float)l.Length
(* End of question 1 *) (* Do not edit this line. *)
(* Question 2 *) (* Do not edit this line. *)
(* val memberof : 'a * 'a list -> bool when 'a : equality *)
let rec memberof l=
match (l: 'a * 'a list) with
| (t,[]) -> false
| (t, x::xs) when t=x -> true
| (t, x::xs) -> t=x || memberof(t,xs)
(* val remove : 'a * 'a list -> 'a list when 'a : equality *)
let rec remove ((k:'a),(l:'a list)) =
match l with
| [] -> []
| x::xs when x=k -> xs
| x::xs ->x::(remove(k,xs))
(* End of question 2 *) (* Do not edit this line *)
(* Question 3 *) (* Do not edit this line *)
(* val isolate : l:'a list -> 'a list when 'a : equality *)
let rec isolate (l:'a list) =
match l with
| [] -> []
| x::xs ->
if memberof(x,xs)
then
let xs = remove (x,l)
isolate xs
else isolate xs
(* End of question 3 *) (* Do not edit this line *)
(* Question 4 *) (* Do not edit this line *)
(* val common : 'a list * 'a list -> 'a list when 'a : equality *)
let rec common (k: 'a list, l:'a list) =
match ((k:'a list),(l:'a list)) with
| (a, b) ->
if a=[] then []
elif b=[] then []
elif List.append(isolate(a),isolate(b)) <> [] then List.append(isolate(a),isolate(b))
else []
common([1.0;2.0;6.0;10.0],[5.0;6.0;10.0])
It seems that <> has fixed the problem but do you have any advice on my function mean_diffs?
Since this appears that you are working on a course and it is building upon the previous exercises, the code is converted to more F# idiomatic and a standardized format of recursive functions to make them easier to use when you get to currying See: F# for fun and profit and Functions as First-Class Values (F#) and other more advanced concepts.
The format is basically
let funXYZ list =
let rec funXYZInner list acc =
match list with
| head :: tail ->
let acc = (somefunc head) :: acc
funXYZInner tail acc
| [] -> acc
funXYZInner list []
where funXYZ is an exposed function name that does NOT have a rec. I can't recall the source but if you can implement a function needing a rec with the rec not being exposed it makes the code more portable.
The basic concept is that you take a list and pull the list apart into a head and tail:
head :: tail
then you process the head:
somefunc head
then accumulate the result into the accumulator
let acc = value :: acc
let acc = value + acc
let acc = acc + (value * value)
then process the remainder of the list, e.g. tail, passing the accumulator
funXYZInner tail acc
When the input list matches empty
| []
just return the result which was accumulated in the accumulator
acc
The inner function funXYZInner does have a rec and uses an accumulator, i.e. acc. This will help in understanding how to use tail calls which will keep you from running out of memory on large computations.
You probably know already that with match statements you want to cover all of the cases of the match variable. This is because of algebraic data types and is the reason you see those warnings about not all cases being covered. If you see one of those warnings and don't know why you are getting it you need to fix them, or run the risk of unexpected runtime errors or crashes.
While the code you gave can only work with float type list, in the future to make it work with more types you will need to learn about LanguagePrimitives.GenericZero<^T> Type Function (F#).
There are some more basic functions that were added because they were needed, e.g. reverse, and help to show the progression as the examples get more complex.
Do to the fact that examples build upon themselves and you had a specific error in the last one, it was better to give the examples a better foundation which should mitigate common problems encountered when first learning about recursive functions.
With regards to the accumulator, the accumulator can hold different types, e.g. float, list, int, and there can be more than one accumulator being used in the recursive function, e.g. numeratorAcc, denominatorAcc. Also by pulling out the calculation of the accumulator value, e.g.let acc = ..., when you get to more advanced functions you can just pass in a function to replace that calculation.
There is one predicate function memberof which does not use an accumulator. A predicate is a function that returns true or false, and once you reach the desired value you can stop processing the remainder of the list.
Also of note is that while some of the functions could call earlier defined functions, the examples don't make the calls so that they can process the list in one pass. When functions call other functions with list, each function has to process the entire list to return the result. By using rec functions it is sometimes possible to process the list once by doing multiple calculations with the head. However there are times this cannot be done. I did not maximize the functions one way or the other but left them a way that give more variation for learning. Feel free to rewrite them which will lead to function composition.
You will probably have more questions about these examples, so please ask as separate SO questions instead of building on this one.
All the code
// val reverse : l:'a list -> 'a list
let reverse l =
let rec reverseInner l acc =
match l with
| x::xs ->
let acc = x :: acc
reverseInner xs acc
| [] -> acc
reverseInner l []
reverse [ 3.0; 2.0; 1.0 ] // val it : float list = [1.0; 2.0; 3.0]
// val length : l:'a list -> int
let length l =
let rec lengthInner l acc =
match l with
| x::xs ->
let acc = acc + 1
lengthInner xs acc
| [] -> acc
lengthInner l 0
length [ 3.0; 2.0; 1.0 ] // val it : int = 3
// val sum : l:float list -> float
let sum l =
let rec sumInner l acc =
match l with
| x::xs ->
let acc = acc + x
sumInner xs acc
| [] -> acc
sumInner l 0.0
sum [ 1.0; 2.0; 3.0 ] // val it : float = 6.0
// val square : l:float list -> float list
let square (l : float list) =
let rec squareInner l acc =
match l with
| x::xs ->
let acc = (x * x) :: acc
squareInner xs acc
| [] -> reverse acc
squareInner l []
square [ 1.0; 2.0; 3.0 ] // val it : float list = [1.0; 4.0; 9.0]
// val mean : l:float list -> float
let mean l =
let rec meanInner l sumacc lengthacc =
match l with
| x::xs ->
let sumacc = sumacc + x
let lengthacc = lengthacc + 1.0
meanInner xs sumacc lengthacc
| [] -> sumacc / lengthacc
meanInner l 0.0 0.0
mean([1.0;2.0;3.0]) // val it : float = 2.0
// val mean_diffs : l:float list -> float list
let meanDiff l =
let rec meanDiffInner l m acc =
match l with
| x::xs ->
let diff = (x - m)
let acc = diff :: acc
meanDiffInner xs m acc
| [] -> reverse acc
meanDiffInner l (mean l) []
meanDiff [ 1.0; 2.0; 3.0 ] // val it : float list = [-1.0; 0.0; 1.0]
// From: https://en.wikipedia.org/wiki/Variance
// Suppose a population of numbers consists of 3, 4, 7, and 10.
// The arithmetic mean of these numbers, often informally called the "average", is (3+4+7+10)÷4 = 6.
// The variance of these four numbers is the average squared deviation from this average.
// These deviations are (3–6) = –3, (4–6) = –2, (7–6) = 1, and (10–6) = 4.
// Thus the variance of the four numbers is ((-3)^2 + (-2)^2 + (1)^2 + (4)^2) / 4 = 15/2 = 7.5
// val variance : l:float list -> float
let variance l =
let deviations = meanDiff l
let rec varianceInner l numeratorAcc denomenatorAcc =
match l with
| devation::xs ->
let numeratorAcc = numeratorAcc + (devation * devation)
let denomenatorAcc = denomenatorAcc + 1.0
varianceInner xs numeratorAcc denomenatorAcc
| [] -> numeratorAcc / denomenatorAcc
varianceInner deviations 0.0 0.0
variance [ 1.0; 2.0; 3.0 ] // val it : float = 0.6666666667
variance [ 3.0; 4.0; 7.0; 10.0 ] // val it : float = 7.5
(* End of question 1 *) (* Do not edit this line. *)
(* Question 2 *) (* Do not edit this line. *)
// val memberof : l:'a list -> item:'a -> bool when 'a : equality
let memberof l item =
let rec memberInner l item =
match l with
| x::xs ->
if x = item then
true
else
memberInner xs item
| [] -> false
memberInner l item
memberof [ 1.0; 2.0; 3.0 ] 0.0 // val it : bool = false
memberof [ 1.0; 2.0; 3.0 ] 1.0 // val it : bool = true
memberof [ 1.0; 2.0; 3.0 ] 2.0 // trueval it : bool = true
memberof [ 1.0; 2.0; 3.0 ] 3.0 // val it : bool = true
memberof [ 1.0; 2.0; 3.0 ] 4.0 // val it : bool = false
// val remove : l:'a list -> item:'a -> 'a list when 'a : equality
let remove l item =
let rec removeInner l item acc =
match l with
| x::xs ->
if x = item then
removeInner xs item acc
else
let acc = x :: acc
removeInner xs item acc
| [] -> reverse acc
removeInner l item []
remove [ 1.0; 2.0; 3.0 ] 0.0 // val it : float list = [1.0; 2.0; 3.0]
remove [ 1.0; 2.0; 3.0 ] 1.0 // val it : float list = [2.0; 3.0]
remove [ 1.0; 2.0; 3.0 ] 2.0 // val it : float list = [1.0; 3.0]
remove [ 1.0; 2.0; 3.0 ] 3.0 // val it : float list = [1.0; 2.0]
remove [ 1.0; 2.0; 3.0 ] 4.0 // val it : float list = [1.0; 2.0; 3.0]
(* End of question 2 *) (* Do not edit this line *)
(* Question 3 *) (* Do not edit this line *)
// val isolate : list:'a list -> 'a list when 'a : equality
let isolate list =
let rec isolateInner searchList commonlist =
match searchList with
| x::xs ->
if (memberof commonlist x) then
isolateInner xs commonlist
else
let commonlist = (x :: commonlist)
isolateInner xs commonlist
| [] -> reverse commonlist
isolateInner list []
isolate [ 1.0; 2.0; 3.0 ] // val it : float list = [1.0; 2.0; 3.0]
isolate [ 1.0; 1.0; 2.0; 3.0 ] // val it : float list = [1.0; 2.0; 3.0]
isolate [ 1.0; 2.0; 2.0; 3.0 ] // val it : float list = [1.0; 2.0; 3.0]
isolate [ 1.0; 2.0; 3.0; 3.0 ] // val it : float list = [1.0; 2.0; 3.0]
isolate [ 3.0; 2.0; 1.0; 1.0; 2.0; 3.0; 2.0; 1.0; 1.0; 3.0] // val it : float list = [3.0; 2.0; 1.0]
(* End of question 3 *) (* Do not edit this line *)
(* Question 4 *) (* Do not edit this line *)
// val common : a:'a list -> b:'a list -> 'a list when 'a : equality
let common a b =
let rec commonInner a b acc =
match (a,b) with
| (x::xs,b) ->
if (memberof acc x) then
commonInner xs b acc
else
let acc = x :: acc
commonInner xs b acc
| ([],y::ys) ->
if (memberof acc y) then
commonInner [] ys acc
else
let acc = y :: acc
commonInner [] ys acc
| ([],[]) -> reverse acc
commonInner a b []
common [ 1.0; 2.0; 6.0; 10.0] [ 5.0; 6.0; 10.0 ] // val it : float list = [1.0; 2.0; 6.0; 10.0; 5.0]
Why the code below is wrong?
Even though the first two results are correct but the last one should return false, it returns true instead. Why so?
let rec is_sorted x = match x with
|h::h2::[] -> if h <= h2 then true else false
|h::h2::t -> if h <= h2 then is_sorted h2::t else false
# is_sorted [4;5;6;5;9];;
- : bool = false
# is_sorted [4;5;6;7;9];;
- : bool = true
# is_sorted [4;5;6;18;9];;
- : bool = true
I'll write the following:
let rec is_sorted x = match x with
| [] -> true
| h::[] -> true
| h::h2::t -> if h <= h2 then is_sorted (h2::t) else false;;
Then:
# is_sorted [];;
- : bool = true
# is_sorted [1];;
- : bool = true
# is_sorted [4;5;6;5;9];;
- : bool = false
# is_sorted [4;5;6;7;9];;
- : bool = true
# is_sorted [4;5;6;18;9];;
- : bool = false
A bit shorter:
let rec is_sorted = function
| x::y::l -> x <= y && is_sorted (y::l)
| _ -> true
This is how I would do it.
let rec sorted x =
match x with
| [] -> true
| [_] -> true
| a::b::t when a <= b -> sorted (b::t)
| _ -> false
;;
The following will check if an int list is sorted in ascending or descending:
let is_sorted l =
let rec aux l cmp =
match l with
| [] | [_] -> true
| x :: ((y :: _) as t) -> cmp x y && aux t cmp
in
aux l ( <= ) || aux l ( >= )
I want to go through an array and return a list of ints (the value of indexes) when a value in the array matches true.
The array is a boolean array of just true/false values.
let get_elements (i:int)(b:bool) : int =
if b = true then (i::l)
else (())
;;
let rec true_list (b: bool array) : int list =
(fun i l -> get_elements i l)
;;
The syntax is wrong for my code and I am confused on exactly how to return a list of ints.I only want to return the indexes of those elements that are true in the array.
You refer to 'l' in get_elements, but it's not in the scope of that function.
Here's an approach using a ref to an integer list (a mutable list):
boolarray = [|true; false; true; false; false; true|] ;;
type ilist = (int list) ref ;;
let intlist () : ilist = ref [] ;;
let push ( l: ilist) (x: int) : unit = l := x::(!l) ;;
let lst = intlist () ;;
Array.iteri ( fun i b -> if b = true then (push lst i )) boolarray ;;
!lst ;; (* => int list = [5; 2; 0] *)
Or, if you'd rather avoid refs (which is usually a good idea) this is cleaner:
let get_true_list (b: bool array) : int list =
let rec aux i lst =
if (i = Array.length b) then lst else
(if b.(i) = true then ( aux (i+1) (i::lst)) else (aux (i+1) lst)) in
aux 0 [] ;;
(* using boolarray defined above *)
get_true_list boolarray ;; (* => int list = [5; 2; 0] *)
I present an example which does not use state, avoids the 'if then else' construct making it easier to read and verify.
let mylist = [| true; false; false; true; false; true |] in
let get_true_indexes arr =
let a = Array.to_list arr in
let rec aux lst i acc = match lst with
| [] -> List.rev acc
| h::t when h = true -> aux t (i+1) (i::acc)
| h::t -> aux t (i+1) acc
in
aux a 0 []
in
get_true_indexes mylist