Double Maths Random in Array with Javascript - javascript

I need your help because I'm totally lost with a javascript exercise (I learn alone).
I cut the exercice in steps
I generate an aleatory number between 3 and 20 (with Maths Random)
I generate an array of 100 cells: In each cells, there is one " _ "
If the number is 5: 5 " _ " is aleatory replaced by a " # " (second Maths Random)
I think my cut is good but I can't write it in code.
Before this exercise I've done exercises easier with maths random but now it's more diffult for me.
Some can help me to create the code?
Thank you very much
edit: I tried to do something but without maths random.
function hashtagLine(){
var number = prompt( "Saisissez un nombre entre 3 et 10" );
var line = "";
if (number >= 1 && number <= 10){
for ( var i = 1; i <= 100; i++ ) {
if ( i % number === 0 ) {
line += "#";
} else {
line += "_";
}
}
console.log( line );
} else {
alert( "vous avez entré un nombre qui ne correspond pas" );
}
}
hashtagLine();

Here is a simple implementation:
HTML
<table id="table"></table>
JS
var t = document.getElementById('table');
var rnd = Math.ceil(Math.random() * 17 + 3);
var string = '<tr>';
for (var i = 1; i <= 100; i++) {
if (i == rnd) {
string += '<td>#</td>';
} else {
string += '<td>_</td>';
}
// for new row...
if (i % 10 == 0) {
string += '</tr><tr>';
}
}
string += '</tr>';
t.innerHTML = string;
But if you're trying to learn the language, it's best to try yourself, not just have somebody hand you the answer.

It is still not clear to me what you are trying to achieve, but here is some code that may help you. If you come back with more information then I may be able to help you some more.
Math.random
// get reference to out output element
var pre = document.getElementById('out');
// Returns a random integer between min (included) and max (excluded)
// Using Math.round() will give you a non-uniform distribution!
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function hashtagLine() {
var min = 3,
max = 20,
cells = 100,
number = getRandomInt(min, max + 1),
line = [],
index;
// create the line array of length cells
for (index = 0; index < cells; index += 1) {
// unclear what you are trying to do here!
if (index % number === 0) {
line.push('#');
} else {
line.push('_');
}
}
// output the array as a line of text
pre.textContent += line.join('') + '\n';
}
// Add a click event listener to our generate button
document.getElementById('generate').addEventListener('click', hashtagLine, false);
<button id="generate">Generate</button>
<pre id="out"></pre>

Related

while loop test case errors

