Why does this function return true? - javascript

const res = (n => {
const even = x => {
if (x === 0)
return true
else {
const odd = y => !even(y)
return odd(x - 1)
}
}
return even(n)
})(42)
console.log(res) //=> true
since 42 was used in the paramtersbut it says to return true only if x is 0 with strictly equaling its type and value, I'm not sure why true is returned. I thought any value but 0 should return false. Can someone please explain this to me, I am very new to javascript and programming.

If you strip all unnecessary parts with local functions and IIFE, then you get just a test for zero, then it's an even value or a recursive call of not even with a reduced value by one.
const even = x => x === 0 || !even(x - 1);
console.log(even(42)) // true
console.log(even(43)) // false
Whats happens is a recursive call of even
n result of calling simplified
-- ----------------- ----------
8 !even(7) !even(7)
7 !!even(6) even(6)
6 !!!even(5) !even(5)
5 !!!!even(4) even(4)
4 !!!!!even(3) !even(3)
3 !!!!!!even(2) even(2)
2 !!!!!!!even(1) !even(1)
1 !!!!!!!!even(0) even(0)
0 !!!!!!!!true true

Lets simplify.
Step 1
const f = n => {
const even = x => {
if (x == 0)
return true
else {
const odd = y => !even(y)
return odd(x - 1)
}
}
return even(n)
}
Step 2
const f = n => {
const even = x => {
if (x == 0) return true
return !even(x - 1)
}
return even(n)
}
Step 3
const f = n => {
let modificator = true
while (true) {
if (n == 0) return modificator
modificator = !modificator
n = n - 1
}
}
Step 4
const f = n => !(n % 2)

The code works by doing negations even/odd times using recursion. Even times negating true gives true. Odd times negating true gives false. Forget 42 check 1 and 2.
If you open up console, you can see stack trace as well.
return even(2) =>
even(2) => odd(2 - 1)
odd(1) => return !even(1)
!even(1) => ! (odd(1-1))
! (odd(0)) => ! ( !(even(0))) => even(0)
even(0) => true
return even(1) =>
even(1) => odd(1 - 1)
odd(0) => !even(0)
!even(0) => !(true) => false
x is 0 with strictly equaling its type and value, I'm not sure why
true is returned
This happens at the tail of recursion, this true is switched back and forth between true and false as each recursive call completes using the negation at !even(y)
const res = ((n) => {
const even = (x) => {
if (x === 0) {
console.log(x);
console.trace();
return true;
}
else {
const odd = (y) => !even(y);
console.log(x);
console.trace();
return odd(x - 1);
}
}
return even(n)
})(2) //=> true
console.log(res);

Related

Recursive call to a monotonic function with an IIFE stop or creating add function that returns unknown num of functions for adding the next number [duplicate]

