Javascript Loop with adding same value - javascript

I hope you guys can help me!
I'm trying the following:
1000 + 100 = 1100 * 2 = 2200;
2200 + 100 = 2300 * 2 = 4600;
4600 + 100 = 4700 * 2 = 9400;
9400 + 100 = 9500 * 2 = 19000;
...
But I'm getting the flowing result.
1000 + 100 = 1100 * 2 = 2200;
2200 * 2 = 4400
4400 * 2 = 8800
...
The values are inputed by the user, but I used static values for the example.
I have te following code:
var generate = function generate(rate){
var array = [];
s=0;
for (var i = 0; i < 10; i++){
s =+ 100;
array.push([
(parseInt(1000) + 100) * Math.pow(2, i),
]);
}
return array;
}

Sounds to me like you want a function that adds 100, doubles and then calls itself recursively a fixed number of times.
This function will run 10 times and output the final answer:
function add100andDouble(num, runTimes){
if(runTimes == 0) return num;
return add100andDouble( (num + 100 ) * 2, runTimes - 1 );
}
$(function(){
var number = parseFloat(prompt("Enter a number"));
alert( add100andDouble(number, 10) );
});

var generate = function generate(rate){
var array = [];
s=0;
for (var i = 0; i < 10; i++){
s = rate + (array[i-1] ? array[i-1] :1000);
array.push(s*2);
}
return array;
}
console.log(generate(100));

I suggest to use a function f(x) for calculating the new value. It makes the code more clearly arranged.
function f(x) {
return (x + 100) * 2;
}
var i = 0,
x = 1000,
array = [];
for (i = 0; i < 10; i++) {
array.push(x);
x = f(x);
}
document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');

Recursion has its merits on other solutions but I would go with plain old for loop for this situation.
Assuming rate is the starting number, and the return is a fixed 10 value series:
function generate(rate) {
var series = [];
for(var i = 0; i < 10; i++) {
series.push(rate = ((rate + 100) * 2));
};
return series;
}
It can be easily modified to send the series length if needed.

Related

brute force polynomial evaluation algorithm javascript

what is required is a brute force algorithm, and not some other!
I'm trying to implement the brute force method for a polynomial in javascript, but an error occurs, the answer is different from the other method above (horner method) - this method is checked and it gives the correct answer
but here is the second brut force- method that gives an excellent result, which is not correct.
What is the error in my code?
input :
_x = 6 _n = 5 polyEval = [2,3,5,-6,2]
output Horner method:
3386 // good. correct answer
output Bruforce method:
1496 // bad. incorrect answer
class Programm {
constructor(x:number, n:number) {
this._x = 4;
this._n = 5;
this.polyEval = [2,3,5,-6,2] //this.RandomArray(this._n);
}
private _x:number;
private _n:number;
private polyEval:number[] = [];
//working method
private Horner(poly:number[], n:number, x:number){
let time = performance.now();
let result = poly[0];
for (let i = 1; i < n; i++){
result = result * x + poly[i];
}
time = performance.now() - time;
console.log("Method: Horner |" ,`Result: ${result}, array: ${this.polyEval} |` ,`time: ${time.toFixed(5)}`);
}
// method with an error that I can't find
private BruteForce(poly:number[], n:number, x:number){
let time = performance.now();
let p: number = 0;
for(let i = n - 1; i >= 0; i--){
let coefficient = 1;
for(let j = 1; j <= i; j++){
coefficient = coefficient * x;
}
p = p + poly[i] * coefficient;
}
time = performance.now() - time;
console.log("Method: Brute Force |" ,`Result: ${p}, array: ${this.polyEval} |` ,`time: ${time.toFixed(5)}`);
}
// generate random array
private RandomArray(n: number):number[]{
let result:number[] = new Array(n);
for (let i = 0; i < n; i++){
if(Math.round(Math.random() * 1) > 0){
result[i] = Math.floor(Math.random() * (10 - 1)) + 1;
}else{
result[i] = Math.floor(((Math.random() * (10 - 1)) + 1) * -1);
}
}
return result;
}
public Main() {
console.log(`n - array length: ${this._n} | x - coefficient: ${this._x}`);
this.Horner(this.polyEval, this._n, this._x);
this.BruteForce(this.polyEval, this._n, this._x);
}
}
const random_N:number = Math.floor(Math.random() * (5 - 1)) + 3;
const random_X:number = Math.floor(Math.random() * (5 - 1)) + 2;
const poly = new Programm(random_N, random_X);
poly.Main();
The Horner's scheme works like this:
// initially
result = poly[0] == p_0;
// iteration 1
result = result * x + poly[1] == p_0 * x + p_1
// iteration 2
result = result * x + poly[2] == (p_0 * x + p_1) * x + p_2
== p_0 * x^2 + p_1 * x + p_2
Thus, the polynomial coefficients in the array poly are in order of highest to lowest. Then to replicate that in the brute force solution, one needs to apply the formula as
result = sum(poly[i] * pow(x, n-1-i)) ==
result = sum(poly[n-1-i] * pow(x, i))

