Delete the ith element of a list - sml

Write a function that deletes the ith element of a list. If the length of the list is less than i, return the list.
This is the output wanted:
- deleteIth([1,2,3,4,5,6],3);
val it = [1,2,4,5,6] : int list
- deleteIth([1,2,3,4,5,6],7);
val it = [1,2,3,4,5,6] : int list
Here's my code:
fun deleteIth (L, i) =
let
(* Deletes the element of a list at ith index *)
fun delete (nil, i, position) = nil
| delete (x::xs, i, position) = if i = position then xs else
x :: delete (xs, i, position + 1)
in
if i >= 0 andalso i < length L then delete (L, i, 0) else L
end;
note: the line x :: delete (xs, I, position + 1) should be right after the else in the previous line the line wrap made me show the code this way. Sorry for that.
But my code out puts
- deleteIth([1,2,3,4,5,6],3);
val it = [1,2,3,5,6] : int list
- deleteIth([1,2,3,4,5,6],7);
val it = [1,2,3,4,5,6] : int list
I would appreciate the help thanks.

Since you've got your expected results, here's a shorter version that only traverses the list once, and never beyond the element to remove.
(length must traverse the entire list to determine its length. It's possibly the least useful list function.)
The general case, k > 1 and the list is not empty:
To remove the k:th element, remove element k-1 from the tail of the list, then add the head of the original list to the result.
Base cases:
Removing element 1 from a list produces the tail of the list.
Removing anything from the empty list produces the empty list.
The case where the list is shorter than k will terminate when it reaches the empty list.
Like this:
fun delete_ith ([], k) = []
| delete_ith (x::xs, 1) = xs
| delete_ith (x::xs, k) = x :: delete_ith (xs, k - 1)

Related

F# Recursive function for adding even list elements

I have a problem, namely, I would like to turn the following code into a recursive function for adding even list elements, but unfortunately I do not know how much ...
let even = List.filter(fun x -> x%2=0)[1..100]
let sum = List.length even
printfn "Even: %A sum: %d " even sum
Thank you for any help!
You can use pattern matching to check if the first element in your list is even,
and if so, to add it into accumulator list and call the same method on the rest of the list. In case the element is odd - just call the same method for the rest of the list without adding anything to accumulator. When list is empty - return the accumulator and you will have list of just even numbers.
let rec getEven (input : int list) (acc: int list) =
match input with
| head :: tail when head % 2 = 0 -> (getEven tail (head :: acc))
| head :: tail when head % 2 = 1 -> (getEven tail (acc))
| _ -> acc
let even = getEven [1..10] []
let sum = List.sum even
Function above will produce:
val getEven : input:int list -> acc:int list -> int list
val even : int list = [10; 8; 6; 4; 2]
val sum : int = 30
P.S. to calculate sum of the elements, you should use List.sum instead of List.length that will return you the number of elements in list.
Also note, that you can calculate sum of even elements in getEven function, storing not the list of even elements, but their sum.

SML - Get specific Element out of List without using List.nth

im trying to learn the basics of SML atm and stumbled across a task I can't find the answer for.
It is to write a function which takes in an int and a list, returns a specific element in the list on the index of that given int. As you see, it's exactly like the List.nth()-function.
Now I'm curious. This is how far I came, but I just can't think of a way to target a specific index manually.
fun nth(nil, _) = 0
| nth(x::xs, 0) = x;
| nth(x::xs, y) =
val list = [1, 2, 3];
nth(list, 0);
As John suggested, indexing an empty list could raise an exception instead of returning 0. This makes nth work for any type of list, not just the subset of int lists for which 0 can reasonably be considered "no result". It seems that the function lacks recursion to work for any index beyond 0. Here's a template to work with:
fun nth ([], _) = raise Empty
| nth (x::_, 0) = x
| nth (_::xs, n) = ...
Here an exception is added, and the variables that will not be used in each case of the function have been blanked out with the pseudo-variable _. You might want a more informative error message, too.
fun nth ([], n) = raise Fail "Failed to find the appropriate index!"
| nth (x::_, 0) = x
| nth (_::xs, n) = ...
A "safer" version of nth has the type 'a list * int -> 'a option, i.e. for nth (xs, i), if xs has an ith element x, it returns SOME x, and if it doesn't, it returns NONE:
fun nth_safe ([], _) = NONE
| nth_safe (x::_, 0) = SOME x
| nth_safe (_::xs, n) = ...
It's "safer" because it doesn't throw an exception if the list is not long enough. An adversarial example: nth ([0,1,2], 3)
But it still doesn't handle if the index is negative. An adversarial example: nth ([0,1,2], ~1)
You could address that concern inside the ... of the third function body with if n < 0 then ..., but then that would get executed on every recursive step, even though you would most likely only need to check it once.
A robust version of this function raises an error when you pass it a negative index. Otherwise your function might cause you to loop negatively until you run out of memory, since the recursive case (the 3rd case) does not converge towards the two base cases (case 1 and 2). For the exception-based version, you can write:
exception IndexError of int
fun nth (xs, n) =
let fun go ([], _) = raise IndexError n
| go (x::_, 0) = x
| go (_::ys, i) = ...
in if n < 0 then raise IndexError n else go (xs, n)
end
A robust version using error-aware data types could instead look like:
fun nth (xs, n) =
let fun go ([], _) = NONE
| go (x::_, 0) = SOME x
| go (_::ys, i) = ...
in if n < 0 then NONE else go (xs, n)
end
And a robust version using error-aware data types that capture the index error just like the exception-based version with the custom IndexError exception looks like:
datatype ('a, 'b) either = Left of 'a | Right of 'b
fun nth (xs, n) =
let fun go ([], _) = Left n
| go (x::_, 0) = Right x
| go (_::ys, i) = ...
in if n < 0 then Left n else go (xs, n)
end
val example_1 = nth ([2,3,5], 5) (* gives: Left 5 *)
val example_2 = nth ([2,3,5], ~1) (* gives: Left ~1 *)
val example_3 = nth ([2,3,5], 2) (* gives: Right 5 *)
A simple approach:
fun nth (nil,0) = raise Fail "You are out of bounds with nth element"
| nth ((x::xr),n) = if n=0 then x else nth (xr,(n-1))

f# sum list in other way

Hello i resolved problem with ealier task.
Now if i have for example list = [ 2; 3; 2 ; 6 ] want to translate it like this [2;5;7;13].
I declared x as my first element and xs as my rest and used List.scan . Idea below
(fun x n -> x + n) 0
but this make something like this
val it : int list = [0; 2; 5; 7; 13]
How to rewrite it to make list looking like this [2;5;7;13] with using any starting parameter. When i delete 0 i get error message.
Another question how it's going to look like List.Fold i tried to write something similar but it can get only sum of this list ;( .
Here's how I would do this with a fold (with type annotations):
let orig = [2; 3; 2; 6]
let workingSum (origList:int list) : int list =
let foldFunc (listSoFar: int list) (item:int) : int list =
let nextValue =
match listSoFar with
| [] -> item
| head::_ -> head + item
nextValue::listSoFar
origList |> List.fold foldFunc [] |> List.rev
For help learning fold, here's how I would do this with a recursive function:
let workingSum' (origList: int list): int list =
let rec loop (listSoFar: int list) (origListRemaining:int list): int list =
match origListRemaining with
| [] -> listSoFar
| remainHead::remainTail ->
let nextValue =
match listSoFar with
| [] -> remainHead
| head::_ -> head + remainHead
loop (nextValue::listSoFar) remainTail
origList |> loop [] |> List.rev
Note that the signature of the inner loop function is really similar to the foldFunc of the previous example, with one major difference: instead of being passed in the next element, it's being passed in the remainder of the original list that hasn't been processed yet. I'm using a match expression to account for the two different possibilities of that remainder of the original list: either the list is empty (meaning we're done), or it's not (and we need to return a recursive call to the next step).

