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()));
}
I created one function with JavaScript which compare two string and return the number of the same characters with the following logic:
Char 1 = “aaabc” | Char 2 = “aakbc” ===> My function return 2
Char 2 = “88835” | Char 2 = “888vbr” ===> My function return 3
Char 1 = “A1234” | Char 2 = “B1234” ===> My function return 0
The logic is that when the function find that the FIRST character of CHAR1 is DIFFERENT is NOT EQUAL than the FIRST character of CHAR2 the function stop the iteration and return 0, if not: the function continue until we find that the CHAR1(i) !== CHAR2(i).
I am using this function to compare between two array of string, T[i] and V[j]. For each value of T[i] I am browsing all V[j] and returning the row which is more similar that T[i] and if the function find same result, I will return the smallest value V[j].
This is the code that I used:
function MyFunction(a, b) {
var n = a.length,
m = b.length;
var v;
var i = 1;
var j = 1;
if (a === b) {
v = a.length;
} else
if (a.charCodeAt(0) !== b.charCodeAt(0)) {
v = 0;
} else {
v = 1;
for (i = 1; i < n; i++) {
if (a.charCodeAt(i) == b.charCodeAt(i)) {
v++;
} else {
return v;
}
}
}
return v;
}
var t = ["350", "840", "35"],
v = ["3506", "35077", "84"],
i, j, f, l,
max,
result = [],
row = [];
for (i = 0; i < t.length; i++) {
max = MyFunction(v[0], t[i]);
l = v[0].length;
f = [
[t[0]],
[v[0]]
];
for (j = 1; j < v.length; j++) {
if (MyFunction(v[j], t[i]) > max) {
max = MyFunction(v[j], t[i]);
f = [
[t[i]],
[v[j]]
];
l = v[j].length;
} else {
if (MyFunction(v[j], t[i]) == max && l > v[j].length) {
max = MyFunction(v[j], t[i]);
f = [
[t[i]],
[v[j]]
];
l = v[j].length;
} else {
continue;
}
}
}
result.push(f);
console.log(f);
}
My code have an issue, the result which I have is:
[350][3506] (Correct value)
[840][84] (Correct value)
[350][3506] (Wrong value)
I don’t find a solution for this issue, my code don’t compare the value [35], the code is comparing the first value [350] (this is the issue).
In each loop of the outer for you start with initialize max to MyFunction(v[0], t[i]), and then scan-compare all the elements in the array. but, in the 3rd case, the resault of this check larger than al the other, so all the comparison in this loop get false and the final resault is what you see.
you can solve it if you initialize max = 0 and then loop over all indices from 0 (include).
To shuffle a string, I could use something like this
String.prototype.shuffle = function () {
var arr = this.split("");
var len = arr.length;
for (var n = len - 1; n > 0; n--) {
m = Math.floor(Math.random() * (n + 1));
tmp = arr[n];
arr[n] = arr[m];
arr[m] = tmp;
}
return arr.join("");
}
But how could I randomly space it with n characters, while preserving the string order?
For example:
"test" => "t-es--t"
"test" => "-t-e-st"
"test" => "te--st-"
I've thought about creating a list from the string, generating a random number to represent an index, and then shifting the list to the left, but is there a better way to do this?
This will insert n characters char randomly into the string. If char is missing, it defaults to a space:
String.prototype.shuffle = function(n, char) {
var arr = this.split(''),
char= char || ' ';
while(n--) {
arr.splice(Math.floor(Math.random() * (arr.length+1)), 0, char);
}
return arr.join('');
} //shuffle
This Fiddle shows the relative random distribution using the method.
If you want a truly unbiased solution that produces all possibilities equally likely, and have access to a perfect random number generator (which is a whole other topic), there's a fairly easy solution. Let's define some terms:
m = number of characters in the string
k = number of spaces you want to insert (you called this n)
Consider one solution to this problem with m=7 and k=3:
0123456789
cab ba g e
What the problem essentially amounts to is choosing k different numbers from among a set of m+k numbers. There are (m+k)!/(m!*k!) possibilities. This is the concept of combinations and is similar to the stars-and-bars problem in the Wikipedia page. (To get an unbiased generator you would need a random number generator with the number of state values much higher than this number of possibilities. But I said RNGs are a whole other topic.)
Here's an example in Python showing all possibilities:
import itertools
def show_all(s, k):
# show all combinations of k spaces inserted into string s
m = len(s)
for sample in itertools.combinations(range(m+k),k):
jprev = 0
out = ''
for ispace, i in enumerate(sample):
j = i-ispace # adjust index by number of spaces used
out += s[jprev:j] + ' '
jprev = j
out += s[jprev:]
yield sample, out
for sample, out in show_all('shoe',2):
print sample,':'+out+':'
output:
(0, 1) : shoe:
(0, 2) : s hoe:
(0, 3) : sh oe:
(0, 4) : sho e:
(0, 5) : shoe :
(1, 2) :s hoe:
(1, 3) :s h oe:
(1, 4) :s ho e:
(1, 5) :s hoe :
(2, 3) :sh oe:
(2, 4) :sh o e:
(2, 5) :sh oe :
(3, 4) :sho e:
(3, 5) :sho e :
(4, 5) :shoe :
Now the problem becomes one of generating a random combination. In Python this is part of the itertools recipes:
def random_combination_with_replacement(iterable, r):
"Random selection from itertools.combinations_with_replacement(iterable, r)"
pool = tuple(iterable)
n = len(pool)
indices = sorted(random.randrange(n) for i in xrange(r))
return tuple(pool[i] for i in indices))
In Javascript we have to implement this ourselves, which we can do using Robert Floyd's algorithm for sampling without replacement:
pseudocode:
initialize set S to empty
for J := N-M + 1 to N do
T := RandInt(1, J)
if T is not in S then
insert T in S
else
insert J in S
Javascript:
function random_comb(r, n, m)
{
/* Generate a combination of m distinct random integers between 0 and n-1
using Floyd's algorithm
r: random generation function
such that r(k) generates an integer in the range [0, k-1]
*/
var S = {};
var out = [];
for (var i = 0; i < m; ++i)
{
var j = i+(n-m);
var t = r(j+1);
var item = (t in S) ? j : t;
S[item] = 1;
out.push(item);
}
return out.sort();
}
Now let's put it all together, ignoring the fact that Math.random() is inadequate:
var r = function(n) { return Math.floor(Math.random()*n); }
function random_comb(r, n, m)
{
/* Generate a combination of m distinct random integers between 0 and n-1
using Floyd's algorithm
r: random generation function
such that r(k) generates an integer in the range [0, k-1]
*/
var S = {};
var out = [];
for (var i = 0; i < m; ++i)
{
var j = i+(n-m);
var t = r(j+1);
var item = (t in S) ? j : t;
S[item] = 1;
out.push(item);
}
return out.sort();
}
function random_insert(r, s, k, c)
{
/* randomly insert k instances of character c into string s */
var m = s.length;
var S = random_comb(r, m+k, k);
var jprev = 0;
var out = '';
for (var ispace = 0; ispace < k; ++ispace)
{
var i = S[ispace];
var j = i - ispace; // adjust index by # of spaces
out += s.slice(jprev,j) + c;
jprev = j;
}
out += s.slice(jprev);
return out;
}
var word = 'shoe';
var results = [];
for (var i = 0; i < 10; ++i)
{
results.push(random_insert(r,word, 2, '-'));
}
var tally = {};
for (var i = 0; i < 100000; ++i)
{
var s = random_insert(r,word,2,'-');
tally[s] = (s in tally) ? (tally[s] + 1) : 1;
}
for (var s in tally)
{
results.push(s+": "+tally[s]);
}
for (var i = 0; i < results.length; ++i)
{
$("#results").append(results[i]+'<br>');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="results"></div>
Working jsFiddle
Even though I loved #Barmar 's idea..
You can do it by simply looping and randomizing positions to insert the spaces..
String.prototype.insertSpaces = function (n, char) {
var str = this;
for(var i = 0; i < n; i++){
var randPos = Math.floor(Math.random() * (str.length + 1)); // get random index to insert
str = str.substring(0, randPos) + char + str.substring(randPos, str.legnth); // insert the repeated sting
}
return str;
}
function addRandomSpaces(str,n,char){
for (var newstr="", i=0; i<str.length;){
if (n && Math.random()<0.5) {
newstr += char;
n--;
} else {
newstr += str[i++];
}
}
while(n--){
newstr += char;
}
return newstr;
}
Here's a function that will loop through a given string str, adding n instances of char at random places. If when it finishes, n items haven't been added, it adds finishes them at the end.
You can use the slice function insert the new character:
var x = "this is phrase";
var y = " a";
[x.slice(0,7), y, x.slice(7)].join('');
Result: this is a phrase
Something like this:
String.prototype.shuffle2 = function() {
'use strict';
var numberOfSpaces = Math.floor(Math.random() * (this.length - 1));
var word = this;
for (var i = 0; i < numberOfSpaces; i++) {
var index = Math.floor(Math.random() * (this.length - 1));
word = [word.slice(0,index), '-', word.slice(index)].join('');
}
return word;
};
Greetings!
String.prototype.addspace = function () {
var arr = this.split("");
var len = arr.length;
maxSp = 4;
for(var i = 0; i <= len; i++){
m = Math.floor(Math.random() * (maxSp + 1));
for(var j = 0; j < m ; j++){
arr.splice(i,0," ");
}
len += m;
i +=m;
}
return arr.join("");
}
alert("Juanito".addspace().shuffle());
What is a fast and simple implementation of interleave:
console.log( interleave([1,2,3,4,5,6] ,2) ); // [1,4,2,5,3,6]
console.log( interleave([1,2,3,4,5,6,7,8] ,2) ); // [1,5,2,6,3,7,4,8]
console.log( interleave([1,2,3,4,5,6] ,3) ); // [1,3,5,2,4,6]
console.log( interleave([1,2,3,4,5,6,7,8,9],3) ); // [1,4,7,2,5,8,3,6,9]
This mimics taking the array and splitting it into n equal parts, and then shifting items off the front of each partial array in sequence. (n=2 simulates a perfect halving and single shuffle of a deck of cards.)
I don't much care exactly what happens when the number of items in the array is not evenly divisible by n. Reasonable answers might either interleave the leftovers, or even "punt" and throw them all onto the end.
function interleave( deck, step ) {
var copyDeck = deck.slice(),
stop = Math.floor(copyDeck.length/step),
newDeck = [];
for (var i=0; i<step; i++) {
for (var j=0; j<stop; j++) {
newDeck[i + (j*step)] = copyDeck.shift();
}
}
if(copyDeck.length>0) {
newDeck = newDeck.concat(copyDeck);
}
return newDeck;
}
It could be done with a counter instead of shift()
function interleave( deck, step ) {
var len = deck.length,
stop = Math.floor(len/step),
newDeck = [],
cnt=0;
for (var i=0; i<step; i++) {
for (var j=0; j<stop; j++) {
newDeck[i + (j*step)] = deck[cnt++];
}
}
if(cnt<len) {
newDeck = newDeck.concat(deck.slice(cnt,len));
}
return newDeck;
}
And instead of appending the extras to the end, we can use ceil and exit when we run out
function interleave( deck, step ) {
var copyDeck = deck.slice(),
stop = Math.ceil(copyDeck.length/step),
newDeck = [];
for (var i=0; i<step; i++) {
for (var j=0; j<stop && copyDeck.length>0; j++) {
newDeck[i + (j*step)] = copyDeck.shift();
}
}
return newDeck;
}
can i has prize? :-D
function interleave(a, n) {
var i, d = a.length + 1, r = [];
for (i = 0; i < a.length; i++) {
r[i] = a[Math.floor(i * d / n % a.length)];
}
return r;
}
according to my tests r.push(... is faster than r[i] = ... so do with that as you like..
note this only works consistently with sets perfectly divisible by n, here is the most optimized version i can come up with:
function interleave(a, n) {
var i, d = (a.length + 1) / n, r = [a[0]];
for (i = 1; i < a.length; i++) {
r.push(a[Math.floor(i * d) % a.length]);
}
return r;
}
O(n-1), can anyone come up with a log version? to the mathmobile! [spinning mathman logo]
Without for loops (I've added some checkup for the equal blocks):
function interleave(arr, blocks)
{
var len = arr.length / blocks, ret = [], i = 0;
if (len % 1 != 0) return false;
while(arr.length>0)
{
ret.push(arr.splice(i, 1)[0]);
i += (len-1);
if (i>arr.length-1) {i = 0; len--;}
}
return ret;
}
alert(interleave([1,2,3,4,5,6,7,8], 2));
And playground :) http://jsfiddle.net/7tC9F/
how about functional with recursion:
function interleave(a, n) {
function f(a1, d) {
var next = a1.length && f(a1.slice(d), d);
a1.length = Math.min(a1.length, d);
return function(a2) {
if (!a1.length) {
return false;
}
a2.push(a1.shift());
if (next) {
next(a2);
}
return true;
};
}
var r = [], x = f(a, Math.ceil(a.length / n));
while (x(r)) {}
return r;
}
Phrogz was pretty close, but it didn't interleave properly. This is based on that effort:
function interleave(items, parts) {
var len = items.length;
var step = len/parts | 0;
var result = [];
for (var i=0, j; i<step; ++i) {
j = i
while (j < len) {
result.push(items[j]);
j += step;
}
}
return result;
}
interleave([0,1,2,3], 2); // 0,2,1,3
interleave([0,1,2,3,4,5,6,7,8,9,10,11], 2) // 0,6,1,7,2,8,3,9,4,10,5,11
interleave([0,1,2,3,4,5,6,7,8,9,10,11], 3) // 0,4,8,1,5,9,2,6,10,3,7,11
interleave([0,1,2,3,4,5,6,7,8,9,10,11], 4) // 0,3,6,9,1,4,7,10,2,5,8,11
interleave([0,1,2,3,4,5,6,7,8,9,10,11], 5) // 0,2,4,6,8,10,1,3,5,7,9,11
Since I've been pushed to add my own answer early (edited to fix bugs noted by RobG):
function interleave(items,parts){
var stride = Math.ceil( items.length / parts ) || 1;
var result = [], len=items.length;
for (var i=0;i<stride;++i){
for (var j=i;j<len;j+=stride){
result.push(items[j]);
}
}
return result;
}
try this one:
function interleave(deck, base){
var subdecks = [];
for(count = 0; count < base; count++){
subdecks[count] = [];
}
for(var count = 0, subdeck = 0; count < deck.length; count++){
subdecks[subdeck].push(deck[count]);
subdeck = subdeck == base - 1? 0 : subdeck + 1;
}
var newDeck = [];
for(count = 0; count < base; count++){
newDeck = newDeck.concat(subdecks[count]);
}
return newDeck;
}