The question as per the practice course is :
Write a JavaScript program to find the maximum integer n such that (1 + 2 + ... + n <= given integer ) is true. For eg. If a given integer is 10, value of maximum integer n is 4 so that 1+2+3+4 <= 10 is true. Your output code should be in the format console.log("Value of n is ", variableName)
My code is :
var num = prompt("Enter a number");
function test(x) {
var sum = 1,
n = 1,
a = 0;
while (sum <= x) {
sum += n;
n = n + 1;
a += 1;
}
return a;
}
var output = test(num);
console.log("Result is :", output);
I'm getting the correct outputs as per the test cases I've entered(10-4,15-5,16-6,17-6) but the website says there is something wrong with the program.
What am i doing wrong?
Better answer than looping: exploit maths. Starting with Triangular number formula:
1 + 2 + ... + n = n * (n + 1) / 2
Thus, for input x, you need to find n such that
n * (n + 1) / 2 <= x
To solve this, we need to clean up the inequality, then use the quadratic equation formula:
n^2 + n <= 2x
n^2 + n - 2x <= 0
n <= (-1 + sqrt(1 + 8x)) / 2
as the final solution. e.g. for
x = 10: n <= (-1 + sqrt(81)) / 2; n <= 4
x = 16: n <= (-1 + sqrt(128)) / 2; n <= 5.156854249492381
Round the upper limit down, and you have the largest allowed integer. Translated into JavaScript:
function test(x) {
return Math.floor((Math.sqrt(8 * x + 1) - 1) / 2);
}
var num = prompt("Enter a number");
console.log("Result is :", test(num));
Consider if the passed value is 11. Then, the maximum integer n should be 4, because 1+2+3+4 < 11 is true, while 1+2+3+4+5 < 11 is false. Your current code outputs 5 for an input of 11, though, which is incorrect; your while loop is sometimes overshooting sum.
You also need to initialize sum to start at 0, not at 1.
Subtract one from a before returning it:
function test(x) {
var sum = 0,
n = 1,
a = 0;
while (sum <= x) {
sum += n;
n = n + 1;
a += 1;
console.log(a, sum);
}
return a - 1;
}
console.log(test(10));
console.log(test(11));
var num = prompt("Enter a number");
var output = test(num);
console.log("Result is :", output);
The code below should work for you. Basically, what I did was that if the input is 10, and your sum is 9, it will still go into the while loop. Then it will add n again and now your number is greater than your input (which is 10), but you still return it. Here what I did is that at the end of the while loop, if your sum is greater than your input, subtract one from a. That way it will still execute, but it will fix the problem.
Also another error I noticed was that sum started at 1, and n started at 1. You wanted 1+2+3+...+n, however using your previous method, you got 1+1+2+3+...+n.
var num = prompt("Enter a number");
function test(x) {
var sum = 0,
n = 1,
tempSum = 1,
a = 0;
while (sum <= x) {
sum += n;
n++;
a++;
if (sum > x) {
a--;
}
}
return a;
}
var output = test(num);
console.log("Result is :", output);
Your order of operation is a little funky; all you have to do is add the incrementor. The while false case will make sure the sum only passes over the number once. So when you return, reduce the number by one:
var num = prompt("Enter a number");
var output = test(num);
console.log("Result is :", output);
function test(num){
let sum = 0
let inc = 0
while(sum<=num)
sum+=++inc
return --inc;
}
This is a reduced version of your code, basically we increment first the number to add (n) in each iteration, and then we add it to the variable holding the sum. When the loop conditions evaluates to false you need to decrement one to n to get your value:
var num = prompt("Enter a number");
function test(x)
{
var sum = 0, n = 0;
while (sum <= x)
{
sum += (++n);
}
return --n;
}
var output = test(num);
console.log("Result is :", output);
I think this will work for you:
var num = prompt("Enter a number");
function test(x) {
var sum = 1,
n = 0;
while ((sum+n) <= x) {
n = n + 1;
sum += n;
}
return n;
}
var output = test(num);
console.log("Result is :", output);
Try below function to find max Number
function maxNumber(a){
var i=1,sum=0,maxNumber=0;
while(sum<=a) {
sum=sum+i;
if(sum<=a)
{
maxNumber=i;
}
i+=1;
}
return maxNumber;
}
doubled checked condition sum<=a to preserve the previous loop value and if condition not satisfied that means current loop value is not useful so returned preserved value of previous loop
Output tested :
Below will help you get the job done.
var num = prompt("Enter a number");
function findMaxNumber(num){
var sum = 0;
var counter = 0;
while(sum < num){
if(sum + counter > num){
break; // Exit loop
}
sum = sum + counter;
counter++;
}
return --counter; // Loop will cause this to be 1 higher than the max int.
}
console.log('Result is: ' + findMaxNumber(num));

Trying to fill 9 spaces with number between 1 and 2 with some rules

