Convert arbitary string to number between 0 and 1 in Javascript - javascript

I'm working with Youtube videos which have ids like 8DnKOc6FISU, rNsrl86inpo, 5qcmCUsw4EQ (i.e. 11 characters in the set A-Za-z0-9_-)
The goal is to convert each id to a colour (represented by the range 0-1), so they can be reliably charted.
According to this question these are 64 bit numbers. Given that:
I want to make full use of the colour space for any given set of videos
Colour perception isn't that accurate anyway
...it seems sensible to base this off the last 2-3 characters of the id.
My lead approach is a function I borrowed from here, which converts each character into a binary number like so:
function toBin(str){
var st,i,j,d;
var arr = [];
var len = str.length;
for (i = 1; i<=len; i++){
d = str.charCodeAt(len-i);
for (j = 0; j < 8; j++) {
st = d%2 == '0' ? "class='zero'" : ""
arr.push(d%2);
d = Math.floor(d/2);
}
}
}
But this leaves the question of how to convert this back to a float.
Any ideas for an elegant solution?
Many thanks for your help!

Knowing that system is base 64 (26+26+10+2), just read each symbol, add it to total and multiply result by 64 on each iteration. In the end you will have an integer number. Divide it by maximum value to normalize it to 0-1 range.
You'll start losing precision when your IDs approach 253 though, as that's maximum what JS can represent in integer precisely.
Alternatively you can count in floats from the very start by adding (letter_index / 64letter_position) for each position in line, but you'd be losing more precision in process.

Related

How can I adjust inputfield rows to a number in Javascript?

I´m programming a math game where user has to transform a decimal digit into binary digit by dividing with 2. I wanted to adjust the rows to the length of the binary digit (e.g. 8 is 1000, so it shall only generate 4 rows to transform digit in a binary digit). I use display() to generate a digit from 1-31, deciToBin() to convert decimal to binary and createBoxes() to adjust rows to the length of binary digit.
But it only works for the first round. If I continue playing there are more rows than the length of the binary digit or less rows than the length of the binary digit.
Two observations:
I'm not seeing anywhere that you're ever setting any inputboxes.style.visibility to hidden. Seems like they should perhaps all get hidden before each new number sets up its boxes (kind of a "reset"). Otherwise, the way it is now, if the first number is 30 you'll display 5 boxes, and if the next number is 1, you'll still display five boxes, because the last four are still visibility:visible.
I think you could replace createBoxes(deciToBin(number).length) with createBoxes((number).toString(2).length) and just get rid of deciToBin(). toString() is standard and fast.
UPDATE: Here's an alternate createBoxes that would set all inputboxes every time there's a new number:
// untested code
function createBoxes(value) {
for (var i = 0, len = inputboxes.length; i < len; i++) {
if (i < value) {
inputboxes[i].style.visibility = "visible";
} else {
inputboxes[i].style.visibility = "hidden";
}
}
}

Find the sum of the digits in the number 100! in javascript

