How many unique jsbin url shortcode combinations can exist? - javascript

This is jsbin's function that generates each bin's identification shortcode:
function shortcode() {
var vowels = 'aeiou',
consonants = 'bcdfghjklmnpqrstvwxyz',
word = '', length = 6, index = 0, set;
for (; index < length; index += 1) {
set = (index % 2 === 0) ? vowels : consonants;
word += set[Math.floor(Math.random() * set.length)];
}
return word;
}
How many different combinations could it produce? If I've calculated well, there are 3.08915776e+8 combinations when using 6 letters from a set of 26 letters(a-z). But how would this be calculated, since there are sets of 5(vowels) and sets of 21(consonants) alternating to produce memorizable shortcodes like 'ecamit', 'izafij', 'erowih', 'avimog' etc...
Would that be (5x21)^3 = 121,550,625 ?

The shortcode method was recently updated because we kept hitting duplicates too often, and in fact the version of code you see also appended numbers on the end to increase force them to become unique.
I believe the number of variations, based on this code alone (the code above, not what's in jsbin's production code base) is: 1,157,625 (5 * 21 * 5 * 21 * 5 * 21) - which really isn't much.
The simple method comes from my old password generator: http://remysharp.com/2008/04/14/pronounceablely-random/ - but recently I had to change it in jsbin's production.
It now keeps adding characters on each positive hit on the database, but also the letters are duplicated in uppercase, so the range of url combinations are much much higher now.

Related

Get every possible combination of numbers (fastest possible method)

I am trying to get every single combination of elements into an array. Now I can use the method below, and remove the duplicates, but this way is far to slow for my use.
The code below would find every possible combination for 2 digits below 4. Now in the code I actually want to use this for, the least possible code would be 6 for loops (within each other) with the amount being 18 (rememeber this is the minimum).
The code below would execute amount^[amount of for loops], or amount^2 which in this case is 16. That means that in the code I want to use this for, it executes 18^6 times, or 34 million times. And this is the minimum, which would get much higher.
After trying to run my code (with 6 foor loops in which amount = 18), it crashed my browser... My question is: Is there any faster and more efficient (not elegant. I don't care how elegant it is) in which my browser won't crash?
Note: This question is not a duplicate question. All the other questions simply ask for a way to do this, however I already have a way. I am just trying to make it more efficient and faster so that it actually works correctly.
let combinations = [];
let amount = 4;
for (let a = 0; a < amount; a++) {
for (let b = 0; b < amount; b++) {
combinations.push(`${a}${b}`);
}
}
console.log(combinations);
Below is a snippet providing a possible example for how my code would work.
let possibilities = [];
let amount = 6; //Amount is set by me, so don't worry about it being incorrect
for (let a = 0; a < amount; a++) {
for (let b = 0; b < amount; b++) {
possibilities.push(a + b);
}
}
possibilities = [...new Set(possibilities)]; //Removes duplicates
possibilities.sort((a, b) => b - a); //Sorts in descending order
possibilities = possibilities.slice(0, 3); //Gets top 3 values
console.log(possibilities);
Ok, as discussed in the comments, if you need top 3 values for a particular amount, you could just do something simple like below:
let amount = 6;
let highest = amount - 1,second_highest = amount - 2,third_highest = amount - 3;
let possibilities = [
highest + highest,
highest + second_highest,
highest + third_highest
];
console.log(possibilities);
I don't know the any better solution for this, but yes there are some conditions you need to check first.
If(amount <= 0) return 'Invalid amount, Please enter a valid amount"
So if somebody enters a negative or zero value your loop will goes into infinite loop, and make the situation more worst.
if(amount === 1) return '1 possible combination'
As amount less than 1 is 0 only and combinations for 0 is 1 only, you need not to parse whole loop for 6 digits or n digits for 0 so it will get solve in complexity of 1 instead of N(no. of digits).
And for amount greater then 1 you can create manual loops, like here you created 2 loops for 2 digits, you create 6 loops for 6 digits, better create dynamic logic for this to create number of loops automatically.
You need to consider 1111, 1112 this type of combinations as well right?
Or if only 1234, 2134, 2314 this kind of scenarios are required? This can be done in very less complexity.
For duplication you can store combinations as a key value pair. and then Object.Keys will be your combinations.

Divide number into equal parts such that none of the parts exceed another number

Pretty much the title; I'm looking for a way to take a number (say 78, for example) and divide it into the minimum number of equal parts that don't exceed another number (say 25, for example). The number of parts doesn't matter, it should just be as small as possible - this means that the resulting numbers should all be as large as possible.
For some context, the reason I want to do this is to work with even text splitting. The messaging service I'm working with only allows 25 lines per message, so I split my text into multiple messages, but I don't want to have messages with only one or two lines. To this end, I'd like to split the text every n lines, where n is as close to 25 as possible and creates as even of a split across the messages as possible. The number of resulting messages doesn't matter at all, though, so it's not a concern.
After some blind bumbling, I managed to solve the issue.
out = [list]
if(list.split("\n").length > 25) {
n = list.split("\n").length
x = Math.floor(n / 25)
y = n / x
while(y > 25) {
x += 1
y = n / x
}
out = []
while(list) {
l25 = list.split(/\r?\n/, Math.ceil(y)).join("\n")
list = list.slice(l25.length)
out.push(l25)
}
}
// Send each value in out as a separate message
Where list is the string to split and out is the resulting array of strings.

Determining Powers of 2?

I am creating a simple bracket system and I need a way to check if there are a correct number of teams, OR if my program needs to compensate for bye rounds.
Right now, I am checking for "powers of two" with this function:
function validBracket(data) {
var x = data.teams.length;
return ((x != 0) && !(x & (x - 1)));
}
This works pretty well, but I am needing to know how many Bye rounds to add.
For instance, if I had 16 teams, I would not need to add anymore teams. However, if I had 12 teams, I would need the first 4 teams to get a bye round.
How can I calculate number of bye rounds to add to my bracket? And would hard-coding an array of powers of two be better?
In pseudo code, something like this is what i was thinking of:
if(validateBracket(data)) {
// Valid number of teams (power of two). Keep going.
} else {
var byeRounds = calculateByeRounds();
}
NOTE: I would rather not use an array of powers of two like below:
var powersOfTwo = [2,4,8,16,32,...];
The reasoning behind this is that I would be limiting the number of teams that could be put in the system (however, I don't think a person would have over 256 teams).
var needed = (1 << Math.ceil(Math.log2(n))) - n;
More generalized solution for extreme cases:
var needed = Math.pow(2, Math.ceil(Math.log2(n))) - n;

Random number in JavaScript per day once

I'm in the process of coding an application that does the following:
Generates a random number with 4 digits.
Changes it once per calendar day.
Won't change that full day. Only once in a day.
I tried:
function my_doubt()
{
var place = document.getElementById("my_div")
place.innerHTML=Math.floor((Math.random()*100)+1);
}
I'm getting a random number with Math.random(). However, I'm rather clueless about how to generate a different number for each day. What are some common approaches for tackling this problem?
Note: It doesn't have to be really random. A pseudo - random number is also OK.
You need to seed the random number generator with a number derived from the current date, for example "20130927" for today.
You haven't been clear about your requirements, so I don't know how random you need (do you have requirements for how uniform of a distribution you need?).
This will generate a random looking 4 digit number which may be good enough for your requirements, but if you perform an analysis you'll find the number isn't actually very random:
function rand_from_seed(x, iterations){
iterations = iterations || 100;
for(var i = 0; i < iterations; i++)
x = (x ^ (x << 1) ^ (x >> 1)) % 10000;
return x;
}
var random = rand_from_seed(~~((new Date)/86400000)); // Seed with the epoch day.
Now that your question is a bit more reasonable, clear and nicer in tone. I can give you a way to get the same result on the client-side. However as others mentioned, to maintain consistency, you probably want to maintain the number on the server to ensure consistency.
var oneDayInMs = 1000*60*60*24;
var currentTimeInMs = new Date().getTime(); // UTC time
var timeInDays = Math.floor(currentTimeInMs / oneDayInMs);
var numberForToday = timeInDays % 9999;
console.log(numberForToday);
// zero-filling of numbers less than four digits might be optional for you
// zero-filled value will be a string to maintain its leading 0s
var fourDigitNumber = numberForToday.toString();
while(fourDigitNumber.length < 4)
{
fourDigitNumber = 0+fourDigitNumber;
}
console.log(fourDigitNumber);
// remember that this number rotates every and is unique for 10000 days
1)create a random number in javascript
2)store in cookie that will expire after one day
3)get value from cookie, if it does not exist goto 1