I need a js sum function to work like this:
sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10
etc.
I heard it can't be done. But heard that if adding + in front of sum can be done.
Like +sum(1)(2)(3)(4). Any ideas of how to do this?
Not sure if I understood what you want, but
function sum(n) {
var v = function(x) {
return sum(n + x);
};
v.valueOf = v.toString = function() {
return n;
};
return v;
}
console.log(+sum(1)(2)(3)(4));
JsFiddle
This is an example of using empty brackets in the last call as a close key (from my last interview):
sum(1)(4)(66)(35)(0)()
function sum(firstNumber) {
let accumulator = firstNumber;
return function adder(nextNumber) {
if (nextNumber === undefined) {
return accumulator;
}
accumulator += nextNumber;
return adder;
}
}
console.log(sum(1)(4)(66)(35)(0)());
I'm posting this revision as its own post since I apparently don't have enough reputation yet to just leave it as a comment. This is a revision of #Rafael 's excellent solution.
function sum (n) {
var v = x => sum (n + x);
v.valueOf = () => n;
return v;
}
console.log( +sum(1)(2)(3)(4) ); //10
I didn't see a reason to keep the v.toString bit, as it didn't seem necessary. If I erred in doing so, please let me know in the comments why v.toString is required (it passed my tests fine without it). Converted the rest of the anonymous functions to arrow functions for ease of reading.
New ES6 way and is concise.
You have to pass empty () at the end when you want to terminate the call and get the final value.
const sum= x => y => (y !== undefined) ? sum(x + y) : x;
call it like this -
sum(10)(30)(45)();
Here is a solution that uses ES6 and toString, similar to #Vemba
function add(a) {
let curry = (b) => {
a += b
return curry
}
curry.toString = () => a
return curry
}
console.log(add(1))
console.log(add(1)(2))
console.log(add(1)(2)(3))
console.log(add(1)(2)(3)(4))
Another slightly shorter approach:
const sum = a => b => b? sum(a + b) : a;
console.log(
sum(1)(2)(),
sum(3)(4)(5)()
);
Here's a solution with a generic variadic curry function in ES6 Javascript, with the caveat that a final () is needed to invoke the arguments:
const curry = (f) =>
(...args) => args.length? curry(f.bind(0, ...args)): f();
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1)() == 5 // true
Here's another one that doesn't need (), using valueOf as in #rafael's answer. I feel like using valueOf in this way (or perhaps at all) is very confusing to people reading your code, but each to their own.
The toString in that answer is unnecessary. Internally, when javascript performs a type coersion it always calls valueOf() before calling toString().
// invokes a function if it is used as a value
const autoInvoke = (f) => Object.assign(f, { valueOf: f } );
const curry = autoInvoke((f) =>
(...args) => args.length? autoInvoke(curry(f.bind(0, ...args))): f());
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1) + 0 == 5 // true
Try this
function sum (...args) {
return Object.assign(
sum.bind(null, ...args),
{ valueOf: () => args.reduce((a, c) => a + c, 0) }
)
}
console.log(+sum(1)(2)(3,2,1)(16))
Here you can see a medium post about carried functions with unlimited arguments
https://medium.com/#seenarowhani95/infinite-currying-in-javascript-38400827e581
Try this, this is more flexible to handle any type of input. You can pass any number of params and any number of paranthesis.
function add(...args) {
function b(...arg) {
if (arg.length > 0) {
return add(...[...arg, ...args]);
}
return [...args, ...arg].reduce((prev,next)=>prev + next);
}
b.toString = function() {
return [...args].reduce((prev,next)=>prev + next);
}
return b;
}
// Examples
console.log(add(1)(2)(3, 3)());
console.log(+add(1)(2)(3)); // 6
console.log(+add(1)(2, 3)(4)(5, 6, 7)); // 28
console.log(+add(2, 3, 4, 5)(1)()); // 15
Here's a more generic solution that would work for non-unary params as well:
const sum = function (...args) {
let total = args.reduce((acc, arg) => acc+arg, 0)
function add (...args2) {
if (args2.length) {
total = args2.reduce((acc, arg) => acc+arg, total)
return add
}
return total
}
return add
}
document.write( sum(1)(2)() , '<br/>') // with unary params
document.write( sum(1,2)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)() , '<br/>') // with unary params
document.write( sum(1)(2,3)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)(4)() , '<br/>') // with unary params
document.write( sum(1)(2,3,4)() , '<br/>') // with ternary params
ES6 way to solve the infinite currying. Here the function sum will return the sum of all the numbers passed in the params:
const sum = a => b => b ? sum(a + b) : a
sum(1)(2)(3)(4)(5)() // 15
function add(a) {
let curry = (b) => {
a += b
return curry;
}
curry[Symbol.toPrimitive] = (hint) => {
return a;
}
return curry
}
console.log(+add(1)(2)(3)(4)(5)); // 15
console.log(+add(6)(6)(6)); // 18
console.log(+add(7)(0)); // 7
console.log(+add(0)); // 0
Here is another functional way using an iterative process
const sum = (num, acc = 0) => {
if !(typeof num === 'number') return acc;
return x => sum(x, acc + num)
}
sum(1)(2)(3)()
and one-line
const sum = (num, acc = 0) => !(typeof num === 'number') ? acc : x => sum(x, acc + num)
sum(1)(2)(3)()
You can make use of the below function
function add(num){
add.sum || (add.sum = 0) // make sure add.sum exists if not assign it to 0
add.sum += num; // increment it
return add.toString = add.valueOf = function(){
var rtn = add.sum; // we save the value
return add.sum = 0, rtn // return it before we reset add.sum to 0
}, add; // return the function
}
Since functions are objects, we can add properties to it, which we are resetting when it's been accessed.
we can also use this easy way.
function sum(a) {
return function(b){
if(b) return sum(a+b);
return a;
}
}
console.log(sum(1)(2)(3)(4)(5)());
To make sum(1) callable as sum(1)(2), it must return a function.
The function can be either called or converted to a number with valueOf.
function sum(a) {
var sum = a;
function f(b) {
sum += b;
return f;
}
f.toString = function() { return sum }
return f
}
function sum(a){
let res = 0;
function getarrSum(arr){
return arr.reduce( (e, sum=0) => { sum += e ; return sum ;} )
}
function calculateSumPerArgument(arguments){
let res = 0;
if(arguments.length >0){
for ( let i = 0 ; i < arguments.length ; i++){
if(Array.isArray(arguments[i])){
res += getarrSum( arguments[i]);
}
else{
res += arguments[i];
}
}
}
return res;
}
res += calculateSumPerArgument(arguments);
return function f(b){
if(b == undefined){
return res;
}
else{
res += calculateSumPerArgument(arguments);
return f;
}
}
}
let add = (a) => {
let sum = a;
funct = function(b) {
sum += b;
return funct;
};
Object.defineProperty(funct, 'valueOf', {
value: function() {
return sum;
}
});
return funct;
};
console.log(+add(1)(2)(3))
After looking over some of the other solutions on here, I would like to provide my two solutions to this problem.
Currying two items using ES6:
const sum = x => y => (y !== undefined ) ? +x + +y : +x
sum(2)(2) // 4
Here we are specifying two parameters, if the second one doesnt exist we just return the first parameter.
For three or more items, it gets a bit trickier; here is my solution. For any additional parameters you can add them in as a third
const sum = x => (y=0) => (...z) => +x + +y + +z.reduce((prev,curr)=>prev+curr,0)
sum(2)()()//2
sum(2)(2)()//4
sum(2)(2)(2)//6
sum(2)(2)(2,2)//8
I hope this helped someone

