Zibonacci recursive, what's wrong with my solution? - javascript

I followed the rules but I still get stack-overflow for n>2.
This function borrows ideas from the Fibonacci series, but the calculated results appear to zig and zag, hence the name. A so-called 'Zibonacci' series would be defined by the following rules:
Zib(0) == 1;
Zib(1) == 1;
Zib(2) == 2;
Zib(2n+1) == Zib(n) + Zib(n-1)+1, if n>0 (i.e. odd values 3 and higher)
Zib(2n) == Zib(n) + Zib(n+1)+1, if n>1 (i.e. even values 4 and higher).
Create the Zibonacci(num) function.
My solution:
function Zibonacci(num){
// Enter code below
if(num == 0){
return 1;
}
if(num == 1 || num == 2){
return num;
}
if(num>0 && num%2 != 0){
return Zibonacci(num) + Zibonacci(num-1)+1;
}
if(num>1 && num%2 == 0){
return Zibonacci(num) + Zibonacci(num+1)+1;
}
}

You'll first need to reformulate the recursive equations to derive Z(n) instead of Z(2n+1) and Z(2n):
Zib(n) == Zib((n - 1) / 2) + Zib((n - 1) / 2 - 1) + 1, if n>0 (i.e. odd values 3 and higher)
Zib(n) == Zib(n / 2) + Zib(n / 2 + 1) + 1, if n>1 (i.e. even values 4 and higher).
This leads to code like this:
function Zibonacci(num){
if (num == 0) {
return 1;
}
if (num == 1 || num == 2) {
return num;
}
if (num > 0 && num % 2 != 0){
return Zibonacci((num - 1) / 2) + Zibonacci((num - 3) / 2) + 1;
}
if (num > 1 && num % 2 == 0) {
return Zibonacci(num / 2) + Zibonacci((num + 2) / 2) + 1;
}
}
for (let i = 0; i < 10; i++) {
console.log(i, Zibonacci(i));
}

#trincot is correct, you have to rewrite the recursive equations in terms of z(n). You can use inductive reasoning for the rest -
if n is negative, throw an error (optional)
(inductive) n is non-negative. if n is less than 3, return max(1,n)
(inductive) n is greater than 2. if n is odd, return z((n - 1) / 2) + z((n - 1) / 2 - 1) + 1
(inductive) n is greater than 2 and even. return z(n / 2) + z(n / 2 + 1) + 1
function z(n) {
if (n < 0)
throw Error
else if (n < 3)
return Math.max(1, n)
else if (n & 1)
return z((n - 1) / 2) + z((n - 1) / 2 - 1) + 1
else
return z(n / 2) + z(n / 2 + 1) + 1
}
for (let i = 0; i < 10; i++)
console.log(i, z(i))
.as-console-wrapper { min-height: 100%; top: 0; }
0 1
1 1
2 2
3 3
4 6
5 4
6 10
7 6
8 11
9 10
We can also write z as a pure functional expression -
const z = n => // n for all n >= 0
n < 3
? Math.max(1, n) // base
: n & 1
? z((n - 1) / 2) + z((n - 1) / 2 - 1) + 1 // odd
: z(n / 2) + z(n / 2 + 1) + 1 // even
for (let i = 0; i < 10; i++)
console.log(i, z(i))
.as-console-wrapper { min-height: 100%; top: 0; }
0 1
1 1
2 2
3 3
4 6
5 4
6 10
7 6
8 11
9 10

Related

Find closest number divisible by 3 [duplicate]