How is randomness achieved with Math.random in javascript?

How is randomness achieved with Math.random in javascript? I've made something that picks between around 50 different options randomly. I'm wondering how comfortable I should be with using Math.random to get my randomness.
From the specifications:
random():
Returns a Number value with positive
sign, greater than or equal to 0 but
less than 1, chosen randomly or pseudo
randomly with approximately uniform
distribution over that range, using an
implementation-dependent algorithm or
strategy. This function takes no
arguments.
So the answer is that it depends on what JavaScript engine you're using.
I'm not sure if all browsers use the same strategy or what that strategy is unfortunately
It should be fine for your purposes. Only if you're doing a large amount of numbers would you begin to see a pattern
Using Math.random() is fine if you're not centrally pooling & using the results, i.e. for OAuth.
For example, our site used Math.random() to generate random "nonce" strings for use with OAuth. The original JavaScript library did this by choosing a character from a predetermined list using Math.random(): i.e.
for (var i = 0; i < length; ++i) {
var rnum = Math.floor(Math.random() * chars.length);
result += chars.substring(rnum, rnum+1);
}
The problem is, users were getting duplicate nonce strings (even using a 10 character length - theoretically ~10^18 combinations), usually within a few seconds of each other. My guess this is due to Math.random() seeding from the timestamp, as one of the other posters mentioned.
The exact implementation can of course differ somewhat depending on the browser, but they all use some kind of pseudo random number generator. Although it's not really random, it's certainly good enough for all general purposes.
You should only be worried about the randomness if you are using it for something that needs exceptionally good randomness, like encryption or simulating a game of chance in play for money, but then you would hardly use Javascript anyway.
It's 100% random enough for your purposes. It's seeded by time, so every time you run it, you'll get different results.
Paste this into your browsers address bar...
javascript:alert(Math.random() * 2 > 1);
and press [Enter] a few times... I got "true, false, false, true" - random enough :)
This is a little overkill...but, I couldn't resist doing this :)
You can execute this in your browser address bar. It generates a random number between 0 and 4, 100000 times. And outputs the number of times each number was generated and the number of times one random number followed the other.
I executed this in Firefox 3.5.2. All the numbers seem to be about equal - indicating no bias, and no obvious pattern in the way the numbers are generated.
javascript:
var max = 5;
var transitions = new Array(max);
var frequency = new Array(max);
for (var i = 0; i < max; i++)
{
transitions[i] = new Array(max);
}
var old = 0, curr = 0;
for (var i = 0; i < 100000; i++)
{
curr = Math.floor(Math.random()*max);
if (frequency[curr] === undefined)
{
frequency[curr] = -1;
}
frequency[curr] += 1;
if (transitions[old][curr] === undefined)
{
transitions[old][curr] = -1;
}
transitions[old][curr] += 1;
old = curr;
}
alert(frequency);
alert(transitions);

Categories