A non-repeating pseudo random number generator in JavaScript - javascript

I want to generate 6-digit numeric coupon codes in JavaScript.
I'd like to use something like Preshing's algorithm.
This is what I have so far,
const p = 1000003;
function permuteQPR(x) {
const residue = x * x % p;
return (x <= p/2) ? residue : p - residue;
}
function next() {
return permuteQPR(
(permuteQPR(m_index++) + m_intermediateOffset) ^ 0x5bf03635
);
};
const seedBase = 123456;
const seedOffset = 44;
m_index = permuteQPR(permuteQPR(seedBase) + 0x682f0161);
m_intermediateOffset = permuteQPR(
permuteQPR(seedOffset) + 0x46790905
);
for (i = 0; i < 20; i++) {
document.body.innerHTML += ('000000' + next()).substr(-6) + "<br>";
}
There is also a jsfiddle.

This one works and is unique:
const p = 1000003;
const seed1 = 123456;
const seed2 = 123457;
function calculateResidue(x) {
const residue = x * x % p;
return (x <= p/2) ? residue : p - residue;
}
function valueForIndex(index) {
const first = calculateResidue((index + seed1) % p);
return result = calculateResidue((first + seed2) % p);
};
let codes = [];
for(i=0;i<1000000;i++) {
const code = valueForIndex(i);
if(codes.indexOf(code)==-1) codes.push(code);
};
document.body.innerHTML += "Unique codes: " + codes.length;

Related

How do I join this numbers together?