Generate a random boolean 70% True, 30% false

I have the following function that generates a random boolean.
choose_direction: function () {
var random_boolean = Math.random() >= 0.5;
if (random_boolean) {
trade.call()
prev_trade.goingUp = true
console.log('Trade: CALL!!!!!!!!!!!!!!!!!!!!!!')
} else {
trade.put()
prev_trade.goingUp = false
console.log('Trade: PUT!!!!!!!!!!!!!!!!!!!!!!!!')
}
}
However, I need the distribution to be unfair. More specifically, I want the output to be 70% of the time true and 30% of the time false.
Instead of >= 0.5 you just need < 0.7:
var random_boolean = Math.random() < 0.7;
// 70% this will be true, 30% false
As #plasmacel commented, Math.random() returns a value between 0 and 1 (including 0, but not 1: [0, 1)), so therefore we do < 0.7.
Let's consider one thing. Math.random() gives you a pseudo-random number.
Try this function:
function randomTest(triesCount) {
var sum = 0;
for(var i = 0; i < triesCount; i++){
sum += Math.random();
}
return sum / triesCount;
}
if you try it with different triesCount parameters the results will be:
randomTest(100) - 0.5189474703446081
randomTest(100) - 0.5189474703446081
randomTest(1000) - 0.4973368682657417
randomTest(10000) - 0.5001058467610172
randomTest(100000) - 0.4987280984186288
randomTest(1000000) - 0.4999987387801045
randomTest(10000000) - 0.49998292815655454
randomTest(100000000) - 0.500079160302315
So as you can se the results go to 0.5 which means this is not a random number generated here.
Although the answer to your question will be
var random_boolean = Math.random() >= 0.3;
as Ionică Bizău said.
But keep in mind that it is pseudo-random number!
Here is a version I made with typescript. Can easily remove the variable types to turn this into javascript.
//Usage
let randomBoolean = randomPercentForTrue(70)
export function randomPercentForTrue(percentage: number): boolean {
return randomNumber(1, 100) <= percentage
}
export function randomNumber(minValue: number, maxValue: number): number {
return Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue
}
These methods are heavily tested with various use cases. Here are test cases with mocha:
it('randomPercentForTrue with 95% accuracy', function() {
let results0: boolean[] = []
let results1: boolean[] = []
let results2: boolean[] = []
let results3: boolean[] = []
let results4: boolean[] = []
let loopAmount = 10000
for(let i = 0; i < loopAmount; i++) {
results0.push(randomPercentForTrue(0))
results1.push(randomPercentForTrue(25))
results2.push(randomPercentForTrue(50))
results3.push(randomPercentForTrue(75))
results4.push(randomPercentForTrue(100))
}
let resultTotals = Array(5).fill(0)
for(let i = 0; i < loopAmount; i++) {
resultTotals[0] += results0[i]
resultTotals[1] += results1[i]
resultTotals[2] += results2[i]
resultTotals[3] += results3[i]
resultTotals[4] += results4[i]
}
expect(resultTotals[0]).to.be.closeTo(0, 0)
expect(resultTotals[1]).to.be.closeTo(loopAmount * 25 / 100, loopAmount * 25 / 100 / 20)
expect(resultTotals[2]).to.be.closeTo(loopAmount * 50 / 100, loopAmount * 50 / 100 / 20)
expect(resultTotals[3]).to.be.closeTo(loopAmount * 75 / 100, loopAmount * 75 / 100 / 20)
expect(resultTotals[4]).to.be.closeTo(loopAmount, 0)
})

how to calculate the ways of a big number split by some small numbers in js

