Difficulty in understanding let and lambda usage in Scheme - c++

I am having hard time to understand the scope of the following code:
(define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))
if I use:
(let ((c (create-counter ))) (+ (c) (c) (c) (c)))
the code work however if i tried with:
(+ (create-counter)(create-counter)(create-counter)(create-counter))
This does not work and give me a 0. Can someone please help me to understand this thoroughly? if possible, please compare to other language like C/C++ it would be easier for me to catch the hold of this. Thanks

(define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))
Translates to:
auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}
A simple C++14 function returning a closure object.
When you do this:
(let ((c (create-counter ))) (+ (c) (c) (c) (c)))
It is:
auto c = create_counter();
auto r = c()+c()+c()+c();
return r;
It creates one counter, then runs it 4 times, returning 0 1 2 3 and adding to 6.
In this case:
(+ ((create-counter))((create-counter))((create-counter))((create-counter)))
It is:
auto r = create_counter()()+create_counter()()+create_counter()()+create_counter()();
return r;
Which creates 4 counters, and runs each one once. The first time you run a counter you get 0. So this adds to 0.
The closure object has state. It returns a bigger number each time you call it.
Now you may not be familiar with C++11/14 lamnda.
auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}
Is
struct counter {
int x,count;
int operator()(){
int r=count;
count+=x;
return r;
};
};
counter create_counter(int x=1){
return {x,0};
}
with some syntax sugar.
I fixed what seems to be a syntax error in your original code. I am no expert, so maybe I got it wrong.
As an aside, a briefer create counter looks like:
auto create_counter(int x=1){
return [=,count=0]()mutable{
int r=count;
count+=x;
return r;
};
}

When you call "create-counter", it creates a counter and then returns a procedure that refers to that particular counter. When you call "create-counter" four times, you're creating four separate counters; each procedure refers to its own counter. When you call "create-counter" once and then the resulting procedure four times, it's creating just one counter, and incrementing it four times.
It's a bit hard to compare this to C, since C and C++ are quite weak in the area of closures; it's not easy to return a function that's defined inside of another function.
The closest analog might be a "counter" object in C++; think of "create-counter" as the constructor for an object containing a single integer, and the resulting procedure as an "increment" method that increments the counter contained in that object. In your second example, then, you're creating four distinct objects, where in your first example, you're creating one object and calling its "increment" method four times.

Related

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.

Need a fresh perspective on recursion

I just can't wrap my head around this.
Why do these two functions produce radically different results,
when line 4 seems identical?
Version I
int factorial(int val) // input=5; output=120
{
if (val != 0)
return factorial(val - 1) * val;
return 1;
}
Version II
int factorial(int val) // input=5; output=0
{
if (val != 0)
return factorial(--val) * val;
return 1;
}
They only seem identical if you don't read them - one says val - 1 and the other says --val.
val - 1: Subtraction. Evaluates to the value of val, minus one
--val: Decrement. Reduces val by one, and evaluates to the new value
The latter example has undefined behaviour because you try to read val again on the same line.
Version 2 changes the value of val via the --val, where version 1 only subtracts 1 from val but doesn't update the value of val when doing so.
Use of
return factorial(--val) * val;
is cause for undefined behavior. Don't use it.
For evaluating the expression, the compiler is free to evaluate factorial(--val) first, then evaluate val, and then perform the multiplication. It is also free to evaluate val first, then evaluate factorial(--val), and then perform the multiplication.
If the compiler chooses the first strategy, that statement is equivalent to:
--val;
return factorial(val)*val;
As you can see, that is incorrect.
If the compiler chooses the second strategy, that statement is equivalent to:
int res = factorial(val-1)*val;
--val
return res;
Had the compiler followed this strategy, you'd have gotten the correct answer.
OTOH, the statment
return factorial(val-1)*val;
does not suffer from that problem and always returns the correct value.

Language Independant: Check if a string consists of a multiple of a certain substring

