Inserting into a list at an index - sml

I am trying to insert a value into a "register" with SML. If the list (or register) is not defined at that index I need to make a list of 0s up until that index. I have attempted the following but cannot get it to work.
fun storeInReg [] valIns idx =
if idx = 0 then
[valIns]
else
0::storeInReg( [] valIns (idx-1))
| storeInReg head::tail valIns idx =
if idx = 0 then
valIns::t
else
head::storeInReg(tail valIns (idx-1));
idx can only be a value between 0 and 9.
Where am I going wrong?

Your basic logic is okay. Just a few syntax errors:
1) t is unbound in valIns::t. You doubtless meant tail
2) You start by defining fun storeInReg [] valIns idx (the curried form of multi-variable functions common in SML) but then later use things like
storeInReg( [] valIns (idx-1))
where you seem to be trying to pass (an ill-formed) tuple to storeInReg. Instead you need
(storeInReg [] valIns (idx-1))
3) Function evaluation has the highest possible precedence in SML, thus the expression
storeInReg head::tail valIns idx
tries to apply the function to head and then concatenate the result to tail valIns idx -- which makes no sense. Instead you need
storeInReg (head::tail) valIns idx
Making these changes yields:
fun storeInReg [] valIns idx =
if idx = 0 then
[valIns]
else
0::(storeInReg [] valIns (idx-1))
| storeInReg (head::tail) valIns idx =
if idx = 0 then
valIns::tail
else
head::(storeInReg tail valIns (idx-1));
It now works as expected:
- val r = storeInReg [] 5 9;
val r = [0,0,0,0,0,0,0,0,0,5] : int list
- storeInReg r 4 3;
val it = [0,0,0,4,0,0,0,0,0,5] : int list

Related

Stack overflow during evaluation (looping recursion?)

i'm new to ocaml and i'm trying to create a function that takes an int list and turn it into a list of int list that are have the first element + the second element, followed by the rest of the list, until there is one element left, for example:
[1; 2; 0; 4; 2; 1]
[3; 0; 4; 2; 1]
[3; 4; 2; 1]
[7; 2; 1]
[9; 1]
[10]
And here is my code:
let rec nth l k =
match l with
| [] -> 0
| s::t -> if k = 0 then s else nth t (k - 1);;
let no_first l =
match l with
| [] -> []
| s::t -> t
let rec left_comp_once l =
match l with
| [] -> []
| s::t -> (s + nth t 0) :: no_first t
let rec left_comps l =
match l with
| [] -> []
| s::t -> let x = (s + nth t 0) :: no_first t in
[x] # left_comps x
The left_comp_once function works, however, i get looping recursion error when i try the left_comps function
I cannot figure out where the issue is coming from
Also, i would like to have a return element in this format:
int list -> (int list) list
However, what i wrote gives me:
int list -> int list list
What do these parenthesis imply ?
If you look at this expression:
let x = (s + nth t 0) :: no_first t in
[x] # left_comps x
you can see that x can't possibly be an empty list. It always has at least one element. Therefore left_comps will never terminate when given a non-empty list.
Possibly you want to terminate the recursion when the incoming list has length < 2.
Here's a cleaner way to do it, using pattern matching to get the first two elements of the list in a tail-recursive helper function:
let left_comps l =
let rec helper l acc =
match l with
(* Empty list; return the accumulator *)
| [] -> acc
(* Single element list; cons it to the accumulator *)
| _ :: [] -> l :: acc
(* Two or more elements; add the first two together,
cons the original to the accumulator and repeat with
a new shorter list *)
| a :: b :: t -> helper (a + b :: t) (l :: acc) in
helper l []
With this definition,
left_comps [1; 2; 0; 4; 2; 1]
returns
[[10]; [9; 1]; [7; 2; 1]; [3; 4; 2; 1]; [3; 0; 4; 2; 1]; [1; 2; 0; 4; 2; 1]]
What do these parenthesis imply?
Parenthesis in an ocaml type signature usually indicate a function. For example, (int -> int) means a function that takes an int argument and returns an int. You're just returning a list of lists of integers, hence int list list.

OCaml: pell function with int lists