For example: There is a total number 1000, and how many ways to equal 1000 using 100/50/20/10/5/1. I have found a idea about this. But obviously, that's not good. So does anyone have some other good ideas to cover it?
total = prompt('you can input number 1-1000, but 1000 will take a LOONG time');
count = 0;
t100 = total;
function money() {
for (var i100 = Math.floor(t100 / 100); i100 >= 0; i100--) {
var t50 = t100 - i100 * 100;
for (var i50 = Math.floor(t50 / 50); i50 >= 0; i50--) {
var t20 = t50 - i50 * 50;
for (var i20 = Math.floor(t20 / 20); i20 >= 0; i20--) {
var t10 = t20 - i20 * 20;
for (var i10 = Math.floor(t10 / 10); i10 >= 0; i10--) {
var t5 = t10 - i10 * 10;
for (var i5 = Math.floor(t5 / 5); i5 >= 0; i5--) {
var t1 = t5 - i5 * 5;
count++;
console.log(i100 + ' 100' + i50 + ' 50' + i20 + ' 20' + i10 + ' 10' + i5 + ' 5' + t1 + ' 1');
}
}
}
}
}
alert('The total number ' + total + ' is ' + count);
}
money()
No idea if it's correct but a little idea that popped to my head:
You know that with the bills/coins given, you can always fill up to the amount you need (value). If at the same time, you assume that you will always chose the highest possible bill / coin for the remainder I think you could do this:
If you use 100 bills you have floor(value / 100) possibilities (You can use 1 x 100, 2 x 100... )
If you don't use 100 but 50 you have floor(value / 50) possibilities
If you don't use 50 but 20 you have floor(value /20) possibilities
and so on. Add those up and you have a total of possibilities.
Let me know if I'm missing something.
I don't know about coding in js but you could try an algorithm like this one, which should be much more performant timely speaking. I'll try to make it as clear as possible :
availableCoins = [100, 50, 20, 10, 5] // all available coins exept 1
numberCoins = availableCoins.Length
mapResults = new Map[(int,int),int]
money(int total, int indexCoin){
if ( indexCoin == numberCoins ) {
return 1 // only coin 1 is available, there is only one solution
}
elseif ( mapResults.containsKey((total,indexCoin)) ) {
return mapResults((total,indexCoin)) // if the result has already been computed
}
else {
int count = 0
int currentCoin = availableCoin[indexCoin]
int upperbound = floor(total / currentCoin) // compute it before to avoid useless computation
for (int i = 0; i <= upperbound; i++) {
count += money(total - i * currentCoin, indexCoin + 1) // we assume only i of the current coin will be use
}
mapResults((total,indexCoin)) = count
return count
}
}
money(1000, 0)
Let me know if I have missed something or if it is not clear.
I let you adapt it to js.
I have got a expression from my colleague, and here it is:
//n is the total number
Change(n,m) {
if(n===0) return 0;
if(n<0 || m === 0) return 0;
var dimes = [1, 5, 10, 20, 50, 100];
return (change(n, m-1)+change(n-dimes[m-1], m));
}

Generate a random 4 digit number with no repeating digits

I have this function to create a random 4 digit number:
generateCode = function(){
var fullNumber = [];
var digit1 = Math.floor(Math.random() * 9) + 1;
var digit2 = Math.floor(Math.random() * 9) + 1;
var digit3 = Math.floor(Math.random() * 9) + 1;
var digit4 = Math.floor(Math.random() * 9) + 1;
fullNumber.push(digit1, digit2, digit3, digit4);
this.theCode(fullNumber.join("")) ;
}
But I need to create a 4 digit random number with no repeating digits.
So "1234" or "9673". But not "1145" or "5668"
Is there an efficient way to do this?
You can use this handy shuffle function to shuffle an array containing the numbers, and pick the first 4.
function random4Digit(){
return shuffle( "0123456789".split('') ).join('').substring(0,4);
}
function shuffle(o){
for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
}
alert( random4Digit() );
Edit: If you actually want a Number not starting with 0:
function random4DigitNumberNotStartingWithZero(){
// I did not include the zero, for the first digit
var digits = "123456789".split(''),
first = shuffle(digits).pop();
// Add "0" to the array
digits.push('0');
return parseInt( first + shuffle(digits).join('').substring(0,3), 10);
}
function shuffle(o){
for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
}
alert( random4DigitNumberNotStartingWithZero() );
Create an array of numbers, randomize it, then slice out the first 4 and join them together.
var numbers = [0,1,2,3,4,5,6,7,8,9];
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
shuffleArray(numbers).slice(0,4).join('');
It really depends on how you'd like to approach the problem. One solution is to store the digits you've used already in an array, then search the array when you generate a number. If the generated number is contained in the array, then you try generating another number. Doing a few different steps like this is also easier to follow if you have a few different functions. See my included example below:
var checkRandomUsed = function(array, number){
return array.indexOf(number) > -1;
}
var getCheckedRandom = function(array){
var random = getRandomNum();
while (checkRandomUsed(array, random)){
random = getRandomNum();
}
return random;
}
var getRandomNum = function(){
return Math.floor(Math.random() * 9) + 1;
}
var generateCode = function(){
var usedNumbers = [];
for (var i = 0; i < 4; i++){
usedNumbers.push(getCheckedRandom(usedNumbers));
}
return usedNumbers.join("");
}
As an update, try this...
const value = (new Array(4))
.map(() => (Math.floor(Math.random() * 9) + 1).toString()).reduce((p, c) => p + c);
This will do it if you're ok with potentially having 0 as the first digit:
var getNum = () => randoSequence(0, 9).slice(-4).join("");
console.log(getNum());
<script src="https://randojs.com/1.0.0.js"></script>
This will do it without 0 as the first digit:
function getNum(){
var sequenece = randoSequence(0, 9).slice(-4);
return (sequenece[6] ? sequenece.slice(-4) : sequenece.slice(0, 4)).join("");
}
console.log(getNum());
<script src="https://randojs.com/1.0.0.js"></script>
Both of these codes use rando.js to simplify the randomness and make it more readable, so don't forget to add the script tag to the head of your HTML document if you want to use either of them.

