Wrong recursion when trying to find Range Sum of BST - javascript

I'm practicing algorithms and tackling this classic problem. There are many solutions and I'm trying to solve it using Javascript. I'll post the question and what I have below:
Given the root node of a binary search tree, return the sum of values of all nodes with value between L and R (inclusive).
The binary search tree is guaranteed to have unique values.
Example 1:
Input: root = [10,5,15,3,7,null,18], L = 7, R = 15 Output: 32
var rangeSumBST = function(root, L, R) {
let result = 0;
if (root === null) return 0;
if (root.val >= L && root.val <= R) {
result += root.val
}
rangeSumBST(root.left, L, R)
rangeSumBST(root.right, L, R)
return result
};
// Output is 10 instead of 32

You are executing rangeSumBST(root.left, L, R) without using result from them. And finally get only first node value. Use instead:
var rangeSumBST = function(root, L, R) {
let result = 0;
if (root === null) return 0;
if (root.val >= L && root.val <= R) {
result += root.val
}
let left = rangeSumBST(root.left, L, R)
let right = rangeSumBST(root.right, L, R)
return result + left + right;
};

Related

Why is my algorithm repeating values instead of producing 32 unique values?

I have asked a similar question before: How to get this PRNG to generate numbers within the range?
How do I take that and make it work for a number which can be up to 5 bits (32 possible values)? I tried this but it is giving "invalid" values:
const fetch = (x, o) => {
if (x >= o) {
return x
} else {
const v = (x * x) % o
return (x <= o / 2) ? v : o - v
}
}
const fetch16 = (x) => fetch(x, 65519)
const fetch8 = (x) => fetch(x, 251)
// the last number can be anything.
// MODIFIED THIS
const build32 = (x, o) => fetch8((fetch8(x) + o) % 256 ^ 101) % 32
const j = 115; // If you don't want duplicates, either i or j should stay fixed
let i = 0
let invalid = [];
let valid = new Set;
while (i <= 32) { // <-- small fix here!
let x = build32(i, j); // To test, you can swap i and j here, and run again.
if (x > 31 || valid.has(x)) {
invalid.push([i, j, x]);
} else {
valid.add(x);
}
i++;
}
console.log("invalid:", invalid);
console.log("valid:", [...valid]);
console.log("count of valid:", valid.size);
The system should iterate through the numbers 0-31 without repeating, in what seems like random order.

deobfuscate javascript with webpack 4

Is there any way to deobfuscate some javascript code that produced with webpack 4 and is also splitChunked?
It's a little more than 1MB js code and I only need to understand a small portion of the code, which is this function :
function l(e) {
t.d(8, function(e) {
for (var n = e.length, r = t.b(n), f = a(), c = 0; c < n; c++) {
var i = e.charCodeAt(c);
if (i > 127)
break;
f[r + c] = i
}
if (c !== n) {
0 !== c && (e = e.slice(c)),
r = t.c(r, n, n = c + 3 * e.length);
var d = a().subarray(r + c, r + n);
c += o(e, d).written
}
return u = c,
r
}(e), u);
var n, r, f = (null !== i && i.buffer === t.e.buffer || (i = new Int32Array(t.e.buffer)),
i), c = (n = f[2],
r = f[3],
d.decode(a().subarray(n, n + r))).slice();
return t.a(f[2], 1 * f[3]),
c
}
I used chrome debugger and set some breakpoints and I was able to grasp what it's doing but I need to do the exact same thing in my project So I need a more readable code to do that.
As far as I know, there is no easy way to do so, but I want to share some tips with you:
Replace all ',' with ', '\n'
Review and correct the possible code breaks
Use a for loop to iterate between static value arrays and replace all the usages.
Change the encoding in case of language dependent breaks
Replace all ; with ; \n and correct possible code breaks
Know it is easier to rename functions and write comments for them.

A code wars challenge