OCaml recursive function int list -> int -> (int list * int list)

Studying for a midterm and was looking through some old exam questions. This one doesn't have a solution posted and is stumping me:
partition: int list -> int -> (int list * int list) divides its
first argument into two lists, one containing all elements less than
its second argument, and the other all the elements greater than or
equal to its second argument. partition [5;2;10;4] 4 = ([2],
[5;10;4])
oh, and i'm supposed to be able to find the solution without using an auxiliary function
here is as far as i've gotten:
let rec partition l n = match l with
| [] -> ([], []) (* must return this type *)
| x :: xs -> if x < n then (* append x to first list, continue recursing *)
else (* append x to second list, continue recursing *)
normally, I'd use an aux function with an extra parameter to store the pair of lists i'm building, but that can't be done here. i'm a bit stuck
You should use the let in construction to match the return value of the recursive call:
let rec partition l n = match l with
| [] -> ([], [])
| x :: xs -> let a, b = partition xs n in
if x < n then (x::a), b
else a, (x::b);;

SML "('a list * int) -> ('a list, boolean)"

So this is my question: i wanna make a function that takes a list and and int, it then recursively moves through the list, and if it finds an element in the list equal to the int, then it should return the entire list with the element removed, and a boolean indicating wether something was removed. this is what i got so far:
fun foo ([], n) = ([],false)
| foo ((x::xs), n) = if x = n
then (xs,true)
else ([x] # foo(xs,n),false);
my idea was to make the function cons the needed elements inside the tuple like this:
([x0] # [x1] # [x2] # [xs], true)
so is there any way to make this function? keep in mind that it has to stop once it hits the element equal to n, but still retain the rest of the list, and be able to return a boolean. run time is key.
Your current code is close to correct logically, but as you know it doesn't type-check because of [x] # foo (xs, n). foo returns a tuple, which can't be directly appended. Here's how to fix it:
fun foo ([], n) = ([], false)
| foo (x::xs, n) = if x = n
then (xs, true)
else let val (xs', tf) = foo (xs, n) in (x::xs', tf) end
The let is needed to extract the list from the tuple and find out if n was found in the tail of the list. Then we simply put the tuple back together with x consed back on to the front.