Math.ceil to nearest five at position 1

Okay....
I have a lot of uncontrolled numbers i want to round:
51255 -> 55000
25 -> 25
9214 -> 9500
13135 -> 15000
25123 -> 30000
I have tried modifying the numbers as string and counting length....
But is there a simple way using some Math function maybe?
Here's my late answer. Uses no Math methods.
function toN5( x ) {
var i = 5;
while( x >= 100 ) {x/=10; i*=10;}
return ((~~(x/5))+(x%5?1:0)) * i;
}
DEMO: http://jsbin.com/ujamoj/edit#javascript,live
[51255, 24, 25, 26, 9214, 13135, 25123, 1, 9, 0].map( toN5 );
// [55000, 25, 25, 30, 9500, 15000, 30000, 5, 10, 0]
Or this is perhaps a bit cleaner:
function toN5( x ) {
var i = 1;
while( x >= 100 ) {x/=10; i*=10;}
return (x + (5-((x%5)||5))) * i;
}
DEMO: http://jsbin.com/idowan/edit#javascript,live
To break it down:
function toN5( x ) {
// v---we're going to reduce x to the tens place, and for each place
// v reduction, we'll multiply i * 10 to restore x later.
var i = 1;
// as long as x >= 100, divide x by 10, and multiply i by 10.
while( x >= 100 ) {x/=10; i*=10;}
// Now round up to the next 5 by adding to x the difference between 5 and
// the remainder of x/5 (or if the remainder was 0, we substitute 5
// for the remainder, so it is (x + (5 - 5)), which of course equals x).
// So then since we are now in either the tens or ones place, and we've
// rounded to the next 5 (or stayed the same), we multiply by i to restore
// x to its original place.
return (x + (5-((x%5)||5))) * i;
}
Or to avoid logical operators, and just use arithmetic operators, we could do:
return (x + ((5-(x%5))%5)) * i;
And to spread it out a bit:
function toN5( x ) {
var i = 1;
while( x >= 100 ) {
x/=10;
i*=10;
}
var remainder = x % 5;
var distance_to_5 = (5 - remainder) % 5;
return (x + distance_to_5) * i;
}
var numbers = [51255, 25, 9214, 13135, 25123, 3, 6];
function weird_round(a) {
var len = a.toString().length;
var div = len == 1 ? 1 : Math.pow(10, len - 2);
return Math.ceil(a / 5 / div) * div * 5;
}
alert(numbers.map(weird_round));
Also updated for numbers below 10. Won't work properly for negative numbers either, just mention if you need this.
DEMO
I'm not sure why, but I thought it would be fun with regular expressions:
var result = +(number.toString().replace(/([1-9])([0-9])(.+)/, function() {
return Math.ceil(+(arguments[1] + '.' + arguments[2])) * 10 - (+arguments[2] < 5?5:0) + arguments[3].replace(/./g, '0');
}));
Working Demo
with(Math) {
var exp = floor(log(number)/log(10)) - 1;
exp = max(exp,0);
var n = number/pow(10,exp);
var n2 = ceil(n/5) * 5;
var result = n2 * pow(10,exp);
}
http://jsfiddle.net/NvvGf/4/
Caveat: only works for the natural numbers.
function round(number) {
var numberStr = number + "",
max,
i;
if (numberStr[1] > '4') {
numberStr[0] = parseInt(numberStr[0]) + 1;
numberStr[1] = '0';
} else {
numberStr[1] = '5';
}
for (i = 2; max = numberStr.length; i < max; i += 1) {
numberStr += '0';
}
return parseInt(numberStr);
}
Strange coincidence, I wrote something really similar not so long ago!
function iSuckAtNames(n) {
var n = n.toString(), len = n.length, res;
//Check the second number. if it's less than a 5, round down,
//If it's more/equal, round up
//Either way, we'll need to use this:
var res = parseFloat(n[0]) * Math.pow(10, len - 1); //e.g. 5 * 10^4 = 50000
if (n[1] <= 5) {
//we need to add a 5 right before the end!
res += 5 * Math.pow(10, len - 2);
}
else {
//We need another number of that size
res += Math.pow(10, len - 1);
}
return res;
}

Categories

Resources