Counting rounds in a tournament - javascript

I've written a huge page in JavaScript for a tournament I'm hosting on a game. I've gotten everything I really need worked out into arrays, but I want to add rounds. The whole script adjusts to tournament settings (for more in the future) and I'd like this to adjust itself as well. So, let's say the tournament settings are [game,teamsize,entrylimit]. The entrylimit will be the key to finding the solution, because that decides the rounds. It works in a tree system (or however it's called). Let's say the entrylimit is 8. That means the first round will consist of 4 matches, and the second will consist of 2. If the entrylimit were 16, then the first round would consist of 8 matches, the second would consist of 4, and the third would consist of 2. I want to find a way to stick this into my loop where matches are written, and use the entrylimit and match number to generate the round number. All I need is a formula that can use those two variables to get my desired result. Also I apologize for the excessive amount of detail.

If I understand the problem, here's an example of how the entrylimit can get the number of rounds and the number of matches in each round.
Calculations:
var entrylimit=16;
var amount_of_rounds = Math.log(entrylimit) / Math.log(2);
for(i=amount_of_rounds; i>0; i--)
{
s = 'Round '+(amount_of_rounds-i+1)+' of '+amount_of_rounds+' consist of '+Math.pow(2, i-1)+' matches';
alert(s);
}
​

Try this:
var entryInfo = [];
function populateEntryInfo(entryLimit)
{
entryInfo = [];
var i = entryLimit;
while(i>1)
{
i = i/2;
entryInfo.push(i);
}
entryInfo.push(i);
}

Related

Finding volume and item count using regular expressions

I am currently building a JavaScript web scraper for a grocery store that processes a title of a product and then returns the item count, volume and price per litre of a product. Most of the product titles look something like this:
Coca cola (vanilla flavour) 12 x 330 mL
In order to obtain meta data about this product, I have written a Regular Expression. It will look for look for a word boundary followed by a 1 or 2 digit number, whitespace, the string 'x', another whitespace and finally a 1, 2 or 3 digit number:
const filter = new RegExp(/\b\d{1,2}\sx\s\d{1,3}/);
I then test each result for a match with the Regular Expression and then calculate the item count, item volume, volume in litres and then the price per litre.
if (result.title.match(filter)) {
result.itemCount = parseInt(result.title.match(/\d{1}\s/));
result.itemVolume = parseInt(result.title.match(/\d{2,3}\s/));
result.litreVolume = (result.itemCount * result.itemVolume) / 1000;
result.pricePerLitre = +(result.price / result.litreVolume).toFixed(2);
} else {
result.itemCount = 1;
result.itemVolume = parseInt(result.title.match(/\d{2,3}\s/));
result.litreVolume = result.itemVolume / 1000;
result.pricePerLitre = +(result.price / result.litreVolume).toFixed(2);
}
90% of the results look good, but sometimes I get unexpected results. For example:
an item count of NaN, which may have to do with the fact that some titles contain several more numbers (Coca Cola (4-Way) 12 x 330 mL))
a volume of Infinity
a price per litre that is way too high
Clearly I am doing something wrong with my approach to calculating the desired meta data. What would be a better way of doing calculations with RegEx? Am I missing something that would make my calculations less prone to errors?
If i understand correctly filter \b\d{1,2}\sx\s\d{1,3} works, but your sub filters do not (\d{1}\s)...
I only used to using regex in c# but, i saw you could use groups in java also.
change your pattern to (\b\d{1,2})\sx\s(\d{1,3}). When you put brackets in your regex, that part becomes a group that you can acces afterwards.
As i said, i haven't used java in a few years, but i picked this code snippet from the web. It shows how to use groups in java. As pattern you should use the (\b\d{1,2})\sx\s(\d{1,3}). If it is the same as in c# group(0) is the whole result, group(1) is your first actual group, group(2) is the second.
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find( )) {
System.out.println("Found value: " + m.group(0) );
System.out.println("Found value: " + m.group(1) );
}
I think you can write it with less code than stated above, but you get the picture ;-)

How to determine the time and space complexity of this algorithm?

