If statements end function early if false in OCaml - ocaml

Assuming pos_of_xy (x, y) n is already defined to return an int, this code segment exits once one of the if statements returns false as if they were nested. I need them all to run regardless of the previous if statements. I'm not sure what I am forgetting.
let final = ref [] in begin
if x < (size-1) then let pos = pos_of_xy (x+1, y) size in final := pos::!final;
if y < (size-1) then let pos = pos_of_xy (x, y+1) size in final := pos::!final;
if y > 0 then let pos = pos_of_xy (x, y-1) size in final := pos::!final;
if x > 0 then let pos = pos_of_xy (x-1, y) size in final := pos::!final;
end;

One way of describing the problem is that let is stronger than if. A let takes a sequence of statements after in, and your subsequent ifs are treated as part of this sequence. Things should work if you parenthesize each let:
if x < size - 1 then
(let pos = pos_of_xy (x + 1, y) size in final := pos :: !final);
Or you could do without the let:
if x < size -1 then final := pos_of_xy (x + 1, y) size :: !final;
As a side comment, the code might look even nicer to an FP progammer if you wrote in a more functional style (without the mutable value).
Update
Here's a quick sketch of a more functional way to calculate your list:
let good (x, y) = x >= 0 && x < size && y >= 0 && y < size in
let topos (x, y) = pos_of_xy (x, y) size in
let goodxy =
List.filter good [(x + 1, y); (x, y + 1); (x - 1, y); (x, y - 1)] in
List.map topos goodxy

As Jeffrey Scofield said, let has lower precedence than if. So it's as if you wrote:
let final = ref [] in begin
if x < (size-1) then (let pos = pos_of_xy (x+1, y) size in (final := pos::!final;
(if y < (size-1) then (let pos = pos_of_xy (x, y+1) size in (final := pos::!final;
(if y > 0 then (let pos = pos_of_xy (x, y-1) size in (final := pos::!final;
(if x > 0 then (let pos = pos_of_xy (x-1, y) size in (final := pos::!final;)))))))))))
end;
You can look at the table of precedences here (scroll up a little). As you can see, if has higher precedence than ;, which has higher precedence than let.

Related

how to compute weakest condition?

if(x < y)
x = x + 1
else
x = 3 * x
{x < 0}
my answer :
x+1<0 --> x<-1
x*3<0 --> x<0
so weakest condition is (x<-1) ∩ (x<0) = x<-1
However, the answer sheet says that x<0 is the answer. How can I get the weakest condition?

Graphtheory. How to approach these kinds of problems? I want to know the logic and the way one needs to think while trying to solve this.

Find the number of paths on the Cartesian plane from (0, 0) to (n, n), which never raises above the y = x line. It is possible to make three types of moves along the path:
move up, i.e. from (i, j) to (i, j + 1);
move to the right, i.e. from (i, j) to (i + 1, j);
the right-up move, i.e. from (i, j) to (i + 1, j + 1)
Path count 101
First, we solve a simpler problem:
Find the number of paths on the Cartesian plane from (0, 0) to (n, n) with:
move up, i.e. from (i, j) to (i, j + 1);
move to the right, i.e. from (i, j) to (i + 1, j);
and we can go to grid which x < y.
How to solve it? Too Hard? Okay, we try to find the number of paths from (0, 0) to (2, 2) first. We could draw all paths in a grid:
We define
f(x,y) => the number of paths from (0, 0) to (x, y)
You can see the path to (2, 2) from either (1, 2) or (1, 2), so we can get:
f(2, 2) = f(2, 1) + f(1, 2)
And then you will notice for point(x, y), its path from either (x, y - 1) or (x - 1, y). That's very natural, since we have only two possible moves:
move up, i.e. from (i, j) to (i, j + 1);
move to the right, i.e. from (i, j) to (i + 1, j);
I draw a larger illustration for you, and you can check our conclusion:
So we can get that:
f(x, y) = f(x, y - 1) + f(x - 1, y)
Wait... What if x = 0 or y = 0? That's quite direct:
if x = 0 => f(x, y) = f(x, y - 1)
if y = 0 => f(x, y) = f(x - 1, y)
The last... How about f(0, 0)? We define:
f(0, 0) = 1
since there just 1 path from (0,0) to (1,0) and (0, 1).
OK, summarise:
f(x, y) = f(x, y - 1) + f(x - 1, y)
if x = 0 => f(x, y) = f(x, y - 1)
if y = 0 => f(x, y) = f(x - 1, y)
f(0, 0) = 1
And by recursion, we can solve that problem.
Your problem
Now let's discuss your original problem, just modify our equations a little bit:
f(x, y) = f(x, y - 1) + f(x - 1, y) + f(x - 1, y - 1)
if x = 0 => f(x, y) = f(x, y - 1)
if y = 0 => f(x, y) = f(x - 1, y)
if x < y => f(x, y) = 0
f(0, 0) = 1
and it will result my code.
The last thing I add to my code is Memoization. In short, Memoization can eliminate the repeat calculation -- if we have calculated f(x,y) already, just store it in a dictionary and never calculate it again. You can read the wiki page for a further learning.
So, that's all of my code. If you still get some questions, you can leave a comment here, and I will reply it as soon as possible.
Code:
d = {} # Memoization
def find(x, y):
if x == 0 and y == 0:
return 1
if x < y:
return 0
if d.get((x, y)) is not None:
return d.get((x, y))
ret = 0
if x > 0:
ret += find(x - 1, y)
if y > 0:
ret += find(x, y - 1)
if x > 0 and y > 0:
ret += find(x - 1, y - 1)
d[(x, y)] = ret
return ret
print find(2, 1) # 4
For additional ideas for solving problems such as this one, there is a mathematical curiosity that is in 1-1 correspondence with not only the sequences produced by lattice walks where one's steps must remain below the line x = y, but a veritable plethora, of fantastical mathematical beasts that cut a wide swath of applicability to problem solving and research.
What are these curiosities?
Catalan Numbers:
C_n = 1/(n+1)*(2n)Choose(n), n >= 0, where if n = 0, C_0 = 1.
They also count:
The number of expressions containing $n$ pairs of parentheses
eg. n = 3: ((())), (()()), (())(), ()(()), ()()()
Number of plane trees with n + 1 vertices
Number of Triangulations of a convex (n + 2)-gon
Monomials from the product: p(x1, ..., xn) = x1(x1 + x2)(x1 + x2 + x3) ... (x1 + ... + xn)
bipartite vertices of rooted planar trees
And soooo many more things
These object appear in a lot of active research in mathematical physics, for instance, which is an active area of algorithms research due to the enormous data sets.
So you never know what seemingly far flung concepts are intimately linked in some deep dark mathematical recess.

