GCD in OCaml ( beginner ) - ocaml

I want to write this simple code :
let rec gcd a b =
if b = 0 then a else gcd b (a mod b);;
val gcd : int -> int -> int = <fun>
Printf.printf "%d da \n" gcd 55 200 ;;
This is the code , the error I get is :
File "tst.ml", line 3, characters 0-3:
Error: Syntax error
And also , can anyone explain to me what is that " int -> int -> int = " all about ? I know that it must be something about the parameters and the returned value of the function but what and how ? :)

You're passing gcd 55 and 200 as separate parameters of printf. So, try this:
Printf.printf "%d da\n" (gcd 55 200);;

It looks like you did some copy & paste from an ocaml interactive session, since normally we don't mix up function definitions (the 2 first lines), and function declarations (the third line, though in this case it looks more like the answer of the ocaml interpreter when provided with the definition - because of the <fun> part which isn't syntactically correct in a program, but is used by the interpreter to indicate that it figured out that the value is a function) in the same scope.
So, you should not include that third line, and you will have to fix the last instruction, as #JeffreyScofield explained.
(* gcd function definition *)
let rec gcd a b =
if b = 0 then a else gcd b (a mod b);;
(* val gcd: int -> int -> int *)
Printf.printf "%d da \n" (gcd 55 200);;
Alternatively, the last line could be written:
Printf.printf "%d da \n" ## gcd 55 200;;
The function signature you included by mistake indicates that gcd takes a sequence of 2 integer parameters, and returns an integer. The notation is said to be in curried form: each parameter passed to a function A yields another function B expecting the remaining parameters of A. Thus you can read that signature several ways:
As a function taking 2 integers and returning one,
val gcd: int -> int -> int
As a function taking an integer, and returning an a function, which takes an integer and returns an integer.
val gcd: int -> (int -> int)
Both notations are equivalent (The arrow "operator" is said to be associative on the right), but the second one helps to understand this idea of function return "chaining".

In int -> int -> int:
The last int is the return value
The first two ints are the parameters
Consider reading this to understand function types.

Related

Haskell runs incredibly slow compared to C++