I have been struggling with this challenge and can't seem to find where I'm failing at:
Some numbers have funny properties. For example:
89 --> 8¹ + 9² = 89 * 1
695 --> 6² + 9³ + 5⁴= 1390 = 695 * 2
46288 --> 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51
Given a positive integer n written as abcd... (a, b, c, d... being digits) and a positive integer p we want to find a positive integer k, if it exists, such as the sum of the digits of n taken to the successive powers of p is equal to k * n. In other words:
Is there an integer k such as : (a ^ p + b ^ (p+1) + c ^(p+2) + d ^ (p+3) + ...) = n * k
If it is the case we will return k, if not return -1.
Note: n, p will always be given as strictly positive integers.
digPow(89, 1) should return 1 since 8¹ + 9² = 89 = 89 * 1
digPow(92, 1) should return -1 since there is no k such as 9¹ + 2² equals 92 * k
digPow(695, 2) should return 2 since 6² + 9³ + 5⁴= 1390 = 695 * 2
digPow(46288, 3) should return 51 since 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51
I'm new with javascript so there may be something off with my code but I can't find it. My whole purpose with this was learning javascript properly but now I want to find out what I'm doing wrong.I tried to convert given integer into digits by getting its modulo with 10, and dividing it with 10 using trunc to get rid of decimal parts. I tried to fill the array with these digits with their respective powers. But the test result just says I'm returning only 0.The only thing returning 0 in my code is the first part, but when I tried commenting it out, I was still returning 0.
function digPow(n, p){
// ...
var i;
var sum;
var myArray= new Array();
if(n<0)
{
return 0;
}
var holder;
holder=n;
for(i=n.length-1;i>=0;i--)
{
if(holder<10)
{
myArray[i]=holder;
break;
}
myArray[i]=holder%10;
holder=math.trunc(holder/10);
myArray[i]=math.pow(myArray[i],p+i);
sum=myArray[i]+sum;
}
if(sum%n==0)
{
return sum/n;
}
else
{
return -1;
}}
Here is the another simple solution
function digPow(n, p){
// convert the number into string
let str = String(n);
let add = 0;
// convert string into array using split()
str.split('').forEach(num=>{
add += Math.pow(Number(num) , p);
p++;
});
return (add % n) ? -1 : add/n;
}
let result = digPow(46288, 3);
console.log(result);
Mistakes
There are a few problems with your code. Here are some mistakes you've made.
number.length is invalid. The easiest way to get the length of numbers in JS is by converting it to a string, like this: n.toString().length.
Check this too: Length of Number in JavaScript
the math object should be referenced as Math, not math. (Note the capital M) So math.pow and math.trunc should be Math.pow and Math.trunc.
sum is undefined when the for loop is iterated the first time in sum=myArray[i]+sum;. Using var sum = 0; instead of var sum;.
Fixed Code
I fixed those mistakes and updated your code. Some parts have been removed--such as validating n, (the question states its strictly positive)--and other parts have been rewritten. I did some stylistic changes to make the code more readable as well.
function digPow(n, p){
var sum = 0;
var myArray = [];
var holder = n;
for (var i = n.toString().length-1; i >= 0; i--) {
myArray[i] = holder % 10;
holder = Math.trunc(holder/10);
myArray[i] = Math.pow(myArray[i],p+i);
sum += myArray[i];
}
if(sum % n == 0) {
return sum/n;
} else {
return -1;
}
}
console.log(digPow(89, 1));
console.log(digPow(92, 1));
console.log(digPow(46288, 3));
My Code
This is what I did back when I answered this question. Hope this helps.
function digPow(n, p){
var digPowSum = 0;
var temp = n;
while (temp > 0) {
digPowSum += Math.pow(temp % 10, temp.toString().length + p - 1);
temp = Math.floor(temp / 10);
}
return (digPowSum % n === 0) ? digPowSum / n : -1;
}
console.log(digPow(89, 1));
console.log(digPow(92, 1));
console.log(digPow(46288, 3));
You have multiple problems:
If n is a number it is not going to have a length property. So i is going to be undefined and your loop never runs since undefined is not greater or equal to zero
for(i=n.length-1;i>=0;i--) //could be
for(i=(""+n).length;i>=0;i--) //""+n quick way of converting to string
You never initialize sum to 0 so it is undefined and when you add the result of the power calculation to sum you will continually get NaN
var sum; //should be
var sum=0;
You have if(holder<10)...break you do not need this as the loop will end after the iteration where holder is a less than 10. Also you never do a power for it or add it to the sum. Simply remove that if all together.
Your end code would look something like:
function digPow(n, p) {
var i;
var sum=0;
var myArray = new Array();
if (n < 0) {
return 0;
}
var holder;
holder = n;
for (i = (""+n).length - 1; i >= 0; i--) {
myArray[i] = holder % 10;
holder = Math.trunc(holder / 10);
myArray[i] = Math.pow(myArray[i], p + i);
sum = myArray[i] + sum;
}
if (sum % n == 0) {
return sum / n;
} else {
return -1;
}
}
Note you could slim it down to something like
function digPow(n,p){
if( isNaN(n) || (+n)<0 || n%1!=0) return -1;
var sum = (""+n).split("").reduce( (s,num,index)=>Math.pow(num,p+index)+s,0);
return sum%n ? -1 : sum/n;
}
(""+n) simply converts to string
.split("") splits the string into an array (no need to do %10 math to get each number
.reduce( function,0) call's the array's reduce function, which calls a function for each item in the array. The function is expected to return a value each time, second argument is the starting value
(s,num,index)=>Math.pow(num,p+index+1)+s Fat Arrow function for just calling Math.pow with the right arguments and then adding it to the sum s and returning it
I have created a code that does exactly what you are looking for.The problem in your code was explained in the comment so I will not focus on that.
FIDDLE
Here is the code.
function digPow(n, p) {
var m = n;
var i, sum = 0;
var j = 0;
var l = n.toString().length;
var digits = [];
while (n >= 10) {
digits.unshift(n % 10);
n = Math.floor(n / 10);
}
digits.unshift(n);
for (i = p; i < l + p; i++) {
sum += Math.pow(digits[j], i);
j++;
}
if (sum % m == 0) {
return sum / m;
} else
return -1;
}
alert(digPow(89, 1))
Just for a variety you may do the same job functionally as follows without using any string operations.
function digPow(n,p){
var d = ~~Math.log10(n)+1; // number of digits
r = Array(d).fill()
.map(function(_,i){
var t = Math.pow(10,d-i);
return Math.pow(~~((n%t)*10/t),p+i);
})
.reduce((p,c) => p+c);
return r%n ? -1 : r/n;
}
var res = digPow(46288,3);
console.log(res);

Calculating the Modular Inverse in JavaScript

I am trying to take ed = 1 mod((p-1)(q-1)) and solve for d, just like the RSA algorithm.
e = 5, (p-1)*(q-1) = 249996
I've tried a lot of code in javascript such as:
function modInverse(){
var e = 5;
var p = 499;
var q = 503;
var d = e.modInverse((p-1) * (q-1));
DisplayResult(d, "privateKeyResultLabel")
}
or
function modInverse(){
System.out.println(BigInteger.valueOf(5).modInverse(BigInteger.valueOf(249996)));
}
I just can't figure out the correct way to solve for d, the modular inverse, in javascript.
I was just going through the definition of modular multiplicative inverse and from what I understand:
ax = 1 (mod m)
=> m is a divisor of ax -1 and x is the inverse we are looking for
=> ax - 1 = q*m (where q is some integer)
And the most important thing is gcd(a, m) = 1
i.e. a and m are co-primes
In your case:
ed = 1 mod((p-1)(q-1)) //p, q and e are given
=> ed - 1 = z*((p-1)(q-1)) //where z is some integer and we need to find d
Again from the wikipedia entry, one can compute the modular inverse using the extended Euclidean GCD Algorithm which does the following:
ax + by = g //where g = gcd(a,b) i.e. a and b are co-primes
//The extended gcd algorithm gives us the value of x and y as well.
In your case the equation would be something like this:
ed - z*((p-1)(q-1)) = 1; //Compare it with the structure given above
a -> e
x -> d
b -> (p-1)(q-1)
y -> z
So if we just apply that algorithm to this case, we will get the values of d and z.
For ax + by = gcd(a,b), the extended gcd algorithm could look something like (source):
function xgcd(a, b) {
if (b == 0) {
return [1, 0, a];
}
temp = xgcd(b, a % b);
x = temp[0];
y = temp[1];
d = temp[2];
return [y, x-y*Math.floor(a/b), d];
}
This algorithm runs in time O(log(m)^2), assuming |a| < m, and is generally more efficient than exponentiation.
I don't know if there is an inbuilt function for this in javascript. I doubt if there is, and I am a fan of algorithms, so I thought you might want to give this approach a try. You can fiddle with it and change it to handle your range of values and I hope it gets you started in the right direction.
This implementation of modular inverse can accept any type of inputs. If input types are not supported, NaN is returned. Also, it does not use recursion.
function modInverse(a, m) {
// validate inputs
[a, m] = [Number(a), Number(m)]
if (Number.isNaN(a) || Number.isNaN(m)) {
return NaN // invalid input
}
a = (a % m + m) % m
if (!a || m < 2) {
return NaN // invalid input
}
// find the gcd
const s = []
let b = m
while(b) {
[a, b] = [b, a % b]
s.push({a, b})
}
if (a !== 1) {
return NaN // inverse does not exists
}
// find the inverse
let x = 1
let y = 0
for(let i = s.length - 2; i >= 0; --i) {
[x, y] = [y, x - y * Math.floor(s[i].a / s[i].b)]
}
return (y % m + m) % m
}
// Tests
console.log(modInverse(1, 2)) // = 1
console.log(modInverse(3, 6)) // = NaN
console.log(modInverse(25, 87)) // = 7
console.log(modInverse(7, 87)) // = 25
console.log(modInverse(19, 1212393831)) // = 701912218
console.log(modInverse(31, 73714876143)) // = 45180085378
console.log(modInverse(3, 73714876143)) // = NaN
console.log(modInverse(-7, 87)) // = 62
console.log(modInverse(-25, 87)) // = 80
console.log(modInverse(0, 3)) // = NaN
console.log(modInverse(0, 0)) // = NaN

elgamal decryption in javascript

i need a way to calculate:
m = a. b ^(p-1-x) mod p
in javascript.
i have found this algorithm for calculating base^exp%mod:
function expmod(base, exp, mod){
if (exp == 0) return 1;
if (exp % 2 == 0){
return Math.pow((this.expmod(base, (exp / 2), mod)), 2) % mod;
}
else {
return (base * (this.expmod(base, (exp - 1), mod))) % mod;
}
}
and it's works great. but I can't seem to find a way to do this for
m = a. b ^(p-1-x) mod p
i'm sorry if this question not perfect. this is my first question here. thank you.
I have no experience with cryptography, but, since no one else is answering, I'll give it a shot.
Your question didn't quite make sense to me the way it was phrased, so I decided to implement a complete Elgamal in JavaScript so that I could understand your problem in context. Here's what I came up with:
// Abstract:
var Alphabet = "!\"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ \n𮃩∆";
Alphabet = Alphabet.split("");
var Crypto = function (alpha, gen, C) {
var p, B, encrypt, decrypt, f, g, modInv, modPow, toAlpha, to10;
toAlpha = function (x) {
var y, p, l, n;
if (x === 0) {
return "!!!!";
}
y = [];
n = 4;
n = Math.ceil(n);
while (n--) {
p = Math.pow(alpha.length, n);
l = Math.floor(x / p);
y.push(alpha[l]);
x -= l * p;
}
y = y.join("");
return y;
};
to10 = function (x) {
var y, p, n;
y = 0;
p = 1;
x = x.split("");
n = x.length;
while (n--) {
y += alpha.indexOf(x[n]) * p;
p *= alpha.length;
}
return y;
};
modInv = function (gen, mod) {
var v, d, u, t, c, q;
v = 1;
d = gen;
t = 1;
c = mod % gen;
u = Math.floor(mod / gen);
while (d > 1) {
q = Math.floor(d / c);
d = d % c;
v = v + q * u;
if (d) {
q = Math.floor(c / d);
c = c % d;
u = u + q * v;
}
}
return d ? v : mod - u;
};
modPow = function (base, exp, mod) {
var c, x;
if (exp === 0) {
return 1;
} else if (exp < 0) {
exp = -exp;
base = modInv(base, mod);
}
c = 1;
while (exp > 0) {
if (exp % 2 === 0) {
base = (base * base) % mod;
exp /= 2;
} else {
c = (c * base) % mod;
exp--;
}
}
return c;
};
p = 91744613;
C = parseInt(C, 10);
if (isNaN(C)) {
C = Math.round(Math.sqrt(Math.random() * Math.random()) * (p - 2) + 2);
}
B = modPow(gen, C, p);
decrypt = function (a) {
var d, x, y;
x = a[1];
y = modPow(a[0], -C, p);
d = (x * y) % p;
d = Math.round(d) % p;
return alpha[d - 2];
};
encrypt = function (key, d) {
var k, a;
k = Math.ceil(Math.sqrt(Math.random() * Math.random()) * 1E10);
d = alpha.indexOf(d) + 2;
a = [];
a[0] = modPow(key[1], k, key[0]);
a[1] = (d * modPow(key[2], k, key[0])) % key[0];
return a;
};
f = function (message, key) {
var n, x, y, w;
y = [];
message = message.split("");
n = message.length;
while (n--) {
x = encrypt(key, message[n]);
y.push(toAlpha(x[0]));
y.push(toAlpha(x[1]));
}
y = y.join("");
return y;
};
g = function (message) {
var n, m, d, x;
m = [];
n = message.length / 8;
while (n--) {
x = message[8 * n + 4];
x += message[8 * n + 5];
x += message[8 * n + 6];
x += message[8 * n + 7];
m.unshift(x);
x = message[8 * n];
x += message[8 * n + 1];
x += message[8 * n + 2];
x += message[8 * n + 3];
m.unshift(x);
}
x = [];
d = [];
n = m.length / 2;
while (n--) {
x[0] = m[2 * n];
x[1] = m[2 * n + 1];
x[0] = to10(x[0]);
x[1] = to10(x[1]);
d.push(decrypt(x));
}
message = d.join("");
return message;
};
return {
pubKey: [p, gen, B],
priKey: C,
decrypt: g,
encrypt: f
};
};
// Usage:
var Alice = Crypto(Alphabet, 69);
var Bob = Crypto(Alphabet, 69);
var message = "Hello!";
console.log(message);
// "Hello!"
message = Alice.encrypt(message, Bob.pubKey);
print(message);
// "Pl)7t&rfGueuL#|)H'P,*<K\.hxw+∆d*`?Io)lg~Adz-6xrR" or something like it.
message = Bob.decrypt(message);
console.log(message);
// "Hello!"
So, basically, Crypto handles all of the Elgamal algorithms, using modPow when it needs to. I think that the modPow function was what you were originally after, wasn't it? The version that you originally posted uses repeated squaring instead of ordinary exponentiation, presumably for purposes of performance, but they're both reasonably speedy.
It still isn't clear to me, though, why you needed a different algorithm for doing "m = a. b ^(p-1-x) mod p". I never needed anything like that in implementing my Elgamal, so I'm not sure what this corresponds to. I did need to implement a function that calculates the modular multiplicative inverse, which I called modInv. Is that what you wanted? I used a stripped-down version of the Extended Euclidean Algorithm to make it.
If it helps, feel free to copy part or all of my code for your project.
And, if you have any more questions about this, please ask me!
EDIT: Note, this code is not intended for actual production-grade encryption. It is really just a proof of concept for the algorithm. With a little work, however, it could be made more secure. Let me know.
EDIT: To encrypt and decrypt text, do the following:
Create a new Crypto object to encrypt the text, and then save it:
var Alice=Crypto(Alphabet, 69);
Here, Alice is just some variable, Alphabet is the 29-symbol alphabet that I defined at the top of the code, and 69 is a primitive root mod 91744613.
Then, create another Crypto object to decrypt the text, and then save it:
var Bob=Crypto(Alphabet, 69);
Although Bob was created in the same way as Alice, they are different objects. Bob cannot decrypt text intended for Alice, and Alice cannot decrypt text intended for Bob.
Now, use Alice's encrypt method to encrypt some text, and save the result:
var codedMessage=Alice.encrypt("HELLO, WORLD.", Bob.pubKey);
Here, message is an empty variable, "HELLO, WORLD." is the text to be encrypted (or the contents of a text file). Bob.key is Bob's public key. We must use Bob's key in the encryption so that Bob (and only Bob) can decrypt the text. The resulting encrypted text will look something like this: "Pl)7t&rfGueuL#|)H'P,*<K\.hxw+∆d*?Io)lg~Adz-6xrR"`. Note that even with the same message, different output will be generated each time. It will still always decrypt to the same value.
Now, in theory, we can send this encrypted text over whatever un-secure channel we want, and no one will be able to decode it. When Bob receives the encrypted text, however, he can decode it. To do this:
var plainMessage=Bob.decrypt(codedMessage);
Now, plainMessage will contain the text "HELLO, WORLD.", which you can read or do whatever you want with.
So, all together, just these four lines will do it:
var Alice=Crypto(Alphabet, 69);
var Bob=Crypto(Alphabet, 69);
var codedMessage=Alice.encrypt("HELLO, WORLD.", Bob.pubKey);
var plainMessage=Bob.decrypt(codedMessage);
// Now, plainMessage contains "HELLO, WORLD."
If you specifically want to do this with text files, then you can either copy-and-paste the contents into the javascript, or you can look into loading the contents of a text file into javascript. To get started, see this SO, and this HG.

Categories

Resources