i am getting answer 659 but that one is wrong answer please check it one's.
this is my code
var fact=1;
for(var i=1;i<=100;i++){
fact = fact*i;
}
var sum = 0;
while (fact > 0) {
sum += fact % 10;
fact = Math.floor(fact / 10);
}
console.log(sum);
There's a syntax error in the definition of length - the var keyword should come before it, not after it, and a similar problem in the calculation of sum.
Regardless, I think that converting the number to a string is the hard way to go at it. You can use the % operator to get the last digit and divide the number by 10 (don't forget to floor!) until you're done with all the digits:
var sum = 0;
while (fact > 0) {
sum += fact % 10;
fact = Math.floor(fact / 10);
}
Cool. You've written a very sensible piece of code. But there are a couple things to think about. One is the gigantic size of 100!. If you go to a console and enter some code, you'll see this:
> fact=1
1
> for(i=1;i<=100;i++){fact *= i;}
9.33262154439441e+157
Crikey. 10 to the 157. Look up the largest integer js can display. It's much smaller! So if this is a programming assignment, you have to be more subtle.
Next, if you get the number, all 158 digits, and you want to add them using your strategy, you may need to convert the strings you get (a substring is a string, after all) to a Number.
But really, the question is, can you determine the sum of the digits without calculating the number?

Javascript split string at 160 characters and add counter?

I am looking to split a string into multiple strings at 160 characters I thought easy enough var splits = myString.split(160);
but apparently that doesn't work anyway.
The other point is that I want to add a counter (android sms style).
so lets say we have this example string (237 characters)
hi there, this message is 237 characters long, which makes it much to
long for a single message, this string will be split up into multiple
messages... this is actually for an sms application hence the reason
we need to split the string.
The final output should be
hi there, this message is 237 characters long, which makes it much to long for a single
message, this string will be split up into multiple messages... thi(1/2)
s string will be split up into multiple
messages... this is actually for an sms application hence the reason
we need to split the string.(2/2)
Now if there was always going to be 9 or less messages I could just do
//ok, so the next line won't work, but it gets the point across...
var splits = mystring.split(155);
var s = splits.length;
for(var i = 0; i < s; i++)
splits[i] += '('+(i+1)+'/'+s+')';
but the issue is that there could be anywhere up to 15 messages, so the amount of characters appended on the end is inconsistent (we want to keep the character count as low as possible to 0 padding numbers less than 10 is not an option).
How can I do this?
http://jsfiddle.net/Lobstrosity/nwaYe/
It will cut off at 160 * 15 characters (since you implied that 15 was the limit). It sets both of those numbers as variables up top so you can fiddle with either one.
Update
New fiddle: http://jsfiddle.net/Lobstrosity/nwaYe/2/
It's ugly...but it works...
It figures out if the y in (x/y) is going to be one digit or two.
It uses a placeholder in the indicators while it builds up the actual message.
It replaces the placeholders.
Finally, it splits on charLimit.
I hope someone else figures out a cleaner way to do this...
I think your best choice for getting optimal messages (i.e. max length) may be to handle each class of max message length separately.
Handle the cases where you have less than ten messages with your current code, then extend that method to cover cases where you have up to 99 messages. If there's a chance of going over 100 messages, then you could extend further, but that sounds unlikely.
Here's a code sample:
if (mystring.length < (155 * 9)) {
var splits = mystring.split(155);
var s = splits.length;
for(var i = 0; i < s; i++)
splits[i] += '('+(i+1)+'/'+s+')';
} else if (mystring.length < (154*9)+(153 * 90)) {
var splits1 = mystring.substr(0,154*9).split(154);
var splits2 = mystring.substr(154*9).split(153);
var splits = [];
var s = splits1.length + splits2.length;
for (var i = 0; i < splits1.length; i++)
splits[i] = splits1[i] + '('+(i+1)+'/'+s+')';
for (var i = 10; i < splits2.length+10; i++)
splits[i] = splits2[i-10] + '('+(i+1)+'/'+s+')';
}

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.

Unlimited-size base conversion?

I'm trying to implement a BigInt type in JavaScript using an array of integers. For now each one has an upper-bound of 256. I've finished implementing all integer operations, but I can't figure out how to convert the BigInt to its string representation. Of course, the simple way is this:
BigInt.prototype.toString = function(base) {
var s = '', total = 0, i, conv = [
,,
'01',
'012',
'0123',
'01234',
'012345',
'0123456',
'01234567',
'012345678',
'0123456789',
,
,
,
,
,
'0123456789abcdef'
];
base = base || 10;
for(i = this.bytes.length - 1; i >= 0; i--) {
total += this.bytes[i] * Math.pow(BigInt.ByteMax, this.bytes.length - 1 - i);
}
while(total) {
s = conv[base].charAt(total % base) + s;
total = Math.floor(total / base);
}
return s || '0';
};
But when the BigInts actually get big, I won't be able to convert by adding anymore. How can I convert an array of base-x to an array of base-y?
See the example I gave in this answer to a similar question recently (it's for base-10 to base-3, but the principle should be transferrable): C Fast base convert from decimal to ternary.
In summary:
Iterate over the input
digits, from low to high. For each
digit position, first calculate what
1000....000 (base-256) would be in the output representation (it's 256x the previous
power of 256). Then multiply that
result by the digit, and accumulate
into the output representation.
You will need routines that perform
multiplication and addition in the
output representation. The
multiplication routine can be written
in terms of the addition routine.
Note that I make no claims that this approach is in any way fast (I think it's O(n^2) in the number of digits); I'm sure there are algorithmically faster approaches than this.
If you're prepared to put on your math thinking cap more than I am right now, someone seems to have explained how to convert digit representations using Pascal's triangle:
http://home.ccil.org/~remlaps/DispConWeb/index.html
There are links to the source code near the bottom. They're in Java rather than JavaScript, but if you're putting in the effort to grok the math, you can probably come up with your own implementation or put in the effort to port the code...

Categories

Resources