I have an assignment, that I need to solve in Haskell.
It was firstly solved in C++, then I rewrote the code to Haskell.
The algorithm is working correctly but the Haskell version runs slower, compared to the C++ version.
For example, for the input:
110110100011010101010101
010101101001000101010100
Haskell (with GHCI): 20 sec
Haskell (compiled GHC): 3 sec
C++: <1 sec
With a difference this much, I think, I am doing something wrong.
Problem description: We are given 2 arrays(strings) of the same length, containing 0s and 1s. Our task is to find the minimal switches(switch=0->1 or 1->0) to make the source array identical to the target. There is a rule for switching: We can only change the state of i if i+1 is 1 AND i+2->n are 0, except for the last one.
C++ code:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
//flips the i-th char int s to match the i-th char in t
int flip2(int i, string& s, char t){
if(i>=s.length() || s[i]==t) return 0; //if matches, or non-existent index, returns 0 steps
int c=1; // 1 step is switching the character
c+=flip2(i+1,s,'1'); //in order to switch i, i+1 have to be 1
for(int j=i+2;j<s.length();j++) //in order to switch i, i+2->n have to be 0
c+=flip2(j,s,'0');
s[i]=t;
return c;
}
//returns the minimum number of switch steps to make s=t
int ultimateFlip( string s, string t){
int c=0;
for(int i=0;i<s.length();i++){ // switches every character in s to match t
c+=flip2(i,s,t[i]); //adds up the steps
}
return c;
}
int main()
{
string s; // source array (made up of 0s and 1s)
getline(cin, s);
string t; //target array (made up of 0s and 1s)
getline(cin, t);
cout<<ultimateFlip(s,t);
}
Haskell code:
import System.IO
import Control.Monad
main :: IO ()
main = do
hSetBuffering stdout NoBuffering
s <- getLine -- source string
t <- getLine -- target string
let sol = ultimateFlip s t
putStrLn $ show sol
return ()
--returns the minimum number of switch steps to make s=t
ultimateFlip :: [Char] -> [Char] -> Int
ultimateFlip [] [] = 0
ultimateFlip (s:sx) (t:tx) = k + ultimateFlip sxn tx
where
(k,sxn)=flip2 s t sx --snx = new (after) version of sx(the rest of the string)
--flips the s to match t, sx= rest of the source string after s
flip2 :: Char->Char->[Char]->(Int,[Char])
flip2 s t sx
| s == t = (0,sx) --if mathes, no switch needed
| null sx = (1,sx) --if last one, one switch need
| otherwise = (k2+k1+1,'1':nsx2)
where
(sxh:sxt) = sx
(k1,nsx1) = flip2 sxh '1' sxt --switch next to 1
(k2,nsx2) = zeroOut nsx1 --switch everything after the next to 0
--switch everything to 0
zeroOut :: [Char] -> (Int, [Char])
zeroOut [] = (0,[])
zeroOut (s:sx) = (k1+k2,'0':nsx2)
where
(k1,nsx1) = flip2 s '0' sx
(k2,nsx2) = zeroOut nsx1
For Haskell I am using: GHC, version 8.10.2
For C++ I am using: gcc (GCC) 10.2.0
You are spending an awful lot of time allocating and immediately destructuring pairs. That's pretty unnecessary, because you always know what [Char] you're going to get back in the second half of the tuple. Here's one way to eliminate that problem:
ultimateFlip :: [Char] -> [Char] -> Int
ultimateFlip [] [] = 0
ultimateFlip (s:sx) (t:tx)
| s == t = ultimateFlip sx tx
| null sx = 1
| otherwise = ultimateFlip sx tx' + 1 + ultimateFlip tx' tx where
tx' = '1' : ('0'<$drop 1 tx)
With this change, the Haskell performs pretty much the same as the C++ on my machine -- sometimes a few ms faster, sometimes a few ms slower, for inputs slightly longer than the one you proposed.
Of course, as usual, switching to a better algorithm blows microoptimizations like this one out of the water in terms of gains. The following implementation takes less time than the reporting precision of time even for much longer strings.
import Data.Bits
main :: IO ()
main = do
s <- getLine
t <- getLine
print (ultimateFlip s t)
ultimateFlip :: [Char] -> [Char] -> Int
ultimateFlip [] [] = 0
ultimateFlip (s:sx) (t:tx)
| s == t = ultimateFlip sx tx
| otherwise = go '1' pow sx + 1 + go '1' pow tx where
pow = 2^(length sx-1)
go _ _ [] = 0
go s pow (t:tx) = go s' pow' tx + n where
pow' = shiftR pow 1
(s', n) = if s == t then ('0', 0) else ('1', pow)
It also smoothly upgrades to using arbitrary-sized integers for those longer inputs just by switching Int to Integer in the type signature of ultimateFlip.
The biggest problem you're having is with a lack of "strictness". Haskell's lazy evaluation means that even simple calculations like k2+k1+1 generally won't be evaluated until the answer is needed. With recursive functions performing a series of additions like thus, you can sometimes end up building an enormous unevaluated expression that takes up tons of memory before it finally gets evaluated at the end.
Here, by adding a language extension at the top:
{-# LANGUAGE BangPatterns #-}
and adding a single strictness "!" annotation in your flip's "where" clause:
(!k1,nsx1) = flip2 sxh '1' sxt
^
this drops the runtime on my machine from 800ms to 80ms (again, compiled with ghc -O2). That's still slower than the C++ version (20ms), but it's in the right ballpark.
The annotation here has the effect of forcing the expression to be evaluated. Figuring out where strictness annotations are needed is a bit of a dark art. In this case, I suspected your counting was causing the problem, so I threw in "!" before all the places that a count was being returned, and then I deleted them until I found the one that made most of the difference.
The remaining speed difference is probably a result of using a lot of list processing in Haskell (versus arrays in C++), so you could likely do better, though I'm not sure it's worth the trouble.

Psum not accumulating (Polymorphic Higher order function) without forcing a type

New to OCaml and Functional Programming as a whole so I was having some problems with keeping the type ambiguous. I'm trying to make a function which takes in a symbol accum(which looks like (+) or (-.) or (*) etc.) and a function f. My current implementation is below and if let's say I passed in (** f (x) = 3x^2 + 5x + 6 **) but I always get '6' instead of '276' because in the else part I'm not summing adding the results of the previous rounds so I just get the final value of '6'.
I get type errors because of the + so when I throw floats in it breaks. How can I overcome this (let partial accept floats or ints but actually accumulate the answer)?
let rec powerSum(sign )(f):'a =
fun x ->
if x = 0 then
f (x)
else if x < 0 then
raise(Failure "Error arg isn't '+'")
else
powerSum sign f (x-1);
Hint: you should use accum at some point.

Writing power function in Standard ML with a predefined compound function

Having trouble writing a power function inStandard Ml. Im trying to write a function called exp of type int -> int -> int.
The application exp b e, for non-negative e, should return b^e.
For example, exp 3 2 should return 9. exp must be implemented with the function compound provided below. exp should not directly calls itself. Here is the compound function, it takes in a value n, a function, and a value x. All it does is it applies the function to the value x n number of times.
fun compound 0 f x = x
| compound n f x = compound (n-1) f (f x);
Im having trouble figuring out how to write this function without recursion, and with the restraint of having to use a function that only can use a function with one parameter. Anyone have any ideas of where to start with this?
This is what I have:
fun exp b 0 = 1
| exp b e = (compound e (fn x => x*x) b)
I know that this doesn't work, since if i put in 2^5 it will do:
2*2, 4*4, 16*16 etc.
You are extremely close. Your definition of exp compounds fn x => x*x which (as you noticed) is not what you want, because it is repeatedly squaring the input. Instead, you want to do repeated multiplication by the base. That is, fn x => b*x.
Next, you can actually remove the special case of e = 0 by relying upon the fact that compound "does the right thing" when asked to apply a function 0 times.
fun exp b e = compound e (fn x => b*x) 1
You could just do this instead I believe
fun exp 0 0 = 1
| exp b 0 = 1
| exp b e = (compound (e - 1) (fn x => b * x ) b);
this may not be exactly 100% proper code. I sort of just now read a bit of Standard ML documentation and took some code and reworked it for your example but the general idea is the same for most programming languages.
fun foo (num, power) =
let
val counter = ref power
val total = 1
in
while !counter > 0 do (
total := !total * num
counter := !counter - 1
)
end;
To be more clear with some pseudo-code:
input x, pow
total = 1
loop from 1 to pow
total = total * x
end loop
return total
This doesn't handle negative exponents but it should get you started.
It basically is a simple algorithm of what exponents truly are: repeated multiplication.
2^4 = 1*2*2*2*2 //The 1 is implicit
2^0 = 1

transform 0 in ’a’, 1 in ’b’, 2 in ’c’ etc

As I am new in OCaml and I didn't find resources, I need your help in the resolution of this function ! I want to generate a list of numbers with transforming int to char.
module Util =
sig
(* transform 0 in ’a’, 1 in ’b’, 2 in ’c’ etc... *)
val int_to_char : int -> char
(*gen_random_list long max *)
(* generate a list of positive numbers <= max *)
(* the length of the list is long *)
val gen_random_list : int -> int -> int list
end
There are good resources for OCaml at http://ocaml.org
Here's a function that converts 1 to 'a' and 2 to 'b'. But I'd say you need a more careful specification, there are many questions unanswered by your three examples.
let ntoc x = Char.chr (x + Char.code 'a' - 1)
Read about the Char and Random modules in the OCaml manual.

How does that recursive function work?

Might be a very basic question but I just got stuck with it. I am trying to run the following recursive function:
//If a is 0 then return b, if b is 0 then return a,
//otherwise return myRec(a/2, 2*b) + myRec(2*a, b/2)
but it just gets stuck in infinite loop. Can anybody help me to run that code and explain how exactly that function works? I built various recursive functions with no problems but this one just drilled a hole in my head.
Thanks.
Here is what I tried to do:
#include<iostream>
int myRec(int a, int b){
if (a==0){
return b;
}
if (b==0){
return a;
}
else return myRec(a/2, 2*b) + myRec(2*a, b/2);
}
int main()
{
if (46 == myRec(100, 100)) {
std::cout << "It works!";
}
}
Well, let us mentally trace it a bit:
Starting with a, b (a >= 2 and b >= 2)
myRec(a/2, 2*b) + something
something + myRec(2*a', b'/2)
Substituting for a/2 for a' and 2*b for b', we get myRec(2*(a/2), (b*2)/2), which is exactly where we started.
Therefore we will never get anywhere.
(Note that I have left out some rounding here, but you should easily see that with this kind of rounding you will only round down a to the nearest even number, at which point it will be forever alternating between that number and half that number)
I think you are missing on some case logic. I last program in C ages ago so correct my syntax if wrong. Assuming numbers less than 1 will be converted to zero automatically...
#include<iostream>
int myRec(int a, int b){
// Recurse only if both a and b are not zero
if (a!=0 && b!=0) {
return myRec(a/2, 2*b) + myRec(2*a, b/2);
}
// Otherwise check for any zero for a or b.
else {
if (a==0){
return b;
}
if (b==0){
return a;
}
}
}
UPDATE:
I have almost forgot how C works on return...
int myRec(int a, int b){
if (a==0){
return b;
}
if (b==0){
return a;
}
return myRec(a/2, 2*b) + myRec(2*a, b/2);
}
VBA equivalent with some changes for displaying variable states
Private Function myRec(a As Integer, b As Integer, s As String) As Integer
Debug.Print s & vbTab & a & vbTab & b
If a = 0 Then
myRec = b
End If
If b = 0 Then
myRec = a
End If
If a <> 0 And b <> 0 Then
myRec = myRec(a / 2, 2 * b, s & "L") + myRec(2 * a, b / 2, s & "R")
End If
End Function
Sub test()
Debug.Print myRec(100, 100, "T")
End Sub
Running the test in Excel gives this (a fraction of it as it overstacks Excel):
T: Top | L: Left branch in myRec | R: Right branch in myRec
The root cause will be the sum of the return which triggers more recursive calls.
Repeating of the original values of a and b on each branch from level 2 of the recursive tree...
So MyRec(2,2) = MyRec(1,4) + MyRec(4,1)
And MyRec(1,4) = MyRec(.5,8) + MyRec(2,2)
So MyRec(2,2) = MyRec(.5,8) + MyRec(2,2) + MyRec(4,1)
Oops.
(The .5's will actually be zeroes. But it doesn't matter. The point is that the function won't terminate for a large range of possible inputs.)
Expanding on gha.st's answer, consider the function's return value as a sum of expressions without having to worry about any code.
Firstly, we start with myRec(a,b). Let's just express that as (a,b) to make this easier to read.
As I go down each line, each expression is equivalent, disregarding the cases where a=0 or b=0.
(a,b) =
(a/2, 2b) + (2a, b/2) =
(a/4, 4b) + (a, b) + (a, b) + (4a, b/4)
Now, we see that at a non-terminating point in the expression, calculating (a,b) requires first calculating (a,b).
Recursion on a problem like this works because the arguments typically tend toward a 'base case' at which the recursion stops. A great example is sorting a list; you can recursively sort halves of the list until a list given as input has <= 2 elements, which is trivial without recursion. This is called mergesort.
However, your myRec function does not have a base case, since for non-zero a or b, the same arguments must be passed into the function at some point. That's like trying to sort a list, in which half of the list has as many elements as the entire list.
Try replacing the recursion call with:
return myRec(a/2, b/3) + myRec(a/3, b/2);