I'm trying to fill 9 boxes with numbers, these numbers could be number 1 or number 2, being that number 2 can only be 4 times and number 1 should fill the other 5 times left... i know it's a problem of simple logic but someway I can't reach my goal... look at the piece of code that I have...
<script type="text/javascript">
for (cicloTipo = 1; cicloTipo < 10; cicloTipo++) {
var tipo = Math.floor((Math.random() * 2) + 1);
document.write(tipo);
}
</script>
You can start with an array of the required values, then either shuffle the array or randomly select values from it. Some say Math.random isn't truely random, but it should be good enough.
The following uses splice to select values, so the loop iterates backwards since splicing shortens the source array each time.
function getRandoms(){
for (var seed=[1,1,1,1,1,2,2,2,2], result=[], i=seed.length; i; i--) {
result.push(seed.splice(Math.random() * i | 0, 1)[0]);
}
return result;
}
// Show randomness of result
(function() {
var s = new Array(30).fill('+');
var r;
for (var i=9; i; ){
document.getElementById(--i).textContent = s.join('');
}
var j = 300; // Number of runs
var delay = 20; // Default delay in ms
function display(lag) {
delay = lag || delay;
getRandoms().forEach(function(v, i, rand) {
var el = document.getElementById(i);
if (v == 1) {
el.textContent = el.textContent.slice(0,-1);
// If run out of "+", add some to every line
if (!el.textContent.length) {
for (var k=0; k < 9; k++) {
document.getElementById(k).textContent += '++++++++++';
}
}
} else {
el.textContent += '+';
}
if (i == 0) {
document.getElementById('msg').innerHTML = 'Remaining: ' + j +
'<br>' + 'Values: ' + rand.join('');
}
});
--j;
if (j > 0) {
setTimeout(display, delay);
}
}
display(50);
}());
// Single call
// console.log(getRandoms().join());
<span id="0"></span><br>
<span id="1"></span><br>
<span id="2"></span><br>
<span id="3"></span><br>
<span id="4"></span><br>
<span id="5"></span><br>
<span id="6"></span><br>
<span id="7"></span><br>
<span id="8"></span><br>
<span id="msg"></span>
For fun I've added a display of the distribution. Each line represents a value in the result array from 0 to 8 and starts with a set number of "+" symbols. Each time a 1 is in the related position, a "+" is removed. Each time a 2 is in the position, a "+" is added. Since there are more 1s than 2s, the lines slowly get shorter. When a line gets to zero length, 10 more "+" are added to every line.
The important part is that the lines stay about equivalent lengths and that the same lines aren't longest or shortest after each run. If you think you see a pattern emerging, it must be sustained for at least 100 runs to show a bias.
Here's a solution which ensures that no more than 4 2's are in the chain.
it means that the digits chain can contain from 0 2's to 4 2's and the rest is 1's
// 2s Counter
var c1 = c2 = 0;
for (var cicloTipo = 1; cicloTipo < 10; cicloTipo++) {
var tipo = Math.floor((Math.random() * 2) + 1);
// check if it's a 2 and 4 2s have been encountred
if (tipo == 2) {
if (c2 < 4) {
// increment counter
c2++;
} else {
tipo = 1;
c1++;
}
}
// check if it's a 1 and 5 1s have been encountred
else if (tipo == 1) {
if (c1 < 5) {
// increment counter
c1++;
} else {
tipo = 2;
c2++;
}
}
document.write(tipo);
}
it looks like your criteria forces 4 2's and 5 1's;
i fixed this code to fit this criteria but #Paul Rooney 's suggestion is the best.

How can I count the number of zero decimals in JavaScript?