function expandedForm(num) {
let len = num.toString().length;
let n = num.toString().split("");
let result = "";
for (let i = 0; i < len; i++) {
result += n[i] + "0".repeat(len -1 -i).join(" + ");
}
return result;
}
What I am trying to do is to separate numbers like this:
1220 = "1000 + 200 + 20"
221 = "200 + 20 + 1"
I have written the code (not the perfect one) where it gets me all the necessary values but I struggle with joining them together with "+". I tried using .join() but it did not work.
.join works on arrays only
function expandedForm(num) {
let len = num.toString().length;
let n = num.toString().split("");
let result = "";
let arr=[];
for (let i = 0; i < len; i++) {
arr[i] = n[i] + '0'.repeat(len-1-i);
console.log(arr[i]);
}
let ans=arr.join('+');
return ans;
}
console.log(expandedForm(1220))
Although there are a variety of approaches, here are some general tips for you:
Probably don't want to output a 0 term unless the input number is exactly 0 (only a leading 0 term is relevant, because it will be the only such term)
str.split('') can also be [...str]
No need to split a string into an array to access a character str.split('')[0] can also be just str[0]
Might want to assert that num is a whole number.
Make sure you provide enough test cases in your question to fully define the behaviour of your function. (How to handle trailing zeros, interstitial zeros, leading zeros, etc. Whether the input can be a string.)
function expandedForm(num) {
const s = num.toString();
const n = s.length - 1;
const result = [...s]
.map((char, index) => char + '0'.repeat(n - index))
.filter((str, index) => !index || +str)
.join(' + ');
return result;
}
console.log(expandedForm(1220));
console.log(expandedForm(221));
console.log(expandedForm(10203));
console.log(expandedForm(0));
console.log(expandedForm(2n**64n));
Join works with an array, not string. It stringifies two subsequent indexes for all indexes and you can decide what to add between them.
function expandedForm(num) { // num = 321
let len = num.toString().length; // len = 3
let n = num.toString().split(""); // [3,2,1]
let result = [];
for (let i = 0; i < len; i++) {
result.push(n[i] + "0".repeat(len -1 -i)); // pushing till result = ['300','20','10']
}
return num + ' = ' + result.join(' + ');
// connection result[0] + ' + ' result[1] + ' + ' result[2]
}
expandedForm(321); // output: "321 = 300 + 20 + 1"
Here's one way of doing it
let num = 221;
function expandedForm(num) {
let len = num.toString().length;
let n = num.toString().split("");
let result = "";
for (let i = 0; i < len; i++) {
let t = "0"
t = t.repeat(len-1-i)
if(result.length > 0){
n[i] !== '0'? result += '+'+ n[i] + t : result
} else {
n[i] !== '0'? result += n[i] + t : result
}
}
return result;
}
console.log(expandedForm(2200))
console.log(expandedForm(num))
below would be my approach in a more mathimatical but clean code that you can adjust to your needs.
let result = parseInt(num / 1000);
return result ;
}
function x100( num ) {
num = num % 1000;
let result = parseInt( num / 100);
return result;
}
function x10(num ) {
num = num % 1000;
num = num % 100;
let result = parseInt(num /10);
return result;
}
function x1( num ) {
num = num % 1000;
num = num % 100;
num = num % 10;
return num
}
num = 12150
console.log(num = `1000 x ${x1000(num)}, 100 x ${x100(num)}, 10 x ${x10(num)}`)```

javascript pyramid within array

I need my output to look like this:
The best I could achieve was that:
Here is my code:
let pyramidComplete = (rows) => {
let array = [];
let str = '';
for (let i = 1; i <= rows; i++) {
//Add the white space to the left
for (let k = 1; k <= (rows - i); k++) {
str += ' ';
}
//Add the '*' for each row
for (let j = 0; j != (2 * i - 1); j++) {
str += "#".repeat(2 * i - 1);
}
//Add the white space to the right
for (let k = i + 1; k <= rows; k++) {
str += ' ';
}
//Print the pyramid pattern for each row
array.push(str)
str = '';
}
}
pyramidComplete(5);
I thought of assembling a line per loop and then, pushing it into an array but, I can't get the desired result.
The logic is fairly direct: for each row, the number of whitespaces is n - i - 1 where i is the row number. The number of # per row is i + 1. You can produce these substrings using String#repeat. Concatenate the two chunks together per line and use the index argument to Array#map's callback to produce each row.
const pyramid = n => Array(n).fill().map((_, i) =>
" ".repeat(n - i - 1) + "#".repeat(i + 1)
);
console.log(pyramid(5));
If the functions used here are incomprehensible, this can be simplified to use rudimentary language features as follows. It's similar to your approach, but the counts for each character per row are different, I iterate from 0 < n rather than 1 <= n and str should be scoped to the outer loop block.
function pyramid (n) {
var result = [];
for (var i = 0; i < n; i++) {
var line = "";
for (var j = 0; j < n - i - 1; j++) {
line += " ";
}
for (var j = 0; j < i + 1; j++) {
line += "#";
}
result.push(line);
}
return result;
}
console.log(pyramid(5));
If you need a true pyramid (which your current output seems to be shooting for, contrary to the expected output):
const pyramid = n => Array(n).fill().map((_, i) => {
const size = i * 2 + 1;
const pad = n - size / 2;
return " ".repeat(pad) + "#".repeat(size) + " ".repeat(pad);
});
console.log(pyramid(5));
I think you want to do this:
let doc, htm, bod, nav, M, I, mobile, S, Q, CharPyr; // for use on other loads
addEventListener('load', ()=>{
doc = document; htm = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
mobile = nav.userAgent.match(/Mobi/i) ? true : false;
S = (selector, within)=>{
var w = within || doc;
return w.querySelector(selector);
}
Q = (selector, within)=>{
var w = within || doc;
return w.querySelectorAll(selector);
}
CharPyr = function(char = '#', className = 'pyr'){
this.char = char; this.className = className;
this.build = (height = 9)=>{
const p = M('div');
p.className = this.className;
for(let i=0,c=this.char,x=c,d; i<height; i++){
d = M('div'); d.textContent = x; p.appendChild(d); x += c;
}
return p;
}
}
// magic happens here
const out1 = I('out1'), out2 = I('out2'), out3 = I('out3'), pyr = new CharPyr;
out1.appendChild(pyr.build(5)); out2.appendChild(pyr.build(7)); out3.appendChild(pyr.build());
}); // end load
*{
box-sizing:border-box;
}
.out{
margin-bottom:7px;
}
.pyr>div{
color:#070; text-align:center;
}
<div class='out' id='out1'></div>
<div class='out' id='out2'></div>
<div class='out' id='out3'></div>

returning equation with all possible parenthesis combinations and the result of each

On a recent interview, I was asked to return all possible combinations of order of operations on an input string, and the result. you should return all the ways/combinations in which you can "force" operations with parenthesis. I got the result (right hand side of the equation) but got stuck on the left side. how could I have done the left side and the right hand side together? Seems like two problems in one...
//input:
console.log(diffWaysToCompute("2 * 3 - 4 * 5"));
//output:
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10
'use strict'
function getNumbersAndOperators(str) {
var arr = str.split(" ");
var operators = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] === "-" || arr[i] === "*" || arr[i] === "+") {
operators.push(arr[i]);
arr.splice(i, 1);
// console.log(operators);
}
}
return [arr, operators];
}
// console.log(getNumbersAndOperators("2 - 1 - 1"))
var diffWaysToCompute = function (input) {
// var numbers = input.split(" ");
// console.log(numbers);
// // console.log(number);
var results = compute(input);
results.sort(function (a, b) {
return a - b;
});
//put the numbers length into valid parenthesis:
var NumbersAndOperators = getNumbersAndOperators(input);
var numbers = NumbersAndOperators[0];
console.log(numbers);
var operators = NumbersAndOperators[1];
console.log(operators);
var parens = validParentheses(numbers.length);
// console.log(numbers);
console.log(operators);
// for (var i = 0; i < parens.length; i++) {
// for (var j = 0; j < parens[i].length; j++) {
// var val = parens[i][j];
// console.log(val);
// if (val === " ") {
// var num = numbers.shift();
// parens.splice(val, 0, num);
// //starting running into infinite loops and out of time.
// j--;
// }
// }
// i--;
// }
console.log(parens);
return results;
};
function validParentheses(n) {
if (n === 1) {
return ['( )'];
}
var prevParentheses = validParentheses(n - 1);
var list = {};
prevParentheses.forEach(function (item) {
list['( ' + item + ' )'] = null;
list['( )' + item] = null;
list[item + '( )'] = null;
});
console.log(Object.keys(list))
return Object.keys(list);
}
function compute(str) {
var res = [];
var i;
var j;
var k;
var left;
var right;
var string = [];
var placed = true;
if (!/[+*-]/.test(str)) { // + - *
return [parseInt(str)];
}
for (i = 0; i < str.length; i++) {
if (/\+|\-|\*/.test(str[i])) { // + - *
left = compute(str.substring(0, i));
right = compute(str.substring(i + 1, str.length));
for (j = 0; j < left.length; j++) {
for (k = 0; k < right.length; k++) {
if (str[i] === '+') {
res.push(parseInt(left[j] + right[k]));
} else if (str[i] === '-') {
// string.push("(" + str[i-2], str[i+2] + ")");
res.push(parseInt(left[j] - right[k]));
} else if (str[i] === '*') {
res.push(parseInt(left[j] * right[k]));
}
}
}
}
}
// console.log(string);
return res;
}
console.log(diffWaysToCompute("2 - 1 - 1"));
console.log(diffWaysToCompute("2 * 3 - 4 * 5"));
I never had to do such silly things, so let me try my teeth at it now.
(Caveat as always: it's highly simplified and without any checks&balances!)
The parser is the simplest thing here:
/*
Use of strings instead of ASCII codes for legibility.
I changed x - y to x + (-y) not only for convenience
but for algebraic correctness, too.
#param a array number nodes
#param o array operator nodes
*/
function parse(s,a,o){
var fnum = 0;
var uminus = false
for(var i=0;i<s.length;i++){
switch(s[i]){
case '-': uminus = true;
a.push(fnum);
o.push('+');
fnum = 0;
break;
case '+':
case '*':
case '/': if(uminus){
uminus = false;
fnum *= -1;
}
a.push(fnum);
o.push(s[i]);
fnum = 0;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': fnum = fnum * 10 + parseInt(s[i]);
break;
default: break;
}
}
//assuming symmetry
a.push(fnum);
}
The (-generation took me some time, too much time--I cheated here ;-)
/*
Found in an old notebook (ported from C)
Algo. is O(n^2) and can be done faster but I
couldn't be a...ehm, had no time, sorry.
#idx int index into individual result
#n int number of groups
#open int number of opening parentheses
#close int number of closing parentheses
#a array individual result
#all array space for all results
*/
function makeParens(idx,n,open,close,a,all){
if(close == n){
all.push(a.slice(0));
return;
} else {
if(open > close){
a[idx] = ')';
makeParens(idx+1,n,open,close+1,a,all);
}
if(open < n){
a[idx] = '(';
makeParens(idx+1,n,open+1,close,a,all);
}
}
}
And now? Yepp, that took me a while:
/*
The interesting part
Not very optimized but working
#s string the equation
#return array nicely formatted result
*/
function parenthesing(s){
var nums = [];
var ops = [];
var all = [];
var parens = [];
// parse input into numbers and operators
parse(input,nums,ops);
/*
Rules:
1) out-most parentheses must be open in direction to center
e.g.: (1+2+3), 1+(2+3), 1+(2+3)+4
but not: 1)+(2+3)+(4
so: first parenthesis on the left side must be open and
the last parenthesis on the right side must be close
2) parentheses in direct neighborhood to a number must be
open in direction to the number (multiplication is
not mutual)
e.g.: 1+(2+3)+4, but not: 1+2(+3+4)
3) parentheses in direct neighborhood to an operator must be
closed in direction to the operator (multiplication is
not mutual)
e.g.: 1+(2+3)+4, but not: 1+2(+3+)4
*/
// build combinations separately not in-line
// it's already a mess, no need to add more
makeParens(0,nums.length,0,0,[],parens);
// You may take a look at the raw material here
// console.log(parens.join("\n"));
for(var i= 0;i<parens.length;i++){
var term = [];
// work on copies to reduce pointer juggling
var _ops = ops.slice(0);
var _nums = nums.slice(0);
for(var j=0;j<parens[i].length;j++){
if(parens[i][j] === '('){
term.push("(");
// rule 3
if(parens[i][j+1] === ')'){
term.push(_nums.shift());
}
// rules 1,2
else {
term.push(_nums.shift());
term.push(_ops.shift());
}
}
if(parens[i][j] === ')'){
term.push(")");
// rules 2,3
if(parens[i][j+1] !== ')')
term.push(_ops.shift());
}
}
// some pretty printing
term = term.join("");
// eval() because I didn't want to write a parser
// but if you need one...
all.push(term + " = " + eval(term));
}
return all;
}
I'm not sure if I would get hired with that abomination. Ah, to be honest: I doubt it.
But I hope it is at least a little bit helpful.
Yikes. That was tricky. Good challenge. I'm sure this could be cut way down, but it works. I used lodash and broke the various functions down to make it more flexible. Here's a jsfiddle:
https://jsfiddle.net/mckinleymedia/3e8g22Lk/8/
Oops - had to add parseInt to the addition so it doesn't add as strings.
/*
//input:
diffWaysToCompute("2 * 3 - 4 * 5");
//output:
(2*(3-(4*5))) = -34 - 2,1,0
((2*3)-(4*5)) = -14 - 0,2,1 & 2,0,1
((2*(3-4))*5) = -10 - 1,0,2
(2*((3-4)*5)) = -10 - 1,2,0
(((2*3)-4)*5) = 10 - 0,1,2
*/
'use strict'
var diffWaysToCompute = function(str) {
var opsAvailable = ['+','-','/','*'],
numbers = [],
operators = [],
getNumbersAndOperators = function(str) {
var arr = str.split(" ");
for (var i in arr) {
if ( opsAvailable.indexOf( arr[i] ) > -1 ) {
operators.push( arr[i] );
} else {
numbers.push( arr[i] );
}
};
return;
},
permutator = function(range) {
var results = [];
function permute(arr, memo) {
var cur,
memo = memo || [];
for (var i in arr) {
cur = arr.splice(i, 1);
if (arr.length === 0) results.push(memo.concat(cur));
permute(arr.slice(), memo.concat(cur));
arr.splice(i, 0, cur[0]);
}
return results;
}
return permute(_.range(range));
},
equations = function( perms ) {
var results = [];
_.each(perms, function( perm, k ) {
results[k] = nest ( perm );
});
return results;
},
nest = function( perm ) {
var eqs = eqs || [],
ref = ref || _.range(perm.length).map(function () { return undefined }),
eq,
target = undefined;
for (var i in perm) {
var cur = perm[i],
next = perm[i] + 1,
n1 = numbers[ cur ],
n2 = numbers[ next ],
r1 = ref[ cur ],
r2 = ref[ next ];
if ( r1 !== undefined) n1 = eqs [ r1 ];
if ( r2 !== undefined) n2 = eqs [ r2 ];
var rNew;
rNew = eqs.length;
for (var x in ref ) {
if ( ( ref[ x ] !== undefined ) && ( ref[ x ] == r1 || ref[ x ] == r2 ) ) ref[ x ] = eqs.length;
};
ref[ cur ] = ref[ next ] = eqs.length;
eqs.push({
ops: operators[ cur ],
nums: [ n1, n2 ]
});
};
return eqs[ eqs.length - 1 ];
},
calculations = function ( eqs ) {
var results = []
_.each(eqs, function(equation) {
results.push(calculate( equation ));
});
return results;
},
calculate = function( eq ) {
var result = {
text: ""
};
// result.eq = eq;
result.text += "( ";
result.total = eq.nums[ 0 ];
if ( _.isObject(result.total) ) {
var result1 = calculate( result.total );
result.total = result1.total;
result.text += result1.text;
} else {
result.text += eq.nums[ 0 ];
}
_.each(eq.ops, function (op, k) {
var num = eq.nums[ k + 1 ];
result.text += " " + op + " ";
if ( _.isObject(num) ) {
var result2 = calculate( num );
num = result2.total;
result.text += result2.text;
} else {
result.text += num;
}
if ( op === '+') result.total = parseInt(result.total) + parseInt(num);
if ( op === '-') result.total = result.total - num;
if ( op === '/') result.total = result.total / num;
if ( op === '*') result.total = result.total * num;
});
result.text += " )";
return result;
},
display = function( as ) {
var target = document.getElementById('result');
target.innerHTML += '<h3 class="problem">String given: ' + str + '</h3>';
target.innerHTML += '<h4>Permutations</h4>';
_.each( as, function(a) {
target.innerHTML += '<div class="permutation">';
target.innerHTML += ' <span class="formula">' + a.text + '</span> = ';
target.innerHTML += ' <span class="total">' + a.total + '</span>';
target.innerHTML += '</div>';
});
},
perms,
eqs,
answers;
getNumbersAndOperators(str);
perms = permutator( operators.length );
eqs = equations( perms );
answers = calculations( eqs );
answers = _.uniq(answers, 'text');
display(answers);
return answers;
};
console.log(diffWaysToCompute("2 * 3 - 4 * 5"));

I can't get eval() to work with my javascript calculation

I am working on a javascript code which calculates the value of Pi. So here's the problem. When eval() calculates the string which is generated by the code it returns 1. It is supposed to return 1.49138888889 (which is a rough value of Pi^2/6).
Here's the code. It returns the correct calculation as a string, But eval() doesn't calculate it properly.
function calculate() {
var times = 10;
var functionpart1 = "1/";
var functionpart2 = "^2+";
var x;
for (var functionpistring = "", x = 1; times != 0; times--, x++) {
functionpistring = functionpistring + functionpart1 + x.toString() + functionpart2;
}
document.getElementById("value").innerHTML = eval(functionpistring.slice(0, functionpistring.length - 1));
}
function calculate() {
var times = 20, // max loops
x, // counter
f = 0, // value representation
s = ''; // string representation
function square(x) {
return x * x;
}
function inv(x) {
return 1 / x;
}
function squareS(x) {
return x + '²';
}
function invS(x) {
return '1 / ' + x;
}
for (x = 0; x < times; x++) {
f += square(inv(x));
s += (s.length ? ' + ' : '') + squareS(invS(x));
document.write(f + ' = ' + s);
}
}
calculate();

Javascript autoincrement index

I need to create a function or use if is possible an already made library to auto increment an index. For example if it starts with 'A' it has to be incremented to 'Z' and after 'Z' it has to start from 'A1' and as soon as . . .'B1','C1', ... 'Z1', 'A2','B2',... . Does exist something like this already made ?
My idea is this, but start from 'A' and don't add number . . .
function nextChar(cont,letter) {
if (cont === 0){return letter;}
else {
letter=letter.charCodeAt(0) + 1;
return String.fromCharCode(letter);
}
}
One of many options:
function nextIndex(idx) {
var m = idx.match(/^([A-Z])(\d*)$/)
if(!m)
return 'A';
if(m[1] == 'Z')
return 'A' + (Number(m[2] || 0) + 1);
return String.fromCharCode(m[1].charCodeAt(0) + 1) + m[2];
}
var a = "";
for(i = 0; i < 100; i++) {
a = nextIndex(a)
document.write(a + ", ")
}
This one's less efficient than georg's but maybe easier to understand at first glance:
for (var count = 0, countlen = 5; count < countlen; count++) {
for (var i = 65, l = i + 26; i < l; i++) {
console.log(String.fromCharCode(i) + (count !== 0 ? count : ''));
}
}
DEMO
Allow me to propose a solution more object-oriented:
function Index(start_with) {
this.reset = function(reset_to) {
reset_to = reset_to || 'A';
this.i = reset_to.length > 1 ? reset_to[1] : 0; // needs more input checking
this.c = reset_to[0].toUpperCase(); // needs more input checking
return this;
};
this.inc = function(steps) {
steps = steps || 1;
while(steps--) {
if (this.c === 'Z') {
this.i++;
this.c = 'A';
} else {
this.c = String.fromCharCode(this.c.charCodeAt(0) + 1);
}
}
return this;
};
this.toString = function() {
if (this.i === 0) return this.c;
return this.c + '' + this.i;
};
this.reset(start_with);
}
var a = new Index(); // A
console.log('a = ' + a.inc(24).inc().inc()); // Y, Z, A1
var b = new Index('B8'); // B8
console.log('a = ' + a.reset('Y').inc()); // Y, Z
console.log('b = ' + b); // B8
Another way to think about this is that your "A1" index is just the custom rendering of an integer: 0='A',1='B',26='A1',etc.
So you can also overload the Number object to render your index. The big bonus is that all the math operations still work since your are always dealing with numbers:
Number.prototype.asIndex = function() {
var n = this;
var i = Math.floor(n / 26);
var c = String.fromCharCode('A'.charCodeAt(0) + n % 26);
return '' + c + (i ? i : '');
}
Number.parseIndex = function(index) {
var m;
if (!index) return 0;
m = index.toUpperCase().match(/^([A-Z])(\d*)$/);
if (!m || !m[1]) return 0;
return Number((m[1].charCodeAt(0) - 'A'.charCodeAt(0)) + 26 * (m[2] ? m[2] : 0));
};
var c = 52;
var ic = c.asIndex();
var nc = Number.parseIndex(ic);
console.log(c+' = '+ic+' = '+nc); // 52 = A2 = 52
If you go this way I would try to check if the new methods don't already exist first...

Categories

Resources