Tail Recursion and Iteration SML - iteration

This is my assignment.
(http://prnt.sc/aa3gwd)
I've been working on this one with a tutor and this is what we have come up with so far.
fun mult(a,b) =
let
val product = 0
in
if (a = 0) then
0
else
while a > 0 do
(
product := product + b;
if (a = 1) then
product
else
a:= a -1
);
end;
; //the function did not run at end;, so we added these two semicolons below
;
Output of this is:
stdIn:102.11-103.6 Error: syntax error: deleting SEMICOLON END SEMICOLON
I've only been introduced to SML in the last 2 weeks and I just can't get my head around it. Any help is very much appreciated.

You need two (mutable) reference variables; one for the product and one for the counter.
Something like this:
fun mult(a, b) =
let val product = ref 0
val counter = ref a
in
while !counter > 0 do (
product := !product + b;
counter := !counter - 1
);
!product
end;
(This isn't exactly a translation of the recursive code you linked to, because that code was unnecessarily complicated. You may need to adjust, depending on your professor.)
(I would write the recursive version more like this:
fun mult (0, _) = 0
| mult (_, 0) = 0
| mult (a, b) = b + mult(a - 1, b);
It's unclear why the exercise has a special case for a = 1.)

Related

Kotlin android if statement

Kotlin, Android studio, v. 4.0.1
I have a progress bar in my app that ranges from 0 to 10.
When it is at 0, the following code gives an error (which is logic):
val rand = Random().nextInt(seekBar.progress) + 1
resultsTextView.text = rand.toString()
So I want to add an if statement before to filter out the 0. If the progress bar is at 0, the 'rand' should be at 0 too.
I have the following but it does not work:
rollButton.setOnClickListener {
val ggg = seekBar.progress
if (ggg = 0) {
val rand = 0
} else {
val rand = Random().nextInt(seekBar.progress) + 1
}
resultsTextView.text = rand.toString()
}
Any idea?
rand is defined in the scope of if and else, you cannot use it outside that scope and instead of comparing ggg with 0 (==) you are setting its value to 0 (=). And if you want to reassign rand, it cannot be a val which can only be assigned once, make it a var instead.
Do it like this:
rollButton.setOnClickListener {
val ggg = seekBar.progress
var rand = 0;
if (ggg != 0) {
rand = Random().nextInt(seekBar.progress) + 1
}
resultsTextView.text = rand.toString()
}
Replace if (ggg = 0) { with if (ggg == 0) {.
A more Kotlin approach might be along the lines of:
rollButton.setOnClickListener {
val rand = seekBar.progress.let {
if (it == 0)
0
else
Random().nextInt(it) + 1
}
resultsTextView.text = rand.toString()
}
This uses an if() expression (not a statement) to avoid any mutable variables.  And by getting the value of seekBar.progress only once, it also avoids any issues if the bar gets moved while that's running.
However, I have to check if that's actually what you want:
Bar position | Possible values
0 | 0
1 | 1
2 | 1–2
3 | 1–3
… | …
That looks wrong to me…  Do you really want to exclude zero in all but the first case?  If not, then you could just move the addition inside the call — Random().nextInt(seekBar.progress + 1) — and avoid the special case entirely.

Why does `variable++` increment the variable but `variable + 1` does not?

Here's the problem in which I encountered this issue:
The function should compare the value at each index position and score a point if the value for that position is higher. No point if they are the same. Given a = [1, 1, 1] b = [1, 0, 0] output should be [2, 0]
fun compareArrays(a: Array<Int>, b: Array<Int>): Array<Int> {
var aRetVal:Int = 0
var bRetVal:Int = 0
for(i in 0..2){
when {
a[i] > b[i] -> aRetVal + 1 // This does not add 1 to the variable
b[i] > a[i] -> bRetVal++ // This does...
}
}
return arrayOf(aRetVal, bRetVal)
}
The IDE even says that aRetVal is unmodified and should be declared as a val
What others said is true, but in Kotlin there's more. ++ is just syntactic sugar and under the hood it will call inc() on that variable. The same applies to --, which causes dec() to be invoked (see documentation). In other words a++ is equivalent to a.inc() (for Int or other primitive types that gets optimised by the compiler and increment happens without any method call) followed by a reassignment of a to the incremented value.
As a bonus, consider the following code:
fun main() {
var i = 0
val x = when {
i < 5 -> i++
else -> -1
}
println(x) // prints 0
println(i) // prints 1
val y = when {
i < 5 -> ++i
else -> -1
}
println(y) // prints 2
println(i) // prints 2
}
The explanation for that comes from the documentation I linked above:
The compiler performs the following steps for resolution of an operator in the postfix form, e.g. a++:
Store the initial value of a to a temporary storage a0;
Assign the result of a.inc() to a;
Return a0 as a result of the expression.
...
For the prefix forms ++a and --a resolution works the same way, and the effect is:
Assign the result of a.inc() to a;
Return the new value of a as a result of the expression.
Because
variable++ is shortcut for variable = variable + 1 (i.e. with assignment)
and
variable + 1 is "shortcut" for variable + 1 (i.e. without assignment, and actually not a shortcut at all).
That is because what notation a++ does is actually a=a+1, not just a+1. As you can see, a+1 will return a value that is bigger by one than a, but not overwrite a itself.
Hope this helps. Cheers!
The equivalent to a++ is a = a + 1, you have to do a reassignment which the inc operator does as well.
This is not related to Kotlin but a thing you'll find in pretty much any other language

Generalizing functions in F#

I need a function that produces primes in F#. I found this:
let primesSeq =
let rec nextPrime n p primes =
if primes |> Map.containsKey n then
nextPrime (n + p) p primes
else
primes.Add(n, p)
let rec prime n primes =
seq {
if primes |> Map.containsKey n then
let p = primes.Item n
yield! prime (n + 1) (nextPrime (n + p) p (primes.Remove n))
else
yield n
yield! prime (n + 1) (primes.Add(n * n, n))
}
prime 2 Map.empty
This works very well, but sometimes I need to work with int64/BigInts as well. Is there a more clever way of reusing this code than providing another sequences like these:
let primesSeq64 = Seq.map int64 primesSeq
let primesBigInts = Seq.map (fun (x : int) -> BigInteger(x)) primesSeq
I've heard about modifying a code using "inline" and "LanguagePrimitives", but all I've found was connected with function while my problem is related to a value.
Moreover - I'd like to have a function that works with integer types and computes a floor of a square root.
let inline sqRoot arg = double >> Math.Sqrt >> ... ?
but I can't see a way of returning the same type as "arg" is, as Math.Sqrt returns a double. Again - is there anything better than reimplementing the logic that computes a square root by myself ?
So the general way to do this requires a function and languageprimitives - in your case everywhere you have 1 you write LanguagePrimitives.GenericOne which will produce 1 or 1.0 etc depending on what is required.
To get this to work, you need to create a function value - you can avoid this by doing something like:
let inline primesSeq() = ...
let primesintSeq = primesSeq() //if you use this as an int seq later the compiler will figure it out, otherwise you use
let specified : int seq = primesSeq()
I am not so sure about the sqrt case though - it probably depends on how hacky you are willing to make the solution.
A naïve implementation of generic sqRoot may go along these lines:
let sqRoot arg =
let inline sqrtd a = (double >> sqrt) a
let result = match box(arg) with
| :? int64 as i -> (sqrtd i) |> int64 |> box
| :? int as i -> (sqrtd i) |> int |> box
// cases for other relevant integral types
| _ -> failwith "Unsupported type"
unbox result
and then, checking in FSI:
> let result: int = sqRoot 4;;
val result : int = 2
> let result: int64 = sqRoot 9L;;
val result : int64 = 3L

Define a static variable for a recursive function in OCaml

I have a recursive function fact, which can be called from either an expression inside it or an expression outside it.
I would like to associate fact with a variable v, such that each time fact is called from outside (another function), v is initialized, and its value can be changed inside fact, but never can be initialized when fact is called from inside.
The following code suits my need, but one problem is that v is defined as a global variable, and I have to do v := init before calling fact from outside, which I do not find beautiful.
let init = 100
let v = ref init
let rec fact (n: int) : int =
v := !v + 1;
if n <= 0 then 1 else n * fact (n - 1)
let rec fib (n: int) : int =
if n <= 0 then 0
else if n = 1 then (v := !v + 50; 1)
else fib (n-1) + fib (n-2)
let main =
v := init;
print_int (fact 3);
print_int !v; (* 104 is expected *)
v := init;
print_int (fib 3);
print_int !v;; (* 200 is expected *)
Could anyone think of a better implementation?
You can hide the function and value definitions within the body of a containing function as follows:
open Printf
let init = 100
let fact n =
let rec fact counter n =
incr counter;
if n <= 0 then 1 else n * fact counter (n - 1)
in
let counter = ref init in
let result = fact counter n in
(result, !counter)
let main () =
let x, count = fact 3 in
printf "%i\n" x;
printf "counter: %i\n" count (* 104 is expected *)
let () = main ()
You can adapt Martin's solution so that data is shared across various calls:
let fact =
let counter = ref 0 in
fun n ->
let rec fact = ... in
fact n
The idea is to transform let fact = fun n -> let counter = ... in ... into let fact = let counter = ... in fun n -> ...: counter is initialized once, instead of at each call of fact.
A classical example of this style is:
let counter =
let count = ref (-1) in
fun () ->
incr count;
!count
Beware however that you may get into typing trouble if the function was meant to be polymorphic: let foo = fun n -> ... is always generalized into a polymorphic function, let foo = (let x = ref ... in fun n -> ...) is not, as that would be unsound, so foo won't have a polymorphic type.
You can even generalize the counter example above to a counter factory:
let make_counter () =
let count = ref (-1) in
fun () ->
incr count;
!count
For each call to make_counter (), you get a new counter, that is a function that shares state across call, but whose state is independent from previous make_counter () counter creations.
With Ocaml's objects, you can do:
class type fact_counter = object ('self)
method get : int
method set : int -> unit
method inc : unit
method fact : int -> int
end;;
class myCounter init : fact_counter = object (self)
val mutable count = init
method get = count
method set n = count <- n
method inc = count <- count + 1
method fact n =
self#inc;
if n <= 0 then 1 else n * self#fact (n - 1)
end;;
Then you can obtain:
# let c = new myCounter 0;;
val c : myCounter = <obj>
# c#fact 10;;
- : int = 3628800
# c#get;;
- : int = 11
# c#set 42;;
- : unit = ()
# c#fact 10;;
- : int = 3628800
# c#get;;
- : int = 53
I hope you can easily see how to adapt myCounter to include fib ...

SML/NJ while loop

I am really new to SML and I can't figure out how to get answer for the same;
It goes something like: 3^4 < 32 but 3^5 > 32 so my answer is 4 (power of 3), similarly if I have numbers 4 and 63 then 4^2<63 but 4^3>63 so my answer is 2(power of 4).
I have come up with the following code
val log (b, n) =
let
val counter = ref b
val value = 0
in
while !counter > n do
( counter := !counter*b
value := !value + 1)
end;
So here value is what I need as my answer but I get a lot of errors. I know I am wrong at many places. Any help would be appreciated.
I can perhaps do this the normal ML way but I want to learnt impure ML also...
fun loghelper(x,n,b) = if x>n then 0 else (1+loghelper((x*b),n,b));
fun log(b,n) = loghelper(b,n,b);
ok so finally here is the correct code for the while loop and it works as well;
fun log (b, n) =
let
val counter = ref b
val value = ref 0
in
while (!counter <= n) do
(counter := !counter*b;
value := !value + 1);
!value
end;
You have several problems in your code:
Errors:
Instead of val log (b, n) = it should be fun log (b, n) =. fun is a convenience syntax that lets you define functions easily. If you wanted to write this with val you would write: val log = fn (b, n) => (it gets more complicated in the cases of recursive functions or functions with multiple curried arguments)
You need a semicolon to separate two imperative statements: ( counter := !counter*b;
value := !value + 1)
value needs to be a ref: val value = ref 0
Logic:
Your function doesn't return anything. A while loop has the unit type, so your function returns () (unit). You probably want to return !value. To do this, you need to add a semicolon after the whole while loop thing, and then write !value
Your while loop condition doesn't really make sense. It seems reversed. You probably want while !counter <= n do
Your base case is not right. Either value should start at 1 (since counter starts at b, and b is b to the first power); or counter should start at 1 (since b to the zeroth power is 1). The same issue exists with your functional version.