How do I get the number of zero decimals behind the comma (but not the total)? So to illustrate an example:
0.00001 > 4
0.000015 > 4
0.0000105 > 4
0.001 > 2
I am looking for methods that are efficient (meaning that they optimize the calculation time).
You can use logarithms to find the magnitude of the number:
var x = 0.00195;
var m = -Math.floor( Math.log(x) / Math.log(10) + 1);
document.write(m); // outputs 2
Later versions of JavaScript have Math.log10, so it would be:
var x = 0.00195;
var m = -Math.floor( Math.log10(x) + 1);
document.write(m); // outputs 2
How using the base-10 logarithm of the numbers works:
x
Math.log10(x)
Math.floor(Math.log10(x) + 1 )
0.1
-1
0
0.01
-2
-1
0.015
-1.8239…
-1
0.001
-3
-2
0.00001
-5
-4
0.000015
-4.8239…
-4
0.0000105
-4.9788…
-4
Use a regex to match the number of zeros after a decimal point and then count them.
var zeros = float.toString().match(/(\.0*)/)[0].length - 1;
DEMO
Use this one:
function numberOfZeros(n) {
var c = 0;
while (!~~n) {
c++;
n *= 10;
}
return c - 1;
}
document.write(numberOfZeros(0.00065));
This code does the following: it multiplies the number by ten as long as it can be truncated to something not equal 0. The truncation operator "~~" is very performant, because it works with byte representation of the number directly.
It doesn't use any string operations and does exactly what you want: counts the zeros.
//my answer
function t1()
{
var num = 0.0000005323;
numOfZeroes = 0;
while(num < 1)
{
numOfZeroes++;
num *= 10;
}
}
//others
//Andrew Morton's answer
//https://stackoverflow.com/a/31002148/1115360
function t2()
{
var num = 0.0000005323;
var m = -Math.floor( Math.log10(num) + 1);
}
//Amy's Answer
//https://stackoverflow.com/a/31002087/4801298
function t3()
{
var r = 0.0000005323;
var count=0;
var splited = r.toString().split(".")[1];
for(var i=0;i<splited.length;i++)
{
if(splited[i]==0)
{
count++;
}
else
{
break;
}
}
}
//Ted's Answer
//https://stackoverflow.com/a/31002052/4801298
function t4()
{
var number = 0.0000005323;
var numberAsString = number.toString();
var decimalsAsString = numberAsString.substr(numberAsString.lastIndexOf('.')+1);
var leadingZeros = decimalsAsString.substr(0, decimalsAsString.lastIndexOf('0')+1).length;
}
//Bartłomiej Zalewski's answer
//https://stackoverflow.com/a/31001998/4801298
function t5()
{
var n = 0.0000005323;
var c = 0;
while (!~~n) {
c++;
n *= 10;
}
return c - 1;
}
//Andy 's answer
//https://stackoverflow.com/a/31002135/4801298
function t6()
{
var float = 0.0000005323;
var zeros = float.toString().match(/(\.0*)/)[0].length - 1;
}
//Praveen's answer
//https://stackoverflow.com/a/31002011/4801298
function t7()
{
var a = 0.0000005323;
return (a.toString().replace("0.", "").split("0").length - 1);
}
//benchmark function
function bench(func)
{
var times = new Array();
for(var t = 0; t < 100; t++)
{
var start = performance.now();
for(var i = 0; i < 10000; i++)
{
func();
}
var end = performance.now();
var time = end - start;
times.push(time);
}
var total = 0.0;
for(var i=0, l=times.length; i<l; i++)
total += times[i];
var avg = total / times.length;
return avg;
}
document.write('t1: ' + bench(t1) + "ms<BR>");
document.write('t2: ' + bench(t2) + "ms<BR>");
document.write('t3: ' + bench(t3) + "ms<BR>");
document.write('t4: ' + bench(t4) + "ms<BR>");
document.write('t5: ' + bench(t5) + "ms<BR>");
document.write('t6: ' + bench(t6) + "ms<BR>");
document.write('t7: ' + bench(t7) + "ms<BR>");
Note:
This would only work with numbers less than 1 of course. Otherwise, just remove numbers left of the decimal point first, like
num -= num % 1;
need to compare this to another way.
a while later...
I would like a better way to bench these function though. I might have my calculation wrong. I'm adding other peoples answers into the test. I'm now attempting to use the performance API
a bit later than before
AHA! Got it working. Here are some comparisons for you.
You can use something like this:
function num (a) {
return (a.toString().replace("0.", "").split("0").length - 1)
}
Here is a working example (a bit lengthy for clarity):
var number = 0.0004342;
var numberAsString = number.toString();
var decimalsAsString = numberAsString.substr(numberAsString.lastIndexOf('.')+1);
var leadingZeros = decimalsAsString.substr(0, decimalsAsString.lastIndexOf('0')+1).length;
// leadingZeros == 3
Convert the number in to a string and split it with the dot (.). Using the for loop to count the zeros occurrences.
var r = 0.0000107;
var count=0;
var splited = r.toString().split(".")[1];
for(var i=0;i<splited.length;i++)
{
if(splited[i]==0)
{
count++;
}
else
{
break;
}
}
console.log(count);
Node.js 9.0.0
I was looking for a solution without converting or the O(n) approach. Here is what solution I made by O(1).
Part of finding decimal by log – caught from #AndrewMorton, but it might be laggy with the divider: log(10) – 2.302585092994046.
Example
const normalize = (value, zeroCount) => {
const total = 10 ** zeroCount
const zeros = Math.floor(-Math.log10(value / total))
return value * (10 ** zeros)
}
Usage
normalize(1510869600, 13) // 1510869600000
normalize(1510869600, 10) // 1510869600

