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.
Related
Hello I am learning the OCaml language and working on an assignment.
infinite precision natural numbers can be represented as lists of ints between 0 and 9
Write a function that takes an integer and represents it with a list of integers between 0 and 9 where the head
of the list holds the least significant digit and the very last element of the list represents the most significant digit.
If the input is negative return None. We provide you with some use cases:
For example:
toDec 1234 = Some [4; 3; 2; 1]
toDec 0 = Some []
toDec -1234 = None
I have written below code for it.
let rec toDec i =
(
if i < 10 then i::[]
else toDec ((i mod 10)::acc) (i/10) in toDec [] i;
);;
I am getting syntax error on line 4. Since I am new to this language, not able to get what's wrong. Can somebody please help on this.
The in keyword must go with a let. You could use a local function aux, as follows:
let toDec i =
let rec aux acc i =
if i < 10 then i::[]
else aux ((i mod 10)::acc) (i/10)
in
aux [] i
This doesn't do what you want but syntax and types are valid and I'm sure you can fix the rest.
Vicky, you forgot to define acc and also forgot to put else if statement.
Update your code as below,
let rec toDec ?acc:(acc=[]) i =
if i < 0 then None
else if i = 0 then Some acc
else toDec ~acc:((i mod 10)::acc) (i / 10)
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.
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.
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
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.