What is the difference between javascript and python Fibonacci code here? - javascript

I'm currently using matrix multiplication formulas to create algorithms for Fibonacci sequences.
I made my JavaScript code based on the following python code. However, it was confirmed that another value was output [case fib(150)]. I think the % mod is wrong, but how can I solve this problem?
javascript code
const n = parseInt(prompt("Number"));
const mod = 1000000007;
const fib = () => {
const zero = [
[1, 1],
[1, 0],
];
const base = [
[1],
[1]
];
const power = (a, num) => {
if (num === 1) return a;
else if (num % 2 != 0) return multi(power(a, num - 1), a);
else return power(multi(a, a), parseInt(num / 2));
};
const multi = (a, b) => {
const temp = Array.from(Array(2), () => Array(b[0].length).fill(0));
for (let i = 0; i < 2; i++) {
for (let j = 0; j < b[0].length; j++) {
let sum_num = 0;
for (let k = 0; k < 2; k++) {
sum_num += a[i][k] * b[k][j];
}
temp[i][j] = sum_num % mod;
}
}
return temp;
};
return multi(power(zero, n - 2), base)[0][0];
};
if (n === 0) {
console.log(0);
} else if (n < 3) {
console.log(1);
} else {
console.log(fib());
}
python code
import sys
input = sys.stdin.readline
MOD = 1000000007
adj=[[1,1],[1,0]]
start=[[1],[1]]
N = int(input())
def power(adj,n):
if n == 1:
return adj
elif n % 2:
return multi(power(adj,n-1), adj)
else:
return power(multi(adj,adj), n//2)
def multi(a,b):
temp=[[0]*len(b[0]) for _ in range(2)]
for i in range(2):
for j in range(len(b[0])):
sum_n = 0
for k in range(2):
sum_n += a[i][k]*b[k][j]
temp[i][j]= sum_n % MOD
return temp
if N < 3:
print(1)
else:
print(multi(power(adj,N-2),start)[0][0])

I solved it using bigint. Thank you for your help. (mplungjan, Kelly Bundy)
const n = BigInt(prompt('Number'));
const mod = 1000000007n;
const fib = () => {
const zero = [
[1n, 1n],
[1n, 0n],
];
const base = [[1n], [1n]];
const power = (a, num) => {
if (num === 1n) return a;
else if (num % 2n != 0) return multi(power(a, num - 1n), a);
else return power(multi(a, a), BigInt(num / 2n));
};
const multi = (a, b) => {
const temp = Array.from(Array(2), () => Array(b[0].length).fill(0));
for (let i = 0; i < 2; i++) {
for (let j = 0; j < b[0].length; j++) {
let sum_num = 0n;
for (let k = 0; k < 2; k++) {
sum_num += a[i][k] * b[k][j];
}
temp[i][j] = sum_num % mod;
}
}
return temp;
};
return multi(power(zero, n - 2n), base)[0][0];
};
if (n === 0) {
console.log(0);
} else if (n < 3) {
console.log(1);
} else {
console.log(parseInt(fib()));
}

Related

Two Sum Leetcode

I wrote the code, but for some reason it displays the index 1, 2, 3, while 3 + 4 will in no way be equal to target (6).
var twoSum = function(nums, target) {
let sum = [];
var n = 2;
for(let i = 0; i < nums.length; i++) {
for(let a = 1; a < nums.length; a++) {
if(nums[i] + nums[a] == target) {
sum.push(i);
sum.push(a);
}
}
}
let unique = sum.filter((e, i) => sum.indexOf(e) === i )
return unique/* .slice(0, n); */
};
console.log(twoSum([1,3,4,2],6))
Input
[1,3,4,2]
6
Output
[1,2]
Expected
[2,3]
As per my comment, start the inner loop at a = i + 1 to avoid summing numbers with themselves as well as to avoid checking the same combination twice, e.g (1, 2) and (2, 1):
var twoSum = function(nums, target) {
let sum = [];
let n = 2;
for (let i = 0; i < nums.length; i++) {
for (let a = i + 1; a < nums.length; a++) {
if (nums[i] + nums[a] === target) {
sum.push(i);
sum.push(a);
}
}
}
let unique = sum.filter((e, i) => sum.indexOf(e) === i )
return unique/* .slice(0, n); */
};

Javascript : How to retrieve initial value after permutation

Starting with a 6-digits value (i.e "123456") and a [0->9] table, this script (but many other exist...) procuces the 123456th permutation of the table :
let tabl10 = [0,1,2,3,4,5,6,7,8,9],
permut = permutation( 123456 , tabl10 )
console.log(permut) // 0,4,1,6,5,9,2,3,7,8
function permutation(n,a) {
let f, k = [], l = a.length;
a = a.slice();
while (l--) {
f = factorial(l);
k.push(Math.floor(n / f));
n %= f;
}
return k.map(function (i) {
return a.splice(i, 1)[0];
});
}
function factorial(n) {
let r = 1;
while (n) {
r *= n;
n--;
}
return r;
}
My question is : is it possible to retrieve "123456" from the "0,4,1,6,5,9,2,3,7,8" permutation ?
We have 10! (3.6288 million) of possibles permutations and trying all of them one by one till we find the 123456th is painfull: it is possible to explore all permutations and retrieve the nth with a 7-digits table [0,1,2,3,4,5,6]: 7!=5040, but a 8-digits (40320) or higher definively freezes browsers. How to achieve this ?
In a Lehmer code for a permutation perm, the i-th number is the number of the elements on the right of i that are less than perm[i]. So, given a permutation, you can compute its LC first, and then convert the LC from the factorial system to an int, which gives you the index of the permutation.
Complete code:
// int => LC
function int2lc(n, len) {
let lc = []
for (let i = 1; i <= len; i++) {
lc[len - i] = (n % i)
n = (n / i) | 0
}
return lc
}
// LC => int
function lc2int(lc, len) {
let n = 0, f = 1
for (let i = 1; i <= len; i++) {
n += lc[len - i] * f
f *= i
}
return n
}
// LC => permutation
function lc2perm(a, lc) {
let perm = [], copy = [...a]
for (let i = 0; i < lc.length; i++) {
perm[i] = copy[lc[i]]
copy.splice(lc[i], 1)
}
return perm
}
// permutation => LC
function perm2lc(perm) {
let lc = []
for (let i = 0; i < perm.length; i++) {
let c = 0
for (let k = i + 1; k < perm.length; k++)
c += perm[k] < perm[i]
lc[i] = c
}
return lc
}
//
A = [0,1,2,3,4,5,6,7,8,9]
// index to perm
N = 123456
lc = int2lc(N, A.length)
console.log('LEHMER', ...lc)
perm = lc2perm(A, lc)
console.log('PERMUT', ...perm)
// perm to index
lc2 = perm2lc(perm)
console.log('LEHMER', ...lc2)
M = lc2int(lc2, A.length)
console.log('INDEX ', M)

Precision of BigInt JavaScript type

I have such part of code, where s1 is a correct binary number (string, up to 900 characters):
console.log(BigInt('0b' + s1));
console.log(toLong10(s1));
25153017620665555630531113...
25153017620663410729799174...
These two functions give different results. Which of them is more likely to be wrong: does BigInt really lose so much precision or is it more realistic that I have a mistake in my function?
function summarize(a, b)
{
while(b.length < a.length)
b = "0" + b;
while(a.length < b.length)
a = "0" + a;
a = "0" + a;
b = "0" + b;
let extra = 0;
let i = a.length - 1;
let res = "";
while (i >= 0)
{
let tmp = Number(a[i]) + Number(b[i]) + extra;
extra = Math.floor(tmp / 10);
tmp = tmp % 10;
res = tmp.toString() + res;
i--;
}
if (res[0] == '0')
{
res = res.substr(1);
}
return(res);
}
function multiply2(a, b)
{
a = "0" + a;
let res = "";
let extra = 0;
for (let i = a.length - 1; i >= 0; i--)
{
let tmp = b * a[i] + extra;
extra = Math.floor(tmp / 10);
tmp = tmp % 10;
res = tmp.toString() + res;
}
if (res[0] == '0')
{
res = res.substr(1);
}
return(res);
}
function multiply(a, b)
{
let res = "0";
if (b.length > a.length)
{
let c = a;
a = b;
b = c;
}
let extra0 = "";
for (let i = b.length - 1; i >= 0; i--)
{
res = summarize(res, multiply2(a, b[i]) + extra0);
extra0 = extra0 + "0";
}
if (res[0] == '0')
{
res = res.substr(1);
}
return(res);
}
function toPower(num, power)
{
let res = "1";
if (power == 0)
return(res);
res = toPower(num, Math.floor(power / 2));
if (power % 2 == 0)
return(multiply(res, res));
else
return(multiply(multiply(res, res), num));
}
function toLong10(a)
{
a = a.split("").reverse().join("");
let res = "0";
let power = 0;
for (let i = 0; i < a.length; i++)
{
res = summarize(res, multiply(a[i], toPower("2", power)));
power++;
}
return(res);
}

Is this Quick Sort Logic Correct?

I have tried to implement Quick-Sort in Javascript without any reference to psuedo Code. Is this correct implementation? if not how can i improve on it.
const quickSort = (arr = []) => {
const length = arr.length;
if (length === 0 || length === 1) {
return arr;
}
const pivot = arr[0];
const leftArray = [];
const rightArray = [];
for (let i = 1; i < length; i++) {
if (arr[i] < pivot) {
leftArray.push(arr[i]);
} else {
rightArray.push(arr[i]);
}
}
return [...quickSort(leftArray), pivot, ...quickSort(rightArray)];
};
console.log(quickSort([2, 45, 6, 7, 8, 1]));
I have added code of test case and executed it over 250000 times.
// Function to generate random array.
const generateRandomArray = n =>
Array.from({
length: n
}, () => Math.floor(Math.random() * n));
// Function to check whether array is sorted.
const checkSorted = (arr = []) => {
let sorted = true;
for (let i = 1; i < arr.length; i++) {
if (arr[i] < arr[i - 1]) {
sorted = false;
break;
}
}
return sorted;
};
// Testing Quick-Sort
const testQuickSort = () => {
for (let i = 1; true; i++) {
const sortedArray = quickSort(generateRandomArray(Date.now() % 100000));
const isSorted = checkSorted(sortedArray);
if (!isSorted) {
console.log("error");
break;
}
console.log("pass", i);
}
};
testQuickSort();
You can try the following Solution
function pivot(arr, start = 0, end = arr.length - 1) {
const swap = (arr, idx1, idx2) => {
[arr[idx1], arr[idx2]] = [arr[idx2], arr[idx1]];
};
// We are assuming the pivot is always the first element
let pivot = arr[start];
let swapIdx = start;
for (let i = start + 1; i <= end; i++) {
if (pivot > arr[i]) {
swapIdx++;
swap(arr, swapIdx, i);
}
}
// Swap the pivot from the start the swapPoint
swap(arr, start, swapIdx);
return swapIdx;
}
function quickSort(arr, left = 0, right = arr.length -1){
if(left < right){
let pivotIndex = pivot(arr, left, right) //3
//left
quickSort(arr,left,pivotIndex-1);
//right
quickSort(arr,pivotIndex+1,right);
}
return arr;
}
console.log(quickSort([100,-3,2,4,6,9,1,2,5,3,23]));

Return array with factorial number from another array

This function will receive an array of positive integers and it should return a new array with the factorial of each number.
So far I came up with this but it doesn't work and I don't know where is the problem, any ideas?
function getFactorials (nums) {
let arr = [];
for(let i = 0; i < nums.length; i++) {
if(nums[i] <= 1) {
return 1;
} else {
arr.push(nums[i] * getFactorials(nums[i] - 1));
}
}
return arr;
}
try this use map
var a = [1, 2, 3, 4, 5];
function fact(x) {
return (x == 0) ? 1 : x * fact(x-1);
}
console.log(a.map(fact));
Try the following:
function getFactorials (nums) {
let arr = [];
for(let i = 0; i < nums.length; i++) {
let j, fact;
fact=1;
for(let j=1; j<=nums[i]; j++)
{
fact= fact*j;
}
arr.push(fact);
}
return arr;
}
let res = getFactorials([5,9])
console.log(res);
Try this way:
function factorial(n) {
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
function getFactorials (nums) {
let arr = [];
for(let i = 0; i < nums.length; i++) {
arr.push(factorial(nums[i]));
}
return arr;
}
getFactorials([6,5,3])
const factorial = (n) => {
let res = [];
while(n != 0){
//get all integers less than or equal to n
res.push(n);
n--;
}
return res.reduce((x, y) => {
return x * y;
//reduce the array of integers into a single number via multiplication
});
}
const nums = [1, 2, 3, 4, 5];
const factorialArr = (arr) => {
return arr.map(n => {
//iterate through a list of numbers and return the factorial of each
return factorial(n);
});
}
const result = factorialArr(nums);
console.log(result) -> // Array [ 1, 2, 6, 24, 120 ]
function getFactorials(nums) {
const factNums = nums.map(
function factorial (num) {
return (num == 0 ? 1 : num * factorial(num -1));
}
)
return factNums;
}
#include <stdio.h>
int iFactorial(int iCount)
{
int iProduct = 1;
int iNumber = 1;
while (iNumber <= iCount)
{
iProduct *= iNumber;
iNumber++;
}
return iProduct;
}
int main(void)
{
int iFac[10] = {0};
int iCount = 0;
for (iCount = 0; iCount < 9; iCount++)
iFac[iCount] = iFactorial(iCount);
for (iCount = 0; iCount < 9; iCount++)
printf("\nThe value of the factorial is %d\n", iFac[iCount]);
return 0;
}

Categories

Resources