This question already has answers here:
Next Nearest Number Divisible By X [closed]
(2 answers)
Getting a number divisible by five with Math.Round
(5 answers)
Closest divisible integer
(8 answers)
Closed 1 year ago.
I need to find a way to get the closest number divisible by three for a given number. As it's only the number three, and i was in a rush, i used if statements. I was wondering if there was a cleaner way of getting the same result?
https://jsfiddle.net/
let indexes = [0, 9, 26, 39];
for (let i = 0, l = indexes.length; i < l; i++) {
newIndex = indexes[i];
if (!(newIndex % 3 == 0)) {
if (((newIndex - 1) % 3 == 0)) {
newIndex = (newIndex - 1);
} else {
if (((newIndex + 1) % 3 == 0)) {
newIndex = (newIndex + 1);
} else if (((newIndex + 2) % 3 == 0)) {
newIndex = (newIndex + 2);
} else if (((newIndex + 3) % 3 == 0)) {
newIndex = (newIndex + 3);
}
}
}
console.log(newIndex);
}
input: 0
expected output: 0
input: 9
expected output: 9
input: 26
expected output: 27
input: 39
expected output: 39
I think i made it a little cleaner.
let indexes = [0, 9, 26, 39, 29];
for (let i = 0; i < indexes.length; i++) {
if(indexes[i] % 3 == 0) {
console.log('Closest multiple: ', indexes[i])
}
else {
if((indexes[i] + 1) % 3 == 0) {
console.log('Closest multiple: ', indexes[i] + 1)
}else {
console.log('Closest multiple: ', indexes[i] - 1)
}
}
}
this switch case would make it better readable
function Get(input){
var number = input % 3;
switch(number){
case 0:
return input;
case 1:
return input-1;
case 2:
return input+1;
default:
return "somethign went wrong";
}
}
So now, you basically have to iterate through your array calling the function above.

addWithSurcharge exercise alternative answers

I had this JavaScript exercise from jshero.net:
Write a function addWithSurcharge that adds two amounts with surcharge. For each amount less than or equal to 10, the surcharge is 1. For each amount greater than 10 and less than or equal to 20, the surcharge is 2. For each amount greater than 20, the surcharge is 3. The call addWithSurcharge(10, 30) should return 44.
My solution was :
function addWithSurcharge (a,b){
let myS = a+b
if (myS <10){
return myS +=2} else if (myS >10 && myS <=20){
return myS +=2} else if (myS >20 && myS <30){
return myS +=3} else if (myS >= 30 && myS <40){
return myS +=4} else if(myS >40){
return myS +=5}
}
Somehow it worked, I passed the challenge but I feel like there was an easier way to solve this. Do you know other alternative answers for this exercise?
you could write it as a switch statement. something like this:
function addWithSurcharge (a,b) {
let myS = a+b
switch (true){
case myS < 10:
return myS + 2
case (myS > 10 && myS <= 20):
return myS + 2
case (myS > 20 && myS < 30):
return myS + 3
case (myS >= 30 && myS < 40):
return myS + 4
default:
return myS + 5
}
}
I think you can round to the superior decade and then divide by 10.
I'm surprised you passed the test cause you don't really fit the problem, you forgot every case when equal to 10, 20, 30, ...
By the way, this is my way to answer your problem. With this way it's "infinite" but if you wan't stop adding after 40, just add Math.max(X, (decadeRounded / 10)) where X is your maximum, for example Math.max(5, (decadeRounded / 10))
function addWithSurcharge (a,b) {
let myS = a + b
let decadeRounded = Math.round( (myS/10) ) * 10;
return myS + (decadeRounded / 10);
}
document.getElementById('result').innerHTML = addWithSurcharge(10, 20);
<div id="result"></div>
You can try something like this
function addWithSurcharge(a, b) {
if (a <= 10) {
a += 1
} else if (a > 10 && a <= 20) {
a += 2
} else if (a > 20) {
a += 3
}
if (b <= 10) {
b += 1
} else if (b > 10 && b <= 20) {
b += 2
} else if (b > 20) {
b += 3
}
return a + b;
}
function addWithSurcharge(a, b) {
i = 0;
if (a <= 10) {
i = i + 1;
} else if (a > 10 && a <= 20) {
i = i + 2;
} else if (a > 20) {
i = i + 3;
}
if (b <= 10) {
i = i + 1;
} else if (b > 10 && b <= 20) {
i = i + 2;
} else if (b > 20) {
i = i + 3;
}
return a + b + i;
}

Similar Javascript and python code does not give same result