I am trying to write a simple function in OCaml
let rec pell (i: int) =
(if i <= 2 then i (*if given n is less tahn 2 then return 2, else return previous n-1 th term and n-2 nd term recursively*)
else if i>2 then
2 * pell i - 1 + pell i - 2
else failwith "unimplemented" (*else fail with unimplemented message*)
);;
Write an infinite precision version of the pell function from before
pell2 0 = []
pell2 1 = [1]
pell2 7 = [9; 6; 1]
pell2 50 = [2; 2; 5; 3; 5; 1; 4; 2; 9; 2; 4; 6; 2; 5; 7; 6; 6; 8; 4]
I have written below code for this:
let rec pell2 i =
(if i <= 2 then
[] -> i;
else if i=0 then [];
else if i>2 then (*finding pell number and using sum function to
output list with infinite precision...*)
[] -> pell2 i-1 + pell2 i-2;
else failwith "unimplemented"
);;
but still has some syntax errors. Can someone help me with this please.
if i <= 2 then
[] -> i
In snippets like this, the -> is invalid. It looks like you might be mixing pattern matching with match ... with ... and if/else up.
Also, you're first checking if i is less than or equal to 2, but then you have an else to test for i being equal to zero. The first check means the second is never going to happen.
First, let's look at the examples for the output of pell2. We see that pell2 has a single integer parameter, and returns a list of integers. So, we know that the function we want to create has the following type signature:
pell2: int -> int list
Fixing (some but not all of) the syntax errors and trying to maintain your logic,
let rec pell2 i =
if i=0 then []
else if i <= 2 then i
else if i>2 then pell2 i-1 + pell2 i-2
Note that I removed the semicolons at the end of each expression since OCaml's use of a semicolon in its syntax is specifically for dealing with expressions that evaluate to unit (). See ivg's excellent explanation on this. The major flaw with this code is that it does not type check. We see that we conditionally return a list, and otherwise return an int. Notice how above we defined that pell2 should return an int list. So, we can begin fixing this by wrapping our int results in a list:
let rec pell2 n =
if n = 0 then []
else if n <= 2 then [n]
else ... something that will return the Pell number as a list ...
As you have already written, the else branch can be written using recursive calls to the pell2 function. However, we can't write it as you did previously, because pell2 evaluates to a list, and the binary operator + only works on two integers. So, we will have to define our own way of summing lists. Calling this sum_lists, we are left with the following code:
We can now fully define our function pell2:
let rec pell2 n =
if n = 0 then []
else if n <= 2 then [n]
else (* Pell(n) = (2 * Pell(n-1)) + Pell(n-2) *)
let half_of_first_term = pell2 n-1 in
let first_term = sum_lists half_of_first_term half_of_first_term in
let second_term = pell2 n-2 in
sum_lists first_term second_term
So, all that is left is to define sum_lists, so that we are properly summing together two lists of the same format as the return type of pell2. The signature for sum_lists would be
sum_lists: int list -> int list -> int list
I'll give a basic outline of the implementation, but will leave the rest for you to figure out, as this is the main crux of the assignment problem.
let sum_lists lst1 lst2 =
let rec sum_lists_helper lst1 lst2 carry =
match lst1, lst2 with
| [], [] -> if carry = 1 then [1] else []
| h::t, []
| [], h::t -> ...
| h1::t1, h2::t2 -> ...
in
sum_lists_helper lst1 lst2 0

OCaml Counting if char exists in char list : syntax error

let count (l: char list) : bool =
let cnt = 0 in
let rec check l =
match l with
| [] -> false
| h::t -> if h = 'a' then
let cnt + 1
check t
else check t
in check []
;;
what causes the syntax error?
I want to add 1 if 'a' exists and -1 if 'b' exists
You should write it like this :
let rec count l =
match l with
| [] -> 0
| c::t -> if c = 'a' then 1 + count t else count t
But this isn't tail recursive. To make it tail recursive, you'll have to add an accumulator and write an auxiliary function:
let count l =
let rec aux cnt l =
match l with
| [] -> cnt
| c::t -> if c = 'a' then aux (cnt + 1) t else aux cnt t
in
aux 0 l
Now this is tail recursive but a little bit long to write, so you could just use List.fold_left and still have a tail recursive function:
let count l =
List.fold_left (fun cnt c -> if c = 'a' then cnt + 1 else cnt) 0 l
OCaml is a functional language, variables are immutable (their content might be mutable, but that is not the default).
Consequently,
let cnt + 1
is both a syntax error and a logical error: it is not possible to update cnt in such way.
As a first step, I would suggest to write a recursive version of count (and maybe rename it to exists_a) without using ifs :
let rec count l = match l with
| [] -> ...
| 'a' :: t -> ...
| _ :: t -> ...