I want the general algorithm to find if a string contains a repeating pattern, and no part of the string is left out of the repeating pattern.
For example, look at these sample strings:
abcabcabc - true
abcabcabcx - false
cucumbercucumber - true
cucumber - false
abaaabaaabaa - true
I looked at this answer, which solved the problem for a few cases, but would fail in case of the cucumber example. I need something that would work in all cases.
A Python solution inspired by https://stackoverflow.com/a/2553533/1763356 is
s in (s + s)[1:-1]
This takes O(n) time assuming an efficient implementation of str.__contains__.
This seems like the obvious way to do it:
String s = "abaaabaabaa" ; // string to test
for (int repeating_pattern_length=1;
repeating_pattern_length<=s.length/2;
repeating_pattern_length++)
{ if (modulo(s.length,repeating_pattern_length)==0)
{ // can fit exactly N times
String proposed_subpattern=s.substring(0,repeating_pattern_length);
for (nth_instance=2; // don't need to check 1st occurrence
nth_instance<=s.length/repeating_pattern_length;
nth_instance++)
{ // check nth occurrence
if (!proposed_subpattern.equal(
s.substring((nth_instance-1)*repeating_pattern_length,
repeating_pattern_length)
cycle repeating_pattern_length; // nth occurrence doesn't match
}
return true;
}
}
return false;
[Untested. This is intended to be Java, but I'm not an expert Java coder. Forgive my trespasses].
This arguably has complexity O(s.length) with a small constant factor.
One might consider building a suffix tree (also linear time) and then checking that the tree has the appropriate cycles. I suspect the above algorithm is pretty good in practice.
Since you aren't asking for a specific language, I'd recommend looking into the Rosetta Code page for Repeating String. You can find and study a bunch of algorithms solving the problem.
Though the problem is stated for 1s and 0s in Rosetta Code, most solutions should work with any possible strings.
I've written a general Common Lisp recursive solution, here the commented code:
(ql:quickload :alexandria)
(defun rep-stringv (a-str &optional (max-rotation (floor (/ (length a-str) 2))))
;; Exit condition if no repetition found.
(cond ((< max-rotation 1) "Not a repeating string")
;; Two checks:
;; 1. Truncated string must be equal to rotation by repetion size.
;; 2. Remaining chars (rest-str) are identical to starting chars (beg-str)
((let* ((trunc (* max-rotation (truncate (length a-str) max-rotation)))
(truncated-str (subseq a-str 0 trunc))
(rest-str (subseq a-str trunc))
(beg-str (subseq a-str 0 (rem (length a-str) max-rotation))))
(and (string= beg-str rest-str)
(string= (alexandria:rotate (copy-seq truncated-str) max-rotation)
truncated-str)))
;; If both checks pass, return the repeting string.
(subseq a-str 0 max-rotation))
;; Recurse function reducing length of rotation.
(t (rep-stringv a-str (1- max-rotation)))))
Testing:
CL-USER> (rep-stringv "cucumber")
"Not a repeating string"
CL-USER> (rep-stringv "abaaabaaabaa")
"abaa"
The best possible solution can be achieved with a suffix tree for the string, as you probably already now - since it's a common problem described everywhere, e.g., Wikipedia.
Implementing it seems overkill to me, unless you really need performance. In any case, examples of suffix trees (in many languages) can be found here.
Here's some elementary C++ code that does the job:
bool IsRepeating( std::string in ) {
int totalLength = in.length();
for (int subLength = 1; subLength <= totalLength / 2; subLength++ ) {
if (totalLength % subLength != 0) continue;
for (int startPos = 0; startPos < subLength; startPos++) {
char startChar =in[startPos];
bool mismatchFound = false;
for (int delta = subLength; delta < totalLength-startPos; delta += subLength) {
if (in[startPos+delta] != startChar ) {
mismatchFound = true;
break;
}
}
if (mismatchFound) {
break;
}
return true;
}
}
return false;
}
It makes use of the fact that the substring length has to be a divisor of the total string length.
The worst-case time complexity is pretty bad, something like O(n^2 log(log(n))), but I'm not sure. (Worst case is when the string consists of exactly two identical substrings.) Still I believe that on average it should perform quite well because most of the outer loop body is only executed for divisors of the string length and the inner loops are aborted as soon as a mismatch is found.
Edit: The solution by #Veedrac is not only much more elegant but also more performant in most cases. For a direct comparison, here's the C++ version:
bool IsRepeating( const std::string& in ) {
if (in.length() < 1) return false;
return (in + in).substr(1, 2 * in.length() - 2).find(in) != std::string::npos;
}
It does however use more memory. And if you don't know the purpose of the function, it might be tough to figure it out. But that also holds for my original version.

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);

How do I save and change the value of a variable in OCaml?

This may be a very newbie question, but I didn't find the answer.
I need to store, for example a list and later replace it with another, under the same pointer.
It can be done via references:
let fact n =
let result = ref 1 in (* initialize an int ref *)
for i = 2 to n do
result := i * !result (* reassign an int ref *)
done;
!result
You do not see references very often because you can do the same thing using immutable values inside recursion or high-order functions:
let fact n =
let rec loop i acc =
if i > n then acc
else loop (i+1) (i*acc) in
loop 2 1
Side-effect free solutions are preferred since they are easier to reason about and easier to ensure correctness.