I have a problem, I have 2 scripts one is in javascript and one is python.
I want to use python to generate the value so I tried to rewrite javascript code to python
but the output is not the same and I can't seem to figure out what values are incorrect!
Any help is appreciated
I am very bad at javascript, but I have a basic/decent understanding of python.
My javascript Code:
<html><head><script type="text/javascript"><!--
function leastFactor(n) {
if (isNaN(n) || !isFinite(n)) return NaN;
if (typeof phantom !== 'undefined') return 'phantom';
if (typeof module !== 'undefined' && module.exports) return 'node';
if (n==0) return 0;
if (n%1 || n*n<2) return 1;
if (n%2==0) return 2;
if (n%3==0) return 3;
if (n%5==0) return 5;
var m=Math.sqrt(n);
for (var i=7;i<=m;i+=30) {
if (n%i==0) return i;
if (n%(i+4)==0) return i+4;
if (n%(i+6)==0) return i+6;
if (n%(i+10)==0) return i+10;
if (n%(i+12)==0) return i+12;
if (n%(i+16)==0) return i+16;
if (n%(i+22)==0) return i+22;
if (n%(i+24)==0) return i+24;
}
return n;
}
function go() {
var p=2998236216354; var s=1750047503; var n;
if ((s >> 15) & 1)/*
else p-=
*/p+= 80068513*
16; else /*
else p-=
*/p-=
60707526*/*
*13;
*/16;/*
p+= */if ((s >> 7) & 1)/*
else p-=
*/p+=/*
else p-=
*/116987388* 8; else
p-= 172213350*/*
else p-=
*/8;if ((s >> 2) & 1)/*
*13;
*/p+=/*
p+= */54228284*/* 120886108*
*/5;/*
*13;
*/else /*
p+= */p-= 542313502*/* 120886108*
*/3;/*
*13;
*/if ((s >> 10) & 1) p+=66991160*/* 120886108*
*/13;else /*
p+= */p-=
158065083*
11;if ((s >> 2) & 1)/*
else p-=
*/p+=311247981*/*
*13;
*/5;/*
*13;
*/else /*
else p-=
*/p-=
376627923* 3; p-=910005807;
n=leastFactor(p);
{ document.cookie="RNKEY="+n+"*"+p/n+":"+s+":3025753160:1";
}
}
//--></script></head>
<body onload="go()">
Loading ...
</body>
</html>
My Python Code:
import math
def least_factor(n):
if n == 0:
return 0;
if n % 1 or n * n < 2: return 1
if n % 2 == 0: return 2
if n % 3 == 0: return 3
if n % 5 == 0: return 5
m = math.sqrt(n)
for i in range(7, int(m + 1), 30):
if n % i == 0: return i
if n % (i + 4): return i + 4
if n % (i + 6): return i + 6
if n % (i + 10): return i + 10
if n % (i + 12): return i + 12
if n % (i + 16): return i + 16
if n % (i + 22): return i + 22
if n % (i + 24): return i + 24
return n
def go():
p = 2998236216354
s = 1750047503
n = None
if (s >> 15) & 1: p += 80068513 * 16
else: p -= 60707526 * 16
if (s >> 7) & 1: p += 116987388 * 8
else: p -= 172213350 * 8
if (s >> 2) & 1: p += 54228284 * 5
else: p -= 542313502 * 3
if (s >> 10) & 1: p += 66991160 * 13
else: p -= 158065083 * 11
if (s >> 2) & 1: p += 311247981 * 5
else: p -= 376627923 * 3
p -= 910005807
n = least_factor(p)
return f'RNKEY={n}*{p / n}:{s}:3025753160:1'
print(go())
The output on javascript is:
RNKEY=1691507*1771981:1750047503:3025753160:1
But on Python the output is:
RNKEY=11*272483478669.72726:1750047503:3025753160:1
Can someone help me understand where in my python code I am giving the wrong values?
Thanks in advance!
In your Python code, in the for loop, you have a line
if n % (i + 4): return i + 4
This if condition is true if n % (i+4) is not equal to 0, so if n is not divisible by i+4. This is the opposite of what you want, and the opposite of what your JavaScript code does.
It should be, for example,
if not n % (i + 4): return i + 4

While loop output not correct