how to check if list has consecutive powers

I am new to ruby and working on a problem but I don't know how to figure it out.
I want to write a function that return true if each consecutive element is a power of the previous element, otherwise return false
for example: if I have a list [2;4;8;16] the function should return true
function should return false , [3; 7; 9;]
let consec_ele element = match element with
[] -> true
h::t ->
if h > t then false
else
if t/h = 0 && t mod h = 0 then true
;;
i just can't figure out how to make it work and that so recursively.
Well, you first need to formalise your problem :
if my list is empty, then true
if my list is not, then it starts with a number n
if n = 1, then I need to start again because a^0 = 1 for all a
if n > 0 then I call a new function check on the rest of the list, tl, acting like this :
if tl is empty, then true
else tl starts with n' then if n' = n * n then I call check recursively on the rest and I need to keep the fact that I'm now checking for n * n * n ...
If n <= 0 then false
In OCaml this would be
let consec_ele l =
let rec cer b = function
| [] -> true
| n :: tl ->
if n <= 0 then false
(* We can start again for the first 1 we see, but if our
* list is [1; 1; 1; ...; 1] then we need to stop
* That's why we have this boolean b which is true and once
* we see 1 as the head of our list we swap it to false
*)
else if n = 1 then b && cer false tl
else
let rec check p = function
| [] -> true
| n' :: tl -> n' = pow n p && check (p + 1) tl
in check 1 tl
in cer true l;;
(For the pow function, I let you write it ;-) Of course, this can be bad because you could have an overflow, maybe you'd prefer to see if n' ^ (1/p) = n (the pth root of n' (why don't we have LaTeX mathmode on stackoverflow ? :-())
Being able to pattern-match on the first two elements in a list makes this trivial. Obviously an empty list is true, and a list with one element is also true. Otherwise, if we consider the first two elements, if the second is a power of the first, the function is true, and we can discard the first and consider the rest of the list recursively. Otherwise, the result is clearly false.
let rec consec_ele =
function
| [] | [_] -> true
| a::(b::_ as tl) when is_power_of a b -> consec_ele tl
| _ -> false
As a note, your test case of [2;4;8;16] should actually return false as 8 is a multiple, but not a power of 4.

Count occurrence of an element in Haskell list and return max sequence

I have the following code to count the occurrence of an element in a Haskell list:
data Elem = Vanilla | Choco deriving (Eq,Show)
maxStarSeq :: [Elem] -> Int
maxStarSeq [] = 0
maxStarSeq (Vanilla:xs) = 0 + maxStarSeq xs
maxStarSeq (Choco:xs) = 1 + maxStarSeq xs
Now, how can I return the max sequence of that element, instead of an absolute counter? I mean, let's say that my list is:
[Vanilla,Choco,Choco,Vanilla,Choco]
With my code, I will get 3 because there are 3 Choco characters in the list. What I want is to get 2, because that is the max sequence of Choco characters, while the next sequence is shorter.
What I need is some way to make a comparison between the sequences, to evaluate which is longer, or something like that.
You can use group and maximum
import Data.List
maxSeqLength :: Eq a => [a] -> Int
maxSeqLength [] = 0
maxSeqLength xs = (maximum . map length . group) xs
You can use worker wrapper pattern to achieve your required result:
maxStarSeq :: [Elem] -> Int
maxStarSeq xs = aux xs 0 0
where aux [] acc prev = max acc prev
aux (Vanilla:xs) acc prev = aux xs (max acc prev) 0
aux (Choco:xs) acc prev = aux xs acc (prev + 1)
The prev parameter will track the current number of consecutive Choco parameters. The acc parameter will have the maximum number of Choco parameters for it's previous run. It's value will be updated each time you encounter Vanilla value.