Check/eliminate different row/columns in Backtracking function javascript - javascript

I have this code to solve a 3x3 sudoku (Only rows/columns are need to be checked, there can be 4 of the same numbers in one block, for example this is a good one:
123
231
312
)
I have the function fillsquare, with input an array [[1,2,0],[0,3,1],[3,0,2]] where the 0 need the be changed to the right number.
function fillsquare(square){
for (var a = 0; a<4; a++){
for (var b = 0; b<4; b++){
if (square[a][b] === 0){
// do the function to check whether I can enter the right number
}
else {
// ?????????????????????
}
}
}
}
According to my professor, it should be a recursive code, but I dont think this is recursive, anyways this base will work.
I still need to change the 0's to the number that fits in place.
I have a small clue how to do this with bruteforce/backtracking, but no code to achieve this.
enter 1 in the zero, if there isn't a one in the row or column, continue to the next zero. Else enter 2 and check again etc.
I hope you can help!
PS: My prof. gave me this psuedocode for checking etc.:
function fillSquare(square) {
find first 0 in square
if (there is no 0) {done!}
else {determine every value that can be put on the place with the zero
(check column and row) save them for example in a temprary row
for (every possible value) {
fillSquare(square with value filled in place)
}
}
}
I hope this is a bit clear, it is translated;)

Related

Add elements up to your intended value

I want to add cards from the deck until I get 17 or more if the dealer's total doesn't exceed 17.
Where the error occurs.
When the total value of two cards is not 17 or more, I want to add cards until it becomes 17 or more.
However, with this code, I tried to add cards until I got 17 or more, but I added the same card as the second card (the card that was turned up by pressing the stand button). It's closed.
How do I add cards until I reach 17 or above?
The problem is caused by your for loop, after calling dealer_3Img in function turnDealer, there is a "break", commented below:
function turnDealer(dealerTotal) {
if(dealerTotal < 17){
for (let i = dealerTotal; dealerTotal < 17; i++) {
console.log(i);
//Get a new card from the array
var card = deck.pop();
dealer_3Img(card);
break //this will exit the loop
}
}
}
please read the usage of "break": The break statement "jumps out" of a loop.
https://www.w3schools.com/js/js_break.asp
To fix the problem, you can use while as #Aaron suggested, you can use while loop to solve your problem: https://www.w3schools.com/js/js_loop_while.asp
Try changing your code to:
function turnDealer(dealerTotal) {
while (dealerTotal < 17) {
console.log(i);
//Get a new card from the array
var card = deck.pop();
//need to update dealerTotal here, e.g. dealerTotal += card
dealer_3Img(card);
}
}
Forgive me but I don't play cards much.. I'm not sure if each card has a different dealerTotal so my example is treating value 17 as 17 cards
// If the dealer does not exceed 17, add cards until it exceeds 17.
function turnDealer (dealerTotal) {
var card = deck.pop()
var cardValue=1 //if cardValue is ever not 1, set it to whatever(since idk)
if (dealerTotal <17) {return turnDealer(dealerTotal+cardValue)}
return true //it has finished selecting
//usage: turnDealer(1) would make it take 17 cards, turnDealer(0) would make it take 18, turnDealer(2) would make it take 16 and so on
}

Selecting a percentage % of a batch in FOR loop using javascript

I am working with javascript and i have a loop that selects all the data rows.
The number of rows can be different each time and I do not want to select ALL rows at a time. I want to get rows in 10% batches so performance is better.
Currently i am trying this approach but needs your suggestion is this is a right approach or if there is any better approach?
var TenPercBatch = 0.1;
// for (i in data) {
for (var i = 0; i < data.length*TenPercBatch; ++i) {
var row = data[i];
var emailAddress = row[0]; // First column
var emailSent = row[1]; // Second column
if (emailSent != EMAIL_SENT) { // Prevents sending duplicates
//PRODUCTION EMAIL FORM LINK
var url = "https://www.mysiteformurl-endpoint.com";
UrlFetchApp.fetch(url + '&EMAILADDRESS=' + encodeURIComponent(emailAddress));
AudienceList.getRange(startRow + i, 2).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
}
}
Depending on number of rows, there are times when i get output in decimal when i calculate 10% of something manually...like 1000 rows, 10% would be 100..but if I have 5 rows, 10% would be 0.5. Is there any way to get the output in non-decimal closest number only so there are no issues in the code?
Like...if 10% is 0.5 then use 1.....if 10% is 7.5 then select 8...and so on...
Is it possible?
Another question is - How to select next 10% only? As I am looking at my loop, I am thinking it MAY always select same 10% batch.
In math there is a function called ceiling with always rounds non-whole numbers to the next integer, e.g. Math.ceil(3) == 3 and Math.ceil(3.1) == 4.
To be safe, you best want to do something like this, although I am unsure as to why you would want to do this in general.
for(var a = 0; a < 10; a++)
{
for(var i = Math.floor(a*data.length*0.1); i < data.length && i < Math.ceil((a+1)*data.length*0.1); i++)
{
//do stuff within batch
}
//do stuff in between batches
}
The inner loop iterates of the the a-th 10% of the data object. If you just want to iterate over the first 10% just set a to 0 instead of the outer for-loop.
Sure it is, use Math.ceil( ) function :)

