I have the following function that should calculate an area using each value in the list.
The problem I have is that the function only prints the first result for the first item in the list, and what I need to print for each item in the list.
You can think that each item in the list is a case and I would like to print all cases.
area([H|_])->(math:sqrt(3.0) * (H*H)) - (3.14 * (H*H))/2;
area([_|T])-> area(T).
You've got the recursion wrong. What should be done is that you print the area of the head, then recurse on the tail. You'll also need to add a base case, handling empty list.
area([]) -> ok;
area([H|T]) ->
io:format("~p~n", [(math:sqrt(3.0) * (H*H)) - (3.14 * (H*H))/2]),
area(T).
If you instead want a list of areas as the result, you can do:
area([]) -> [];
area([H|T]) ->
[(math:sqrt(3.0) * (H*H)) - (3.14 * (H*H))/2 | area(T)].
Related
I am new to F# and have stumbled on a problem that I am interested in. I am trying to recreate similar functionality to List.reduce with recursion instead. The function uses sumTwoPoints to calculate the sum of two elements in a list of coordinates and returns one element.
let sumTwoPoints(x1, y1) (x2, y2) : float * float = (x1 + x2, y1 + y2)
What I have done so far:
let rec pathSum list =
match list with
| [] -> failwith "Empty List"
| head::next::rest -> sumTwoPoints head next :: rest
My thought process is this
// e0() e1() e2() e3() e4()...
// sumTwoPoints (e0 e1) = r1
// sumTwoPoints (r1 e2) = r2
// sumTwoPoints (r2 e3) = r3
// sumTwoPoints (r3 e4) = r4
// pathSum = r4
The e0 represents the element in the list. If we go by this system, head = e0 and tail = e1 and the rest list has leftover elements. I am not sure about adding the new r1 to the rest list, but that is what I came up with. The next step, if my logic is correct, is to pass this new list to pathSum, but get again, I don't know how to achieve that in the code.
My proposed solution might be completely wrong, and any advice or help would be appreciated.
You'd need to modify your function to add a parameter for the current point.
The logic would be that it adds the 'head' of the list to that point, then recursively calls itself with the result of that addition and the rest of the list. When it's finally called with an empty list, it simply returns the point value.
let rec pathSum (current:float * float) list =
match list with
| [] -> current
| head::rest ->
let next = sumTwoPoints head current
pathSum next rest
The initial call would have to pass an initial value of (0, 0):
pathSum (0, 0) list
A follow up to what Charles Mager as answered you need to look at list. It can either be empty []or have the value of another list x::y. If you take a closer look at your functions
sumTwoPoints : (float * float) -> (float * float) -> (float * float)
pathSum : (float * float) list -> (float * float)
This way you have rest as the type of (float * float) list which when called with pathSum gives the type (float * float). This way you can utilize the function sumTwoPoints without the need of next
let rec pathSum list =
match list with
| [] -> (0.0, 0.0)
| head::rest ->
sumTwoPoints head (pathSum(rest))
And lastly you will need to change failwith to give zero as otherwise it will fail the recursion.
I would like to subtract two consecutive element in a list with numbers in Scala.
For example : I have this list :
val sortedList = List(4,5,6)
I would like to have an output list like diffList =(1, 1) where 5-4 = 1 and 6-5 = 1.
I tried the following code:
var sortedList = List[Int]()
var diffList = List[Int]()
for (i <- 0 to (sortedList.length - 1) ;j <- i + 1 to sortedList.length - 1)
{
val diff = (sortedList(j) - sortedList(i))
diffList = diffList :+ diff
}
I have the following result for diffList =(1, 2, 1) but I want diffList = (1,1).
It's because of the for loop. it does not iterate over the two variables (i and j) at once.
You do not mutability nor imperative programming to solve this problem, functional programming got you covered.
def consecutiveDifferences(data: List[Int]): List[Int] =
if (data.isEmpty) List.empty
else data.lazyZip(data.tail).map {
case (x, y) => y - x
}
As I always say, the Scaladoc is your friend.
(Also, as an advice, the best way to learn functional programming is to forbid yourself from mutability)
You can use the sliding method, which according to the docs:
/** Groups elements in fixed size blocks by passing a "sliding window"
* over them (as opposed to partitioning them, as is done in `grouped`.)
*
* An empty collection returns an empty iterator, and a non-empty
* collection containing fewer elements than the window size returns
* an iterator that will produce the original collection as its only
* element.
* #see [[scala.collection.Iterator]], method `sliding`
*
* #param size the number of elements per group
* #return An iterator producing ${coll}s of size `size`, except for a
* non-empty collection with less than `size` elements, which
* returns an iterator that produces the source collection itself
* as its only element.
* #example `List().sliding(2) = empty iterator`
* #example `List(1).sliding(2) = Iterator(List(1))`
* #example `List(1, 2).sliding(2) = Iterator(List(1, 2))`
* #example `List(1, 2, 3).sliding(2) = Iterator(List(1, 2), List(2, 3))`
*/
Then, solving your query is pretty straight forward:
diffList = sortedList.sliding(2).collect {
case Seq(a, b) =>
b - a
}.toList
Which results in List(1,1)
Code run at Scastie.
for(i <- 0 until (sortedList.size - 1)) yield sortedList(i + 1) - sortedList(i)
yield Vector(1,1) which can be converted to list with toList
That's can be also achieved with the following function:
val sortedList = List(4,5,7)
#tailrec
def findDiffs(xs: List[Int])(seed: List[Int]): List[Int] = {
if(xs.isEmpty || xs.size == 1) seed.reverse
else {
val currDiff = xs(1) - xs(0)
findDiffs(xs.tail)(currDiff :: seed)
}
}
val res = findDiffs(sortedList)(Nil)
println(res)
Or just easily with zip:
sortedList.drop(1) zip sortedList map { case (x,y) => x - y }
Sliding (see answer by #Tomer Shetah) over a list delivers an iterator, which may prove convenient for very large collections to avoid/reduce the amount of intermediate structures in the processing. Another approach includes the zipping of the list with itself shifted by one (see answers by #Luis Miguel Mejía Suárez and #Zvi Mints); in this regard another approach to shifting and then zipping is by dropping the first element as in
xs.drop(1) zip xs map {case(a,b) => b-a}
This can be generalised by dropping any number n so that we subtract the first and the n-th elements, then the second and the n+1-th elements, and so forth.
I have three type :
type position = float * float
type node = position
type edge = node * node * float
And I'd like to make a list of edge by using a list of node by doing this :
let create_type_list nodes_list =
let rec create_type_list_aux nodes =
match nodes with
| [] -> []
| x::y::l -> Some (x,y, dist2 x y) # create_type_list_aux l
in create_type_list_aux nodes_list
dist2 is just a function that calculates the distance between two nodes.
I'm left wondering why such a function can't work and how I could be able to reach my goal of creating a list of type. I have the following error :
Error: This variant expression is expected to have type 'a list
The constructor Some does not belong to type list
Thanks
The expression you're using to build up the list is presumably this:
Some (x,y, dist2 x y) :: create_type_list_aux l
Indeed this adds an element to the front of the list of type (position * position * float) option. However, the type position is the same as the type node. So this is also type (node * node * float) option. This, in turn is the same as edge option. So your only problem is that you're adding an edge option to your list rather than an edge. You might try using this expression instead:
(x, y, dist2 x y) :: create_type_list_aux l
The only difference is that I removed Some, which is a constructor of the option type.
I have an sml-nj project in which I want to work with a 'list of lists' structure, which has "Squares". I'm trying to insert values to the list of lists recursively, but I still haven't understood how to insert elements to a 2d list.
Note - I CAN'T USE 'REF', ONLY http://smlfamily.org/Basis/list.html#SIG:LIST.app:VAL these functions.
datatype SquareContent = Mine | Digit of int | Blank;
datatype Square = Revealed of SquareContent | Concealed of SquareContent;
fun createMineSweeperGrid (n:int)
:(Square list list)=
let
fun createMines (rowCounter:int, colCounter:int
, retGame:Square list list):(Square list list) =
if rowCounter=n then
retGame (* finished all rows, should be n lists of size n*)
else
if colCounter=n then (*finished current row, move on*)
createMines (rowCounter+1, 0, mines,retGame)
else
let
val squareToInsert = Concealed(Mine) (* I wish to insert 'squareToInsert'
to retGame[rowCounter][colCounter], it's done dynamically, but I don't know
how to do that *)
in
createMines (rowCounter, colCounter+1, retGame)
end
in
createMines (0,0,[])
end
I could insert any kind of Square, it's decided dynamically and here I gave example only of concealed Mine so you can help me.. HELP..?
The essential thing to recognize is that in Standard ML, you don't mutate existing structures; rather, you create new ones. (Standard ML does support mutable structures, via ref and its friends, but it's not something to do lightly, and I see that you've already — rightly — ruled it out.)
In general, therefore, inserting something into the middle of a linked list is pretty expensive: it requires "unwinding" the list to the point where you want to insert, then inserting the value, and lastly building a copy of everything you'd unwound. For example, here's a function that would insert a value x at index i of a list:
fun insert (x, 0, L) = x :: L
| insert (x, i, h :: t) = h :: insert (x, i - 1, t)
| insert (_, _, nil) = raise Subscript
Fortunately, your function is written so as to not have to insert anything into the middle of an already-built linked list; rather, if I understand correctly what it's trying to do, it always puts the new square at the beginning of the first list. So:
let
val squareToInsert = Concealed(Mine)
val topRow :: rest = retGame
in
createMines (rowCounter, colCounter+1, (squareToInsert::topRow)::rest)
end
Note that you'll also need to fix another bug, which is that you never actually create new rows: you have a comment about "finished current row, move on", but then it just proceeds exactly the same as if it were still in the same row (just resetting the numbers as if it had moved to a new row). To fix this, use [] :: retGame when you want to add a new row at the top, and use [[]] instead of [] for the initial board (so that it starts out with an empty row).
I am trying to create a function, that takes a co-ordinate, and then given a set of co-ordinates, it extracts all the coordinates that are within one unit of the given co-ordinates, and then makes a list out of that. I already know how to make this function, I just need clarification as to how I make it RETURN the new list.
For example if I give the function (2,1) [(1,3),(1,2),(3,0),(4,2),(2,2),(3,1)], it would return a list [(1,2),(3,0),(2,2),(3,1)].
I already know how to implement a function that can find if a list is within one unit, I just need to know how take the functions I found matching my pattern, and returning it into a fresh list
local_elements :: Coordinate -> List_with_coordinates -> List_with_coordinates
local_elements (x_c,y_c) list = case list of
(x_l,y_l) :xs
| abs (x_l - x_c) <= 1 && abs (y_l - y_c) <=1 -> "what would go here?" local_elements xs
| otherwise -> local_elements xs
[] -> []
You make a function
dist :: Int -> Coordinate -> Coordinate -> Bool
dist k (x_c,y_c) (x_1,y_1) = ((abs (x_1 - x_c)) <= k) && ((abs (y_1 - y_c)) <= k)
It checks if a coordinate is fine. Theny ou say:
local_lements c = filter (dist 1 c)
This is sufficient to do exactly what you want. If two coordinates are only 1 apart, dist 1 will return True, and the builtin function filter will take all elements x from list that cause dist 1 c x to return True.