As I am preparing for an upcoming interview I worked on the string permutations problem. -
Problem statement - Write a function for generating all permutations of an input string.
Here's the solution that I feel is pretty good.
function getPermutations(string) {
// base case
if (string.length <= 1) {
return new Set(string);
}
var allCharsExceptLast = string.slice(0, -1);
var lastChar = string[string.length - 1];
// recursive call: get all possible permutations for all chars except last
var permutationsOfAllCharsExceptLast = getPermutations(allCharsExceptLast);
// put the last char in all possible positions for each of the above permutations
var permutations = new Set();
permutationsOfAllCharsExceptLast.forEach(function(permutationOfAllCharsExceptLast) {
for (var position = 0; position <= allCharsExceptLast.length; position++) {
var permutation = permutationOfAllCharsExceptLast.slice(0, position) + lastChar + permutationOfAllCharsExceptLast.slice(position);
permutations.add(permutation);
}
});
return permutations;
}
Even though I understand the solution (took me a few tries and about a million console logs), recursion confuses the crap out of me. Would someone please break down time and space complexity for me?
Let's think about the process. Say our String is n characters long. First, we must pass over each character in the string (n operations), and then for each character, recursively generate a permutation of the other n-1 characters in the string, from which we will for each 2nd character, recursively generate a permuation of n-2 chars in the string, and so on... until there is only 1 char left. To calculate the total time complexity, we multiply all these terms together (n * (n-1) * (n-2) * ... * 1 = n!), getting a time complexity in Big-O notation of O(n!).
To think about why we multiply them, we can think of the much simpler problem as follows: How many different permutations are there of clothes to wear if we have 2 pairs of pants and 3 shirts. The answer is clearly six, and we get this by noting that for each shirt, we have two choices for pants, so we take the number of shirts and multiply by the number of pants.
We can translate this example to a easy string, say the word "cat". To get every permutation, your code first chooses a character (it does not matter what order you choose the characters in, so I will first choose the 'c'), and then find the permutations in the remaining string, in this case "at". It is trivial that the only two permuations of this are "at" and "ta", so we add the strings "atc" and "tac" to overall permutations. Next, we take out 'a', and the remaining String is "ct", from which the permutations are "ct" and "tc". Thus, we add "cta" and "tca" to our overall permutations. Finally, doing the same thing when we take out 't', we end up with "ca" and "ac" as our remaining permutations, so we add "cat" and "act" to our overall permuations, and we are done. Notice that in this case they are all unique, but if a letter had been duplicated, (such as in "wow"), then your algorithm will double count, which is okay, as this not really necessary to account for.
Anyway, hope this helps, please leave a comment if you have an additional question.

Find numbers at a specific position

I'm trying to find an expression for JavaScript which gives me the two characters at a specific position.
It's always the same call so its may be not too complicated.
I have always a 10 char long number and i want to replace the first two, the two at place 3 and 4 or the two at place 5 and 6 and so on.
So far I've done this:
number.replace(/\d{2}/, index));
this replace my first 2 digits with 2 others digits.
but now I want to include some variables at which position the digits should be replaced, something like:
number.replace(/\d{atposx,atpox+1}/, index));
that means:
01234567891
and I want sometimes to replace 01 with 02 and sometimes 23 with 56.
(or something like this with other numbers).
I hope I pointed out what I want.
This function works fine:
function replaceChars(input, startPos, replacement){
return input.substring(0,startPos) +
replacement +
input.substring(startPos+replacement.length)
}
Usage:
replaceChars("0123456789",2,"55") // output: 0155456789
Live example: http://jsfiddle.net/FnkpT/
Numbers are fairly easily interpreted as strings in JS. So, if you're working with an actual number (i.e. 9876543210) and not a number that's represented by a string (i.e. '987654321'), just turn the number into a string (''.concat(number); ) and don't limit yourself to the constraints of what you can do with just numbers.
Both of the above examples are fine (bah, they beat me to it), but you can even think about it like this:
var numberString = ''.concat(number);
var numberChunks = numberString.match(/(\d{2})/g);
You've now got an array of chunks that you can either walk through, switch through, or whatever other kind of flow you want to follow. When you're done, just say...
numberString = numberChunks.join('');
number = parseInt(numberString, 10);
You've got your number back as a native number (or skip the last part to just get the string back). And, aside from that, if you're doing multiple replacements.. the more replacements you do in the number, the more efficient breaking it up into chunks and dealing with the chunks are. I did a quick test, and running the 'replaceChars' function was faster on a single change, but will be slower than just splitting into an array if you're doing two or more changes to the data.
Hope that makes sense!
You can try this
function replaceAtIndex(str,value,index) {
return str.substr(0,index)+value+str.substr(index+value.length);
}
replaceAtIndex('0123456789','X',3); // returns "012X456789"
replaceAtIndex('0123456789','XY',3); // returns "012XY56789"

Chunk a string every odd and even position