How to find total possible values from length and characters?

I'm totally not a Math whiz kid here, but have put together a function with the great help of StackOverflow (and a lot of trial and error) that generates a random serial number from a Formula, group of Letters/Numbers, and array (so as to not duplicate values).
So, my current formula is as follows:
$.extend({
generateSerial: function(formula, chrs, checks) {
var formula = formula && formula != "" ? formula : 'XXX-XXX-XXX-XXX-XXX', // Default Formula to use, should change to what's most commonly used!
chrs = chrs && chrs != "" ? chrs : "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", // Default characters to randomize, if not defined!
len = (formula.match(/X/g) || []).length,
indices = [],
rand;
// Get all "-" char indexes
for(var i=0; i < formula.length; i++) {
if (formula[i] === "-") indices.push(i);
}
do {
rand = Array(len).join().split(',').map(function() {
return chrs.charAt(Math.floor(Math.random() * chrs.length));
}).join('');
// Rebuild string!
if (indices && indices.length > 0)
{
for(var x=0; x < indices.length; x++)
rand = rand.insert(indices[x], '-');
}
} while (checks && $.inArray(rand, checks) !== -1);
return rand;
}
});
Ok, so, what I need to be able to do is to find total possible values and make sure that it is possible to generate a unique serial number before actually doing so.
For example:
var num = $.generateSerial('XX', 'AB', new Array('AB', 'BA', 'AA', 'BB'));
This will cause the code to do an infinite loop, since there are no more possibilties here, other than the ones being excluded from the extension. So this will cause browser to crash. What I need to be able to do here is to be able to get the number of possible unique values here and if it is greater than 0, continue, otherwise, don't continue, maybe an alert for an error would be fine.
Also, keep in mind, could also do this in a loop so as to not repeat serials already generated:
var currSerials = [];
for (var x = 0; x < 5; x++)
{
var output = $.generateSerial('XXX-XXX-XXX', '0123456789', currSerials);
currSerials.push(output);
}
But the important thing here, is how to get total possible unique values from within the generateSerial function itself? We have the length, characters, and exclusions array also in here (checks). This would seem more like a math question, and I'm not expert in Math. Could use some help here.
Thanks guys :)
Here is a jsFiddle of it working nicely because there are more possible choices than 16: http://jsfiddle.net/qpw66bwb/1/
And here is a jsFiddle of the problem I am facing: Just click the "Generate Serials" button to see the problem (it continuously loops, never finishes), it wants to create 16 serials, but 16 possible choices are not even possible with 2 characters and only using A and B characters: http://jsfiddle.net/qpw66bwb/2/
I need to catch the loop here and exit out of it, if it is not able to generate a random number somehow. But how?
The number of possible serials is len * chrs.length, assuming all the characters in chrs are different. The serial contains len characters to fill in randomly, and chrs.length is the number of possible characters in each position of that.

Finding the smallest multiple