Scala: Applying a linear operation on all elements of an ArrayBuffer, and also checking bounds

My question is a two-parter.
Part 1
I have an ArrayBuffer of tuples (x,y). I have a tuple, (deltaX,deltaY), which can look like (-1,0) (as an example) to designate the change to apply to all tuples of the ArrayBuffer.
In Python it would be something like:
newBuffer = [(x+deltaX,y+deltaY) for x,y in oldBuffer]
Part 2
Is there a way to check a conditional on all the items in the ArrayBuffer? In my case I wish to ensure all coordinates are within bounds, so something like (to again use the Python equivalent):
if all(0<=x<xBound and 0<=y<yBound for x,y in buffer)
I can do all these things with lots of very long and annoying code but I am wondering if there is a smarter way.
The first one is a simple map:
val (dx, dy) = (-1, 0)
val (xBound, yBound) = (4, 3)
val tuples = Array(1 -> 2, 2 -> 4, 3 -> 0)
tuples.map { case (x, y) => (x + dx, y + dy) }
And the second one is a use of exists or forall:
tuples.exists { case (x, y) => x >= xBound || y >= yBound }
tuples.forall { case (x, y) => x < xBound && y < yBound }
You might also want to use filter and then check isEmpty, or nonEmpty:
tuples.filter { case (x, y) => x < xBound && y < yBound }.isEmpty
tuples.filter { case (x, y) => x >= xBound || y > yBound }.nonEmpty
Scala has many syntactic alternatives that you may come across. Here are some examples:
tuples.map(tuple => (tuple._1 + dx) -> (tuple._2 + dy))
tuples forAll { tuple =>
val (x, y) = tuple
x < xBound && y < yBound
}
tuples.filter(_._1 < xBound).filter(_._2 < yBound).isEmpty
for { (x, y) <- tuples } yield (x + dx, y + dy)
(for {
(x, y) <- tuples
if x < xBound
if y < yBound
} yield (x, y)).isEmpty

ocaml weired recursion

I am trying to calculate the square root of a number by Ocaml, this is my code :
let isclose x y = abs_float(x -. y)<0.001;;
let average x y = (0.5*.x)+.(0.5*.y);;
let rec guess x y = if isclose y (x /. y) then y else guess x (average y x/.y);;
let sqr x = guess x 1.;;
then, typing
sqr 1.;;
gives 1 as expected, but typing
sqr 2.;;
lasts undefinitely.
Can one help with my error (I tested the algo in Python and it works as expected).
Thanks for help
You want this:
let rec guess x y =
if isclose y (x /. y) then y else guess x (average y (x/.y))
Note the extra parentheses.
The meaning of
average y x /. y
is
(average y x) /. y
Whereas you want:
average y (x /. y)

1D vector - 3D indices

I am using a 1D vector to represent a 3D data structure, with indices 0 to x*y*z, where x, y and z are the number of cells in each direction.
In order to index a specific cell [xi][yi][zi], I use:
index = xi + x*yi + x*y*zi ;
My problem is, I can't work out how to go the other way!
e.g. I want to get the individual coordinates represented in index 43.
I think I've worked out how to get xi:
xi = index % x ;
but I can't for the life of me get the others... :/
EDIT: Hmmm. Is this right?
xi = index % x;
yi = ((index - xi)/x) % y;
zi = ((index - xi - x*yi) / x) / y ;
Try this:
xi = index % x;
yi = (index / x) % y;
zi = ((index / x) / y) % z;
This can be easily generalized as one might expect.
Some modular arithmetic should do the trick.
index % x = (xi + x*yi + x*y*zi) % x = xi % x,
but 0 <= xi < x therefore xi % x = xi.
Then for yi:
(index / x) % y = yi.
Then lastly:
index / (x * y) = zi.
EDIT:
In code (as opposed to math above) it would be:
xi = index % x;
yi = (index / x) % y;
zi = index / (x * y);