I believe my problem might have a simple solution, but I can't figure it out how to fix it...
Codepen
let x;
let op;
let horamin = 10;
let horamax = 15;
function hora (x, op){
if (x > horamin && x < horamax) {
if (op == 'soma') {
document.querySelector(".hora").innerText = x + 1
} else {
document.querySelector(".hora").innerText = x - 1
} ;
}
}
document.querySelector(".horaU").addEventListener('click', (event) = > {
x = parseInt(document.querySelector(".hora").innerText);
op = "soma";
hora(x, op);
//document.querySelector(".hora").innerText = x+1;
});
document.querySelector(".horaD").addEventListener('click', (event) = > {
x = parseInt(document.querySelector(".hora").innerText);
op = "diminui";
hora(x, op)
});
Everything works as intendend, until I reach horamin or horamax value. Then it just stops working, no matter how much I click. How can I fix it?
If the number gets out of range you just block increasing & decreasing, I guess you want to always allow one of the actions:
if (op == 'soma') {
if(x >= horamax) return;
document.querySelector(".hora").innerText = x +1
} else {
if(x <= horamin) return;
document.querySelector(".hora").innerText = x -1
}
Related
I am making tetris in JS. When making a block fall, it makes the block reach the bottom of the screen in one draw instead of slowly approaching the bottom. I tried creating a variable that stores the changes to be made so that it only looks at the current board, but no luck. After checking whether the output variable is == to the board, it seems like the board is changing after all, as it returns true. What's going on?
EDIT: I have successfully made a shallow copy of the array. It still falls to the bottom immediately, though. What's going on?
var data = [];
function array(x, text) {
var y = [];
for (var i = 0; i < x-1; i++) {y.push(text);}
return y;
}
for (var i=0; i<20; i++){data.push(array(10, "b"));}
function draw(){
var j;
var i;
var dataOut = [...data];
for (i = 0; i < data.length - 1; i++){
for (j = 0; j < data[i].length; j++){
if (data[i][j] == "a" && data[i + 1][j] == "b" && i < data.length - 1) {
dataOut[i][j] = "b";
dataOut[i + 1][j] = "a";
}
}
}
data = dataOut;
}
data[0][4] = 'a';
draw();
console.log(data);
In JavaScript, Arrays and Objects are passed by reference. So when you do this:
var dataOut = data;
Both of these references point to the same Array. You could clone the Array every time:
var dataOut = JSON.parse(JSON.stringify(data));
Or simply revert your loop, to go from the bottom to the top. I took the liberty of renaming the variables to make this more clear. Try it below:
var chars = {empty: '.', block: '#'},
grid = createEmptyGrid(10, 20);
function createEmptyGrid(width, height) {
var result = [], x, y;
for (y = 0; y < height; y++) {
var row = [];
for (x = 0; x < width; x++) {
row.push(chars.empty);
}
result.push(row);
}
return result;
}
function draw() {
var x, y;
for (y = grid.length - 1; y > 0; y--) {
for (x = 0; x < grid[y].length; x++) {
if (grid[y][x] === chars.empty && grid[y - 1][x] === chars.block) {
grid[y][x] = chars.block;
grid[y - 1][x] = chars.empty;
}
}
}
}
// Just for the demo
var t = 0, loop = setInterval(function () {
draw();
if (grid[0].includes(chars.block)) {
clearInterval(loop);
grid[9] = 'GAME OVER!'.split('');
}
document.body.innerHTML = '<pre style="font-size:.6em">'
+ grid.map(row => row.join(' ')).join('\n')
+ '</pre>';
if (t % 20 === 0) {
grid[0][Math.floor(Math.random() * 10)] = chars.block;
}
t++;
}, 20);
Im working on JavaScript to get three different algorithms to work in the same code, I set up a function for each algorithm. I'm trying to get three Primality testing methods: Trial Division, the Fermat Primality Test, and the Miller-Rabin Primality Test. The first two are working fine but the Miller-Rabin isn't. I'm pretty new to JavaScript and programming in general, so if you can find where I went wrong or can think of a way to make it work, please let me know! Thanks!
// 1531 6389 68819 688889 6388819
// 68883889 688838831 1000000009
// 561 is a Carmichael number; a Fermat pseudoprime with the property a^n-1 = 1 mod n, for any "a" coprime to 561.
input = 5491763;
numTrials = 2000;
document.getElementById("input").innerHTML = input;
function TrialDiv(n) {
if (n === 1) {
return false;
} else if (n === 2) {
return true;
} else {
for (var x = 2; x < n; x++) {
if (n % x === 0) {
return false;
}
}
return true;
}
}
if ((TrialDiv(input)) === true) {
a = "Prime"
} else if ((TrialDiv(input)) === false) {
a = "Composite"
}
//---------------------------------------------------------------------------
function gcd(x, y) {
while (y !== 0) {
var z = x % y;
x = y;
y = z;
}
return x;
}
function getRndInteger(max) {
return Math.floor(Math.random() * (max - 2)) + 2;
}
//--------------------------------------------------------------------------
function Fermat(n) {
for (var t = 0; t = numTrials; t++) {
m = getRndInteger(input);
if (gcd(m, n) !== 1) {
return false;
}
}
return (Math.pow(m, n - 1) % n !== 1);
}
if ((Fermat(input)) === true) {
b = "Prime";
} else if ((Fermat(input)) === false) {
b = "Composite";
}
//---------------------------------------------------------------------------
function genD(n) { // Generates "d" such that "n-1 = 2^s * d"
var p = n - 1;
var d = p / 2;
while (d % 2 === 0) {
d = d / 2;
}
return d;
}
function genS() { // Generates "s" such that "n-1 = 2^s * d"
var s = Math.log2(p / d);
return s;
}
//---------------------------------------------------------------------------
function MillerRabin(n) {
for (var t = 0; t < numTrials; t++) {
m = getRndInteger(input);
if (gcd(m, n) !== 1) {
return false;
} else {
for (var r = 0; r < genS(); r++) {
power = (Math.pow(2, r) * genD(input));
if (Math.pow(m, genD(input)) % n === 1 || Math.pow(m, power) % n === -1) {
return true;
} else {
return false;
}
}
return true;
}
return true;
}
}
if ((MillerRabin(input)) === true) {
c = "Prime";
} else if ((MillerRabin(input)) === false) {
c = "Composite";
}
<body>
<button type="button" onclick='document.getElementById("TrialDivision").innerHTML = a; document.getElementById("FermatTest").innerHTML = b; document.getElementById("MillerRabinTest").innerHTML = c; '>Show</button>
<hr>
<b style="color:rgb(0,0,120)">PRIMALITY TESTS</b>
<p></p>
Input:
<l id="input"></l>
<hr>
<h5 style="color:rgb(160,0,0)">TRIAL DIVISION</h5>
<p></p>
Output:
<i id="TrialDivision"></i>
<hr>
<h5 style="color:rgb(160,0,0)">FERMAT PRIMALITY TEST</h5>
<p></p>
Output:
<i id="FermatTest"></i>
<hr>
<h5 style="color:rgb(160,0,0)">MILLER-RABIN PRIMALITY TEST</h5>
<p></p>
Output:
<i id="MillerRabinTest"></i>
</body>
<script>
That's how I wrote it up, this was purely created by me from the original mathematical algorithms for each test. What happens is that the Miller-Rabin Output doesn't show anything when the input number is prime; the algorithm isn't able to identify it. But it does identify composites correctly.
Please let me know of any improvements you think of!
You have some problems with loops not running. I'm not sure how the algorithm is supposed to work, so I don't if it's working or not, but the immediate problem is cause by leaky variable and variables not declared in functions (which makes them global).
The fix for this immediate problem is to declare the local variables in the functions so you don't depend on having them set by some other function.
function genD(n) { // Generates "d" such that "n-1 = 2^s * d"
var p = n - 1;
var d = p / 2;
while (d % 2 === 0) {
d = d / 2;
}
return d;
}
function genS(n) { // Generates "s" such that "n-1 = 2^s * d"
var p = n - 1
var d = p / 2
var s = Math.log2(p / d);
return s;
}
Once you start fixing the errors that crash there are a few other big problems. For example your fermat() potentially runs for ever:
for (var t = 0; t = numTrials; t++) {
Should be:
for (var t = 0; t == numTrials; t++) {
= sets t to numTrails for every loop
I think you should start at the beginning, put all your functions together and all you other logic code that calls the functions together so you can see what's going on.
I am doing my first game snake, but I have a problem which appears sometime when I eat a rectangle and try to generate another my script crashes and I have an infinite loop.
var coincide = false;
var cmpt;
do {
mangey = Math.random();
mangey *= canvas.height;
t = mangey % 20;
mangey -= t;
mangex = Math.random();
mangex *= canvas.width;
t = mangex % 20;
mangex = mangex - t;
for (cmpt = 0; cmpt < snake.length; cmpt++) {
if ((snake[cmpt][0] == mangex) && (snake[cmpt][1] == mangey)) {
coincide = true;
alert(snake);
console.log(mangex,mangey);
}
}
}
while ((coincide) || ((mangex > 480) || (mangex < 0)) || ((mangey > 380) || (mangey < 0)));
When coincide = true;, it never changes, so it is constantly true, hence the infinite loop. So I'd add an else statement:
if ((snake[cmpt][0] == mangex) && (snake[cmpt][1] == mangey))
{
coincide = true;
alert(snake);
console.log(mangex,mangey);
}
else
{
coincide = false;
}
Problem Solved , Thank you for views .
In the previous code : When we have coincide=true it will not change even when the generated rectangle do not have an intersection .
Solution is simple it's just a we suppose that coincide =false before the for loop .
Great :D
I've created an array that I now want to reverse. The array should display every number from the number specified down to 0.
I've tried using the reverse() method in various ways but it either misses out every other number in the array or returns nothing at all?
In the code below the else if statement is where the array wants reversing.
Is there a way to use the reverse() method on the array here or an alternative way to do this?
Thanks
function myFunc() {
var x = Math.floor(Math.random() * 100);
var counter = [];
var start = 0;
if (x > 40) {
start = 40;
} else {
start = 0; }
for (var i = start; i < x; i++) {
if (x > 40 && i % 2 == 1) {
counter.push(i);
} else if (x < 40) {
counter.push(i).reverse(); //reverse here returns nothing
counter.reverse(); //reverse here returns every other number only
}
}
return counter + ',' + x;
}
console.log(myFunc())
......
for (var i = start; i < x; i++) {
if ((x > 40 && i % 2 == 1) || x < 40) {
counter.push(i);
}
}
if(x<40)
counter.reverse();
return counter;
}
Should work like this.. (unless I misunderstood your problem?)
http://jsfiddle.net/aLUfh/2/
var x = Math.floor(Math.random() * 100);
var counter = [];
for (i = 0; i < x; i++) {
counter.push(i);
}
counter.reverse();
$('#Xis').html(x);
$('#outcome').html(counter + ',' + x);
I've created an array that I now want to reverse. The array should display every number from the number specified down to 0.
If this is the problem, then you can solve it easier like this:
var x = Math.floor(Math.random() * 100);
var counter = [];
var end = (x > 40 ? 40 : 0);
while (end <= x) {
counter.push(x);
--x;
}
return counter;
Demo
Try before buy
Your code however does something else, but you can adjust it like:
while (end <= x) {
if ( ((40 < x) && (1 == x % 2)) || (40 > x)) {
counter.push(x);
}
--x;
}
I'm trying to write a code that randomizes a number (1 - 100), then prints all the odd numbers from 40 to that one. If the number is smaller than 40 it should print all the numbers up to the randomized one.
i.e. if the number is 45, it should print 41, 43, 45. And if it's 5 it should print 1,2,3,4,5.
My code below works until I add the else if statement. When I add this if the number is above 40 it still includes all numbers from 0 to 40? I don't understand why as I thought if statements should go one way or another not both?
Any ideas help on how to solve this, or what i'm doing wrong?
Thanks in advance
function myFunc() {
var x = Math.floor(Math.random() * 100);
var counter = [];
for (var i = 0; i < x; i++) {
if (i > 40 && i % 2 == 1) {
counter.push(i);
} else if (i < 40) {
counter.push(i);
}
}
return counter + ',' + x;
}
console.log(myFunc())
Just add a new variable that checks where to start from. That way you can shorten the conditional in the loop too.
function myFunc() {
var x = Math.floor(Math.random() * 100);
var counter = [];
var start = x >= 40 ? 40 : 0; // new variable
for (var i = start; i < x; i++) {
if (i % 2 === 1) { counter.push(i); }
}
return counter + ',' + x;
}
console.log(myFunc())
you write not correct conditional:
else if (i < 40)
this statement is run, because first statement is false and i in progress 1,2,3,4,
you must change second statement to x < 40
function myFunc() {
var x = Math.floor(Math.random() * 100);
var counter = [];
for (var i = 0; i < x; i++) {
if (i > 40 && i % 2 == 1) {
counter.push(i);
} else if (x <= 40) { // only when x <= 40
counter.push(i);
}
}
return counter + ',' + x;
}
console.log(myFunc())