I'm busy with a udacity excercise and the following question:
A while loop that:
Loop through the numbers 1 to 20
If the number is divisible by 3, print "Julia"
If the number is divisible by 5, print "James"
If the number is divisible by 3 and 5, print "JuliaJames"
If the number is not divisible by 3 or 5, print the number
I keep submitting the answer but it tells me that my while loop condition is incorrect, Is there anything im doing wrong?
var x = 1;
while (x <= 20) {
if (x/3 === 0) {
console.log("julia" );
} // check divisibility
else if (x/5 === 0) {
console.log("james");
}
else if (x/5 === 0 && x/3 === 0 ) {
console.log("juiliajames");
} // print Julia, James, or JuliaJames
else {
console.log(x);
}
x= x + 1;// increment x
}
You need to use Modulus (%) instead of divide (/). And make x % 5 === 0 && x % 3 === 0 as your first condition.
Change your code like following.
var x = 1;
while (x <= 20) {
if (x % 5 === 0 && x % 3 === 0) {
console.log("juiliajames");
} // print Julia, James, or JuliaJames
else if (x % 3 === 0) {
console.log("julia");
} // check divisibility
else if (x % 5 === 0) {
console.log("james");
} else {
console.log(x);
}
x = x + 1; // increment x
}
var x = 1;
while (x <= 20) {
if(x%3 === 0 && x%5 === 0 ){
console.log("juiliajames" );
} // check divisibility
else if(x%3 === 0){
console.log("juilia");
}
else if (x%5 === 0){
console.log("james");
} // print Julia, James, or JuliaJames
else{
console.log(x);
}
x= x + 1;// increment x
}
If you want to check divisibility, you should use the % operator instead of / operator.
Check x divisible by 5 AND 3 at the begining or it will never been done because if it is divisible by 3 your loop won't go to the else if statment.
To check divisibility use modulo (x/3 === 0 only for x = 0)
var x = 1;
while (x <= 20) {
if(x%5 === 0 && x%3 === 0){
console.log("juiliajames" );
}
else if(x%5 === 0){
console.log("james");
}
else if (x%3 === 0 ){
console.log("juilia");
}
else{
console.log(x);
}
x= x + 1;// increment x
}
My approach works by setting bitwise flags on an integer. If it's divisible by three (value % 3 === 0, where % is 'modulo' which gives an integer remainder from division) The first bit is set and if it's divisible by five the second bit is set. That gives a result that could have three binary values 01, 10 or 11, or in decimal 1, 2 & 3 (The three comes about when both bits are set).
var DIVISABLE_BY_THREE = 1;
var DIVISABLE_BY_FIVE = 2;
var DIVISABLE_BY_THREE_AND_FIVE = 3;
var value = 0;
while(value++ < 20) {
var modulo_3 = (value % 3 === 0) | 0;
var modulo_5 = ((value % 5 === 0) | 0) << 1;
switch(modulo_3 | modulo_5) {
case DIVISABLE_BY_THREE:
console.log("Julia");
break;
case DIVISABLE_BY_FIVE:
console.log("James");
break;
case DIVISABLE_BY_THREE_AND_FIVE:
console.log("JuliaJames");
break;
default:
console.log(value);
break;
}
}
var x = 1;
while (x <= 20) {
var name ="";
if (x % 3 == 0) {
name = name + "julia";
}
if (x % 5 == 0) {
name = name + "james";
}
if(name.length > 0)
console.log(name);
else
console.log(x);
x++;
}

Format numbers in comma separated value

I am using javascript to format the number with commas , it was working very fine.
But now the problem is if a value is comming in negative for example : -792004
It is returning the output like : -,792,004 that is comma is in the start.
How can I modify this method ?
Here is my code :
function Comma(number) {
number = '' + number;
if (number.length > 3) {
var mod = number.length % 3;
var output = (mod > 0 ? (number.substring(0, mod)) : '');
for (i = 0; i < Math.floor(number.length / 3); i++) {
if ((mod == 0) && (i == 0))
output += number.substring(mod + 3 * i, mod + 3 * i + 3);
else
output += ',' + number.substring(mod + 3 * i, mod + 3 * i + 3);
}
return (output);
} else return number;
}
The simplest way I know which will helps you is toLocaleString() method on number:
var x = 10033001;
var y = -10033001;
console.log(x.toLocaleString(), y.toLocaleString());
But for correction of your code, you can remove number sign with Math.abs and add it after with Math.sign.
var sign = Math.sign(number);
number = Math.abs(number);
// Do the conversion
return (sign < 0) ? ("-" + output) : output;
Try this:
const comma = function(number) {
const prefix = number < 0 ? '-' : ''
number = String(Math.abs(number))
if (number.length > 3) {
const mod = number.length % 3
let output = (mod > 0 ? (number.substring(0,mod)) : '')
for (let i = 0; i < Math.floor(number.length / 3); i++) {
if (mod === 0 && i === 0)
output += number.substring(mod+ 3 * i, mod + 3 * i + 3)
else
output+= ',' + number.substring(mod + 3 * i, mod + 3 * i + 3);
}
return prefix + output
} else {
return prefix + number
}
}
If the number is negative, it assigns - to prefix. Then it changes number to its absolute value (Math.abs(number)). In the end it returns value with prefix.

Categories