What's wrong with this even/odd Javascript?

I am trying to write a very simple JS program. I want it to generate 10 random numbers between 1 and 100 and display how many of them are even and how many are odd. I've been looking all over and I can't find why this isn't working. It's displaying 0 even numbers and 10 odd numbers, no matter the combination. What am I overlooking?
function main()
{
var number = 0;
var totalNumbers = 0;
var evenNumbers = 0;
var oddNumbers = 0;
document.write("Here are ten random numbers between 1 and 100:<br><br>");
while(totalNumbers < 10)
{
number = document.write((Math.floor((Math.random()* 100)+1)) + "<br>");
if(number % 2 == 0)
{
evenNumbers++;
}
else
{
oddNumbers++;
}
totalNumbers++;
}
document.write("<br><br>Even Numbers: " + evenNumbers + "<br>" +
"Odd Numbers: " + oddNumbers);
}
document.write() does not return a number. Store the number in a variable before calling document.write().
while(totalNumbers < 10)
{
var number = Math.floor((Math.random()* 100)+1;
document.write(number + "<br>");
if(number % 2 == 0)
{
evenNumbers++;
}
else
{
oddNumbers++;
}
totalNumbers++;
}

Cannot assign new value to array element - javascript

I am relatively new to programming and I am new to javascript/html/css (read over a few tutorials) and am having a weird problem with my first script. (trying to make sudoku solver)
the array puzzle contains: "3.542.81.4879.15.6.29.5637485.793.416132.8957.74.6528.2413.9.655.867.192.965124.8 "
where puzzle[0] = 3 puzzle[ 1 ] = . and so on.
puzzle represents an unsolved sudoku puzzle where digits 1-9 rep solved cells and . unsolved cells.
Below is my code for one of my functions and there are 4 alert messages in it. My problem lies near MESSAGE 4 where puzzle[c+(9*r)] = nums[0]; shows that puzzle[c+9*r] still contains a . and not the value of num[0] (in the first case 6).
Declared outside of functions:
var puzzle = new Array();
var options = new Array();
var nums = new Array();
var r = 0;
var c = 0;
var num=0;
function checkNumber works fine *
MESSAGE 1: "puz conatians ."
MESSAGE 2: "nums length is 1"
MESSAGE 3: "nums[0] is 6"
MESSAGE 4: = "puzzle is ." SHOULD BE "puzzle is 6"
Any help would be much appreciated! Please let me know if I need to further clarify something =]
function makeOptionsArray() {
// loop through 9x9 grid of sudoku r = row c = column
for (r = 0; r < 9; r++) {
for (c = 0; c < 9; c++) {
nums.length = 0; // reset array for each new cell
if (puzzle[c + (9 * r)] == '.') { // if unknown cell
alert("puz contains " + puzzle[c + 9 * r]); // MESSAGE 1
for (num = 1; num <= 9; num++) {
if (checkNumber(num, r, c)) { // check digits 1-9
nums.push(num); // keep track of possible values
//for this cell based on other known values on the board
}
}
options[c + (9 * r)] = nums; // used for another part & will contain all possible values for an unsolved cell
alert("nums length is " + nums.length); // MESSAGE 2
if (nums.length == 1) { // if only 1 possible number add to sudoku
alert("nums[0] is " + nums[0]); // MESSAGE 3
puzzle[c + (9 * r)] = nums[0];
document.getElementById(c + 9 * r).innerHTML = nums[0];
alert("puzzle is " + puzzle[c + 9 * r]); //MESSAGE 4
makeOptionsArray(); // call function again with updated puzzle (one less unknown cell)
}
if (nums.length == 0) { //if no possible options then no solutions for puzzle
alert("No solutions");
return true;
} else {
continue;
}
}
}
}
}

Categories