I'm trying to learn and practice javascript on my own and I've made a bit of progress but I can still get stuck with elementary problems. I think my code is really close to giving me the correct answer but I fail to see what issue I'm missing. If someone better at coding would please take a second and fill me in on what logic error I have, I would be greatly appreciative!
<script>
//2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
var input = 11;
function smallestMultiple(){
for(var i = 2; i <= 10; i++){
if(input % i === 0 && isDivisible(input))
alert(input);//this should only alert when input is divisible by all numbers between 2 and 10
}else{
input ++;
//if input isn't divisible by all numbers between 2 and 10, increment input by 1
}
}
};
// The following function should return true when "input" is divisible by 10, which is the trigger for alerting "input"
function isDivisible(input){
if(input % 10 === 0){
return true;
}else{
return false;
}
};
smallestMultiple();
</script>
Your script is going to find the smallest integer that's divisible both by 10 and a number in 2,3,...,9, which is not what you need.
The faster implementation would probably be setting a couple of temporary divisors that shrinks until the left edge surpass the right one ...
The simplest instead is just selecting a number in 1,2,3...,9, then try to divide it for every number in 1,2,3...,9
The following html sandbox (to remain on-topic) would probably help you to understand.
<html>
<head>
<meta charset="utf8">
</head>
<body>
<div>
<p class="output"></p>
</div>
<script>
window.onload = function() {
function smallest_shared_multiple(from, to) {
var tmp_divisor = from
var tmp_candidate = tmp_divisor
for(;tmp_divisor < to +1;) {
if (tmp_candidate % tmp_divisor) {
tmp_divisor = from
tmp_candidate++
} else {
tmp_divisor++
}
}
return tmp_candidate
}
document.querySelector('p.output').innerHTML =
'For the given range, the smallest shared multiple is ' +
smallest_shared_multiple(1, 10)
}
</script>
</body>
</html>
edit: Please, consider to indent your code before posting. Moreover, as a general rule of programming, it's better naming functions in way that's evocative to what they're supposed to do. ..and make variables' scope the smallest you can. :)

Elegant way to bias random boolean

I'd like to create a random boolean in JavaScript, but I want to take the previous value into account. If the previous value was true, I want it to be more likely for the next value to be true. At the moment I've got this (this is in the context of a closure - goUp and lastGoUp are locals to the containing scope):
function setGoUp() {
goUp = getRandomBoolean();
if(lastGoUp) {
goUp = getRandomBoolean() || goUp;
}
else {
goUp = getRandomBoolean() && goUp;
}
lastGoUp = goUp;
}
So, the algorithm goes:
Get a random boolean
If the random boolean from the previous call was True:
a) get another random boolean, and or these two together
b) else get another random boolean and and these together.
I'm sure this algorithm could be simplified. I wondered about doing:
if(lastGoUp && goUp) {
goUp = goUp * (getRandomBoolean() || goUp);
}
but that seems really dirty.
There's also a problem with this algorithm which means that I can only double the chance of getting the same boolean again - I can't tweak it easily. Any ideas?
You should define the distribution you want, but maybe you are looking for the following?
if (lastGoUp) {
goUp = Math.random() < 0.8;
} else {
goUp = Math.random() < 0.2;
}
Instead of getting a random boolean, get a random number, say between 0 and 99. Keep a threshold value instead of the last number, and adjust the threshold according to the result:
var threshold = 50;
function setGoUp() {
goUp = getRandomNumber() < threshold;
threshold += goUp ? -10 : 10;
}
This would keep a running tab, so if you get consecutive results that are the same, the probability would keep falling for that result.
If you only want to consider the last result, you would instead set the threshold to a specific value:
threshold = goUp ? 40 : 60;
If you only want the probability of the next event to depend on the current value, and not the history of values up til now, what you want is called a Markov process. Often these are implemented with a 2D table of probabilities that you look up (prob of each next outcome given current one), but for a simple bool-valued event, an if statement is sufficient (see meriton's answer; note that it corresponds to a table of probabilities [0.8 0.2; 0.2 0.8]).
If you want something that gets more likely, say, the more successes you get in a row, then you need to devise a sequence of probabilities for success that perhaps approaches, but does not exceed, 1. There are any number of formulas which can do this, depending on how strong you want the bias to become and how quickly you want it to get there.
I would just make the probability of getting value true be an explicit float variable p. Then I could tweak it easily, by increasing p in some way if I got true last time or by doing nothing with it if I got 'false'.
Can replace Math.random for a better randomizer.
var setGoUp = (function(){
var last;
return function(){
// if last 66% chance for true else 50% chance of true.
return !!(last ? Math.random()*3 : Math.random()*2);
}
}());
!! converts anything to a boolean, 0 = false.

Categories