I know nothing about javascript.
Assuming the string "3005600008000", I need to find a way to multiply all the digits in the odd numbered positions by 2 and the digits in the even numbered positions by 1.
This pseudo code I wrote outputs (I think) TRUE for the odd numbers (i.e. "0"),
var camid;
var LN= camid.length;
var mychar = camid.charAt(LN%2);
var arr = new Array(camid);
for(var i=0; i<arr.length; i++) {
var value = arr[i]%2;
Alert(i =" "+value);
}
I am not sure this is right: I don't believe it's chunking/splitting the string at odd (And later even) positions.
How do I that? Can you please provide some hints?
/=================================================/
My goal is to implement in a web page a validation routine for a smartcard id number.
The logic I am trying to implement is as follows:
· 1) Starting from the left, multiply all the digits in the odd numbered positions by 2 and the digits in the even numbered positions by 1.
· 2) If the result of a multiplication of a single digit by 2 results in a two-digit number (say "7 x 2 = 14"), add the digits of the result together to produce a new single-digit result ("1+4=5").
· 3) Add all single-digit results together.
· 4) The check digit is the amount you must add to this result in order to reach the next highest multiple of ten. For instance, if the sum in step #3 is 22, to reach the next highest multiple of 10 (which is 30) you must add 8 to 22. Thus the check digit is 8.
That is the whole idea. Google searches on smartcard id validation returned nothing and I am beginning to think this is overkill to do this in Javascript...
Any input welcome.
var theArray = camid.split(''); // create an array entry for each digit in camid
var size = theArray.length, i, eachValue;
for(i = 0; i < size; i++) { // iterate over each digit
eachValue = parseInt(theArray[i], 10); // test each string digit for an integer
if(!isNaN(eachValue)) {
alert((eachValue % 2) ? eachValue * 2 : eachValue); // if mod outputs 1 / true (due to odd number) multiply the value by 2. If mod outputs 0 / false output value
}
}
I discovered that what I am trying to do is called a Luhn validation.
I found an algorithm right here.
http://sites.google.com/site/abapexamples/javascript/luhn-validation
Thanks for taking the time to help me out. Much appreciated.
It looks like you might be building to a Luhn validation. If so, notice that you need to count odd/even from the RIGHT not the left of the string.

Influence Math.random()

I'm looking for a way to influence Math.random().
I have this function to generate a number from min to max:
var rand = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Is there a way to make it more likely to get a low and high number than a number in the middle?
For example; rand(0, 10) would return more of 0,1,9,10 than the rest.
Is there a way to make it more likely to get a low and high number than a number in the middle?
Yes. You want to change the distribution of the numbers generated.
http://en.wikipedia.org/wiki/Random_number_generation#Generation_from_a_probability_distribution
One simple solution would be to generate an array with say, 100 elements.
In those 100 elements represent the numbers you are interested in more frequently.
As a simple example, say you wanted number 1 and 10 to show up more frequently, you could overrepresent it in the array. ie. have number one in the array 20 times, number 10 in the array 20 times, and the rest of the numbers in there distributed evenly. Then use a random number between 0-100 as the array index. This will increase your probability of getting a 1 or a 10 versus the other numbers.
You need a distribution map. Mapping from random output [0,1] to your desired distribution outcome. like [0,.3] will yield 0, [.3,.5] will yield 1, and so on.
Sure. It's not entirely clear whether you want a smooth rolloff so (for example) 2 and 8 are returned more often than 5 or 6, but the general idea works either way.
The typical way to do this is to generate a larger range of numbers than you'll output. For example, lets start with 5 as the base line occurring with frequency N. Let's assume that you want 4 or 7 to occur at frequency 2N, 3 or 8 at frequency 3N, 2 or 9 and frequency 4N and 0 or 10 at frequency 5N.
Adding those up, we need values from 1 to 29 (or 0 to 28, or whatever) from the generator. Any of the first 5 gives an output of 0. Any of the next 4 gives and output of 1. Any of the next 3 gives an output of 2, and so on.
Of course, this doesn't change the values returned by the original generator -- it just lets us write a generator of our own that produces numbers following the distribution we've chosen.
Not really. There is a sequence of numbers that are generated based off the seed. Your random numbers come from the sequence. When you call random, you are grabbing the next element of the sequence.
Can you influence the output of Math.random in javascript (which runs client side)?
No. At least not in any feasible/practical manner.
But what you could do is to create your own random number generator that produces number in the distribution that you need.
There are probably an infinite number of ways of doing it, and you might want to think about the exact shape/curvature of the probability function.
It can be probably be done in one line, but here is a multi-line approach that uses your existing function definition (named rand, here):
var dd = rand(1,5) + rand(0,5);
var result;
if (dd > 5)
result = dd - 5;
else result = 6 - dd;
One basic result is that if U is a random variable with uniform distribution and F is the cumulative distribution you want to sample from, then Y = G(X) where G is the inverse of F has F as its cumulative distribution. This might not necessarily be the most efficient way of doing and generating random numbers from all sort of distributions is a research subfield in and of itself. But for a simple transformation it might just do the trick. Like in your case, F(x) could be 4*(x-.5)^3+.5, it seems to satisfy all constraints and is easy to invert and use as a transformation of the basic random number generator.

Categories

Resources