How do I return the number value of an if statement if certain conditions are met?

I am working on a function where if certain properties of an array are true then return the number of those conditions that are true.
e.g.
if (a > b || a < c || d == e || f == e)
{
return "number of condition that are met";
}
Store the conditions in an array
const conditions = [
(a,b,c,d,e,f) => a>b,
(a,b,c,d,e,f) => a<c,
(a,b,c,d,e,f) => d==e,
(a,b,c,d,e,f) => f==e,
];
Now, you can use filter to find how many are true
const howManyTrues = conditions.filter(cond => cond(a,b,c,d,e,f) )
if(howManyTrue > 0){
return howManyTrue;
}

Trying to make a repeater function using only higher order functions?

I'm trying to make a function that accepts another function and outputs that function repeatedly by only using function expressions/applications.
So far I have a function twice which accepts another function as an argument and returns func(func(x)):
function twice(func) {
function x(x) {
return func(func(x));
}
return x;
}
I'm trying to make a repeater function such that const thrice = repeater(twice) returns func(func(func(x))), and const fourtimes = repeater(thrice) etc. but i'm confused as to how to do this. Any help would be appreciated greatly. Thank you
Using your current structure thats impossible as twice does not expose a reference to func, thus repeater cannot call it.
The only solution I could think of would be to leak func from the inside through a (hidden) property:
const r = Symbol();
const repeater = f => Object.assign(
v => f[r] ? f(f[r](v)): f(v),
{ [r]: f[r] || f }
);
const addThree = repeater(repeater(repeater(n => n + 1)));
console.log(addThree(10));
You should two base cases (if n == 0 => exit, if n == 1 => return f(x)), where n is an additional parameter that specifies how many times the function should repeat with the arguments args:
function repeater(func, x, n) {
if (n == 0) return;
if (n == 1) return func(x);
else {
return func(repeater(func, x, --n));
}
}
let sqr = n => n * n;
console.log(repeater(sqr, 2, 3));
Do you look for something like this?
function chain(f, g) {
return function (x) {
return f(g(x));
}
}
function ntimes(f, n) {
if (n == 0) {
return function (x) { return x }
} else {
return chain(f, ntimes(f, n-1));
}
}
This will make a new function which repeats the original function f n times.

