I'm attempting to port the following JavaScript code to ruby:
https://github.com/iguigova/snippets_js/blob/master/pokerIn4Hours/pokerIn4Hours.js
I think I have most of it sorted, the function that is giving me grief is:
var kickers = function(idx){ // http://en.wikipedia.org/wiki/Kicker_(poker)
idx = idx || -15;
var notplayed = Math.max(input.length - 1/*player input*/ - 5, 0);
return function(all, cardinality, rank) {
return (all || 0) + (((cardinality == 1) && (notplayed-- <= 0)) ? rank * Math.pow(10, ++idx) : 0);
};
}();
And it is called further down like so:
k = kickers(k, cardsofrank[i], i);
I was wondering if someone could explain how this works in JavaScript. The fact that the inner function has 3 parameters and the outer only has 1 is confusing, especially given that it is called with 3 parameters. I would like to understand what it's trying to accomplish, so that I can port the code with confidence.
function(idx) this function returns a new function function(all, cardinality, rank) and this new function is referred by kickers variable in turn. so kickers is basically pointing at the inner function you have returned.
the only way to call your returned function is this kickers(k, cardsofrank[i], i)
var kickers = function(idx){
var xyz;//below function in return statement can access this and argument idx
return function(...) {//this ensures that your kickers is infact a function
};
}();//invoke this function instantly due to () and assign the output to kickers
When Javascript interpreter read above assignment to Kickers it will execute the anonymous function
Since that function itself returns a function, the kickers will now a function (with closure).
Meaning the kickers function will have a reference to the environment variables (idx and notplayed )
Edit:
1) Where it is getting value of idx - Since nothing is passed while invoking the function(last line ();) the idx will be undefined and idx = idx || -15; will assign the value -15 to it.
2) Could this be re-written without an inner function? - Yes. But the current implementation has an advantage where the scope of idx and notplayed is limited to kicker function and will not be accessible globally. Here is how you can write it directly as a function
/* now idx and notplayed is global- but its meant to be used only by kicker
* we cant move it inside the function definition as it will behave as local variable to the function
* and hence will be freed up once executed and you cannot maintain the state of idx and notplayed
*/
var idx = -15;
var notplayed = Math.max(input.length - 1/*player input*/ - 5, 0);
var kickers = function(all, cardinality, rank) {
return(all || 0) + (((cardinality == 1) && (notplayed-- <= 0)) ? rank * Math.pow(10, ++idx) : 0);
}
Related
why is it necessary to add return statement before ternary operator in recursive function to return function output?
// This dose not work
function rec(n) {
n == 1 ? n : n + rec(n - 1);
}
// This works as return statement is added before ternary operator
function rec(n) {
return n == 1 ? n : n + rec(n - 1);
}
// This works
function rec(n) {
if (n == 1) return 1;
return n + rec(n - 1);
}
// If you would like to do this in one line then correct solution would be:
let rec = n => n == 1 ? n : n + rec(n - 1);
// Now you dont need to add the return keyword before
// This works as return statement is added before ternary operator
function rec(n) {
return n == 1 ? n : n + rec(n - 1);
}
// This works
function rec(n) {
if (n == 1) return 1;
return n + rec(n - 1);
}
A recursive function is function which calls itself during the execution. The ternary operator decides if the function need to call itself. So the return statement call the same function.
In the example n == 1 ? n : n + rec(n - 1); if n=1 then the function should return the value of n if not then the function will call itself with new value that is n-1.
You need a return because of
n + rec(n - 1);
where the rec(n-1) call needs to return a value to be able to calculate n + rec(n - 1), and that goes for each call to rec() until n reaches 1 when it just returns 1.
return is never default in ternary operation.
return is default in Arrow-function but it not default in normal function deceleration.
to return a output from a normal function execution it is always necessary to add return statement, but it is optional in case of Arrow-function.
function x() { 5;}
console.log(x()); // Opuput: undefined
let y = () => 5;
console.log(y()); // Output: 5
A conditional expression (often called a ternary) is simply an expression. It yields a value, but it doesn't do anything with it. In fact, unless it has side-effects, it's totally useless unless you either:
return it from a function,
assign its result to a variable, or
nest it in another expression in which you do one of these things
You may be confused by the fact that arrow functions with single-expression bodies return the result of that expression. It's still being returned by the function, even though you don't explicitly use return. And because of this simplicity, conditional expressions are often used as the body of arrow function.
But it should be no more surpising that you have to have return here than that you have to have it in
function add (x, y) {
return x + y;
}
If you took out the return there, the addition will still happen when the function is invoked, but it won't yield any value. It's the same thing in your original.
I just stumbled upon an interesting example of recursive lambdas and I don't really understand why it works in this manner.
rec = lambda x : 1 if x==0 else rec(x-1)*x
f = rec
rec = lambda x: x+1
print(f(10))
Same in javascript.
var rec = function(a) {
if (a == 0) return 1;
return rec(a - 1) * a;
}
var f = rec
rec = function(a) {
return a + 1;
}
console.log(f(10));
To my surprise both of these print 100 instead of 10! (as I would expect).
Why does the reassignment of rec change the behavior of the f function? When the rec variable is captured in lambda, doesn't it refer to the lambda itself?
Edit.
As most of the answers explain what is going on, let me rephrase the question because I am looking for a more in depth explanation.
So at the moment of the declaration of the function rec in the first line why doesn't the rec in the body of the function bind to itself?
For example if you take JavaScript and rewrite the first line in a seemingly "same" way as suggested in one of the answers you get:
var rec =function rec(a) {
if (a == 0) return 1;
return rec(a - 1) * a;
};
f = rec;
rec = function (a) {
return a + 1;
}
console.log(f(10));
This one prints out 10! as one would expect.
So in this case the "inner rec"(in the function body) binds to the rec of the function-name instead of looking at rec variable and the reassignment of the variable rec didn't change the behavior.
So what I am really asking is the mechanism by which those languages decide what to bind the variables in the lambdas.
I am writing an interpreter myself for a class project and I came across to the same question of when and where to bind those variables. So I wanted to understand how this works in popular languages to implement something similar.
I will address it for python because that is what i am familiar with.
First, this behaviour is only possible because python (and looks like javascript i presume) follows late-binding for their closures. further read
Late binding is when the names within a closure are looked up at runtime (unlike early binding where the names are looked up at compile time.)
What this allows is to mutate behaviours at run time, by rebinding variables that are being looked up at runtime(such as functions like rec).
The last step then is just converting the lambda functions into equivalent def syntax so the real behaviour is clearer.
The code:
rec = lambda x : 1 if x==0 else rec(x-1)*x
f = rec
rec = lambda x: x+1
print(f(10))
Can be equivalent to:
First:
def somefunc(x):
return 1 if x==0 else rec(x-1)*x
Note, python will not complain about rec not existing even on a clean session/kernel because it does not look the value up during function definition. late binding means unless this function is called, python does not care about what rec is.
Then:
rec = somefunc
f = rec
def someotherfunc(x):
return x + 1
f(10) #3628800
Now we change the rec function
rec = someotherfunc
And observe that subsequent function calls of f will use the late-bound rec, that is looked up on the function call.
f(10) #100
PS. Complete code added below:
def somefunc(x):
return 1 if x==0 else rec(x-1)*x
rec = somefunc
f = rec
def someotherfunc(x):
return x + 1
f(10) #3628800
rec = someotherfunc
f(10) #100
You could add some console.log and view, that first f is called with 10, then rec with 9 and the result is 10 * 10.
var rec = function(a) {
console.log('f', a);
if (a == 0) return 1;
return rec(a - 1) * a;
};
f = rec;
rec = function(a) {
console.log('rec', a);
return a + 1;
}
console.log(f(10));
Keeping rec.
var rec = function rec(a) {
console.log('f', a);
if (a == 0) return 1;
return rec(a - 1) * a;
};
f = rec;
rec = function(a) {
console.log('rec', a);
return a + 1;
}
console.log(f(10));
These 3 statements can sum up to a single statement
rec = lambda x : 1 if x==0 else rec(x-1)*x
f = rec
rec = lambda x: x+1
from 1 & 2
f = lambda x : 1 if x==0 else rec(x-1)*x
from above & 3
f = lambda x : 1 if x==0 else x*x
I will suggest to use variable names properly, here you don't need reassignment
why it uses second rec not the first one ?
well your function call is happening after reassignment of rec so you have the latest value in rec as
rec = function(a) {
return a + 1;
}
var f = function(a) {
if (a == 0) return 1;
return rec(a - 1) * a;
}
var rec = function(a) {
return a + 1;
}
console.log(f(10));
Should add all the natural numbers below 1000 that are multiples of 3 or 5.
var sum = _.reduce( _.range(1, 1000), function(x, n) {
if (n % 3 == 0 || n % 5 == 0) { return x+=n; }
}, 0);
I expect the output to be 233168 but I get NaN.
For some reason sum is not accepting the initialized value of 0. However if I preface this with var sum = 0; then it works and returns the proper output of 233168
Why doesn't it accept the initialized value?
The problem is the reducing function returns undefined when the conditional fails .. thus x evaluates to undefined (the last return value) in the subsequent invocation .. and undefined + a number is .. well, NaN.
Also, reduce is being used incorrectly; it should carry its own state. Compare it with:
var sum = _.reduce( _.range(1, 1000), function(x, n) {
// Add n to the tally if it is a valid multiple..
// (the returned value is used as the *next* value of x)
if (n % 3 == 0 || n % 5 == 0) { return x + n; }
// ..or simply return the current tally.
else { return x; }
}, 0);
Note that the sum variable was not assigned from within the reducing function (it would have been overwritten by the outside assignment anyway). This keeps reduce a pure operation, not withstanding the occasional abuse of a mutable memo, truer to its functional roots.
I have this simple factorial function. It works on recursion. the number that I get at the end however is NaN. I am expecting an output of 6, factorial of 3. Is the problem because I defined x as a global variable ? and if so how do you define a variable as local inside the function without making it change in recursion.
var x;
function factorial(num)
{
if (num > 0) {
x = num * factorial(num - 1);
}
return x;
}
console.log(factorial(3));
If num > 0, you define x. What is x when num is not > 0?
HINT: Should be 1. Isn't. :)
HINT2: Try console.log(1 * undefined)
P.S.: Yes, var x should go inside the function. No, it doesn't do anything bad in this case, but it could.
You need to initialize x with value first.
var x = 1;
Let's investigate detaily what happened:
f(3) = 3 * f(2);
f(2) = 2 * f(1);
f(1) = 1 * f(0);
For f(0), it directly goes to return x;, while your global variable var x; is not initialized, thus f(0) return undefined, and 1 * factorial(0) get NaN, propagates to the final result.
One solution is not to use global variable:
function factorial(num)
{
var x = 1;
if (num > 0) {
x = num * factorial(num - 1);
}
return x;
}
console.log(factorial(3)); // 6
I'm trying to understand how recursion works in javascript. But I'm having problems even getting this function to work properly.
example problem shows calculating power and "potentially" setting the results of the calculation to innerHTML of var my header:
var myHeader= document.getElementById("myHeader");
var answer = 0;
answer = power(10, 5);
function power(base, exponent) {
if(exponent == 0)
return 0;
else
return base * power(base, exponent - 1);
}
myHeader.innerHTML = answer;
Could you please edit this example code to make it work?
Example code
I just want to use chrome debuggers so I can set a breakpoint and walk through the function one by one to see the order of operations.
I'm taking this function from eloquent javascript by Marijin Haverbeke
Your power function is wrong
function power(n, p) {
if(p == 0)
{
return 1; // see Math.pow(5, 0) for example
}
return power(n, p - 1) * n;
}
and
document.getElementById('myHeader').innerHTML = power(5, 10);
You have 2 problems :
1 You used var answer = 0, you didn't assign it to get the result from power.
2 Inside your function, you returned 0 if exponent === 0, so basically, when exponent = 0, you are returning base * power(base, 0) which equals to base * 0 which in turn equals to 0, so your function will always return 0.
var myHeader= document.getElementById("myHeader");
var answer = power(10,5);
function power(base, exponent) {
if(exponent === 0)
return 1;
else
return base * power(base, exponent - 1);
}
myHeader.innerHTML = answer;
myHeader.innerHTML = power(10,5);
If you are looking for some ref parameters like in C#: function(param1, param2, ref param3), no, JavaScript has no such parameter.
If you're just looking to get the power function working, then this is a better solution:
document.getElementById("myHeader").innerHTML = Math.pow(10,5);