Calculate Base Factorial

How could I function named unfactorial that takes a number and returns a string representing it's base factorial in the form: n!? This would result in the un-do the factorial operation if one is possible. It should return null if no factorial was possible.
Package
A factorial operation looks like this:
5! = 5 * 4 * 3 * 2 * 1 = 120
Function Output:
unfactorial(120) // '5!'
unfactorial(150) // null
unfactorial(5040) // '7!'
My current Solution
const unfactorial = (num) => {
let d = 1
while (num > 1 && Math.round(num === num)) {
d += 1
num /= d
}
if (num === 1)
return `${d}!`
else return null
}
Here's one way you could do it using an auxiliary recursive function.
Note, it will not work for numbers that are not actual factorials. This is left as an exercise for the asker.
const unfactorial = x => {
const aux = (acc, x) => {
if (x === 1)
return acc - 1
else
return aux(acc + 1, x / acc)
}
return aux(2, x)
}
console.log(unfactorial(120)) // 5
console.log(unfactorial(5040)) // 7
How it works
Starting with the input number x and a counter, acc = 2, successively divide x by acc (then acc + 1, then acc + 2, etc) until x == 1. Then return acc - 1.
Or go bananas using only expressions. You'll probably like this, #Mr.Polywhirl
const U = f => f (f)
const Y = U (h => f => f (x => h (h) (f) (x)))
const unfactorial = Y (f => acc => x =>
x === 1 ? acc - 1 : f (acc + 1) (x / acc)
) (2)
console.log(unfactorial(120)) // 5
console.log(unfactorial(5040)) // 7

How to build a function with multiple fat arrows clauses in javascript?

I am coming to Javascript from a functional background.
I am imagining something like this to compute the factorial of 3:
var Function1 =
{
(0) => 1,
(1) => 1,
(n) => n*Function1(n-1)
}
document.write(Function1(3),"<br/>")
but it doesn't work.
Is there something similar to my example in javascript that computes 6 using fat arrow notation?
You can't do it in the descriptive/declarative way in JS, but you can listen to the value of the parameter and react accordingly:
var Function1 = (n) => {
if (n === 0) return 1;
if (n === 1) return 1;
return Function1(n-1)*n;
}
document.write(Function1(3),"<br/>"); // 6
Another way would be to return a curried function:
var Function1 = (n) => {
if (n === 0) return () => 1;
if (n === 1) return () => 1;
return () => Function1(n-1)()*n;
}
document.write(Function1(3)(),"<br/>"); // 6
Mind the second function call here Function1(3)().
Your example could be shortened a bit with a ternary operator, but it works against maintainability and readability:
var Function1 = (n) => [0, 1].includes(n) ? 1 : Function1(n-1)*n;
document.write(Function1(3),"<br/>"); // 6
Simplified "one-line" alternative using Number constructor:
var Function1 = (n) => { return Number(n === 0 || n === 1) || Function1(n-1)*n; };
console.log(Function1(0)); // 1
console.log(Function1(1)); // 1
console.log(Function1(4)); // 24

Categories