reduction of complexity numbers procedure - javascript

I'm looking for a solution to my problem
if I have numbers
var first = 14:1
var next = 13:8
therefore, the console should give a result
console.log(first_result) // 141
console.log(next_result) // 141
and I want the numbers counted like 141 in the result to be
simply if there is an example
13:8 if both digits are the last, 3 and 8 are bigger than ten, then turn the tens and turn and insert into the previous number and leave the rest at the end
so 13:8 becomes 141

If you are starting with strings, then you just simply split the string on : to get your 2 numbers.
To get the last digit, you can simply use x % 10. Then just add the numbers and see what happens.
let value = '13:8',
nums = value.split(':').map(Number),
last_digits = nums.map(x => x % 10),
// or last_digits.reduce((x,y) => x+y, 0)
sum = last_digits[0] + last_digits[1],
result;
if (sum > 10) {
nums[0]++;
nums[1] = sum - 10; // or, probably sum % 10
}
result = nums.join('');
console.log(result);

Related

Integer adding problems with JavaScript

We are currently learning JavaScript in our labs and we just created a simple Fibonacci function that calculates first 100 numbers of the Fibonacci sequence.
function fibo(stop) {
let counter = 0;
let first = 1;
let second = 1;
let third = 0;
console.log(third);
console.log(second);
console.log(first);
while (true) {
third = second;
second = first;
first = second + third;
counter++;
if (counter >= stop) {
break;
}
console.log(first);
}
}
fibo(100);
Now when I run it there's a section that just magically adds numbers together wrong.
When I separately add those exact two numbers together in JavaScript, I get the same answer as the third line in the screenshot. However when I redo the adding on a calculator, it shows 14 472 334 024 676 221 instead of 14 472 334 024 676 220. My first guess was that it has something to do with Integer Overflow, but then again log2(14472334024676220) = 53.684... which means that in a 64 bit integer it is not overflowing. Why is it so? Where does it come from? I tried asking my teacher but he had no idea.
When dealing with integers, the maximum safe integer (i.e where n + 1 !== n) is 9007199254740991 which is 2^53 - 1
Javsacript Numbers are 64 bit floating point, that doesn't mean integers
Use BigInts - to initialise a BigInt youse can use the n suffix to a number as below
function fibo(stop) {
let counter = 0;
let first = 1n;
let second = 1n;
let third = 0n;
console.log(third.toString());
console.log(second.toString());
console.log(first.toString());
while (true) {
third = second;
second = first;
first = second + third;
counter++;
if (counter >= stop) {
break;
}
console.log(first.toString());
}
}
fibo(100);
Note: the Stack Snippet console.log fails to log BigInt which is why I put the .toString()

Is there a simple way to split a number into an array of digits without converting it to a string and back?

I was working on a Javascript exercise that required a number to be converted into an array of single digits and the only way I can seem to achieve this is by converting the number into a string and then converting it back to a number.
let numbers = 12345;
Array.from(numbers.toString(10), Number) // [1, 2, 3, 4, 5]
Basically, I'm wondering if this is the best way to achieve a split like this on a number or if there is a more efficient method that doesn't require such a conversion.
You can always get the smallest digit with n % 10. You can remove this digit with subtraction and division by 10 (or divide and floor). This makes for a pretty simple loop:
function digits(numbers){
if (numbers == 0) return [numbers]
let res = []
while (numbers){
let n = numbers % 10
res.push(n)
numbers = (numbers - n) / 10
}
return res.reverse()
}
console.log(digits(1279020))
This takes the numbers in reverse order so you either have to unshift the results on to the array or push and reverse at the end.
One of the nice things about this, is that you can find the digits of different bases by swapping out 10 for a the base of your choice:
function digits(numbers, base){
if (numbers == 0) return [numbers]
let res = []
while (numbers){
let n = numbers % base
res.push(n)
numbers = (numbers - n) / base
}
return res.reverse()
}
// binary
console.log(digits(20509, 2).join(''))
console.log((20509).toString(2))
// octal
console.log(digits(20509, 8).join(''))
console.log((20509).toString(8))
Although once your base is larger than 10 you will have to map those digits to the appropriate letters.
One approach would be to iterate through the number of digits and calculate the difference of each modulo by base, and then populate the output list from the result of each iteration.
A quick way to identify the number of digits in your base 10 input would be the following:
Math.floor(Math.log(input) / Math.LN10 + 1) // 5 for input of 12349
Next, iterate through this range and for each iteration, calculate the base of the current and previous iterations, and perform module of the input against these. The digit for the current iteration is then derived from the difference of the modulo calculations like this:
function arrayFromInput(input) {
const output = [];
for (let i = 0; i < Math.floor(Math.log(input) / Math.LN10 + 1); i++) {
const lastBase = Math.pow(10, i);
const nextBase = Math.pow(10, i + 1);
const lastMod = input % lastBase;
const nextMod = input % nextBase;
const digit = (nextMod - lastMod) / lastBase;
output.unshift(digit);
}
return output;
}
console.log(arrayFromInput(12345), '= [1,2,3,4,5]');
console.log(arrayFromInput(12), '= [1,2]');
console.log(arrayFromInput(120), '= [1,2 0]');
console.log(arrayFromInput(9), '= [9]');
console.log(arrayFromInput(100), '= [1,0,0]');

How do i return a number excluding the last digit?

So I have a number like 5467. I want my code to return 546.
I tried taking the last number and subtracting it from the original number but I get 5460 instead of 546.
Combine / with %:
(5467 - (5467 % 10)) / 10
564
Sounds like you also need to divide my 10. You could do something like this:
var number = 5467;
number = number - (number % 10); // This will subtract off the last digit.
number = number / 10;
console.log(number); // 546
We first use the modulo operator % to get the last digit, and we subtract it from number. That reduces the number from 5467 to 5460. Now to chop off the last digit (which is guaranteed to be a 0) we divide by 10 and get 546.
Written more concisely you could do:
number = (number - ( number % 10)) / 10;
There's a few things you can do the most concise being:
Math.floor(num / 10);
Or, convert to a string, remove the last character and convert back to number.
parseInt(num.toString().slice(0, -1));
If string representation would be fine for you then one other way is
var num = 5467,
cut = (num/10).toFixed(); // <-'547'
Well... warning..! i have to say toFixed() method rounds if necessary. So in this particular example it doesn't work.
I dont mind some of the other answers, but i feel that this maybe too fixed on it being a number.
Which it is, but you want to remove the last digit/char, regardless of the number, so why not substr?
http://www.w3schools.com/jsref/jsref_substr.asp
var s = 5467;
s = s.toString().substr(0, s.toString().length - 1);
console.log(s)
or even easier:
var s = (5467).toString();
s = s.substr(0, s.length - 1);
console.log(s)
These dont take into account single digit numbers, so passing in 1 would return blank. To answer that you could simply do a check like:
var s = (1).toString();
if(s.length > 1)
s = s.substr(0, s.length - 1);
console.log(s)
Also, similar question to:
Remove last digits from an int
Remove the last digits of a number (not string)
Removing the last digits in string
To truncate digits from the right hand side until the number is less than 30, keep dividing by 10 and rounding down until a suitable value is reached:
var n = 12341235;
while (n > 30) n = n/10|0;
document.write(n);
The greater than and division operations will coerce n to a number, so it can be a number or string. If ToNumber(n) results in NaN (e.g. n = 'foo'), then the value of n is not modified.
You can simply divide the number by 10 and parseInt()
var num = 5467;
num = parseInt(num/10);
Update :
To repeat the process until the answer is less than 30, use while loop as
var num = 5467;
while(num >= 30) {
num = parseInt(num/10);
}
document.write(num);

Random number generator, what's wrong with my approach/statistics? [JS]

First of all, what I want to know is if I am doing a systematic fault or am I messing up with the math, or do you have any ideas what could be wrong?
I was trying to write a little random number generator which numbers can be influenced / verified by the user (provably fair). The generated number is between 4096 and 65535. I simulated the function 100,000 times and get some strange statistics (Or am I thinking wrong??).
Why is the chance that the number is under 8000 around ~50%. Shouldn't it be 50% around the middle of the number range (~30700)?
Here is the output of the simulation:
< 65536 : 100000 Times :100%
< 60000 : 91813 Times :91.813%
< 56000 : 86406 Times :86.406%
< 52000 : 81334 Times :81.334%
< 48000 : 76743 Times :76.743%
< 32768 : 62356 Times :62.356%
< 32000 : 61748 Times :61.748%
< 30719 : 60860 Times :60.86%
< 24000 : 56628 Times :56.628%
< 16000 : 52871 Times :52.871%
< 12000 : 51540 Times :51.54%
< 8000 : 50447 Times :50.447%
< 6000 : 36003 Times :36.003%
< 5096 : 21583 Times :21.583%
< 4608 : 11714 Times :11.714%
< 4250 : 3674 Times :3.674%
< 4100 : 100 Times :0.1%
< 4096 : 0 Times :0%
A little more details on the function I wrote:
I am generating two hashes. One is the userhash and the other is the serverhash. Both of these have a format like e.g.:
Server =3CDC3C8C97DEE62169B2C403BB2B6B501C1B0A0BD8015699B47DA67789C3F628
User =CF27CC73E33E0AC1DA5239DE8DAF94044D89B8636DA90F4CE510E652C8AC7F54
(The Userhash, is generated by a unique ID. The Serverhash is generated by taking a random number (standard function: math.random() )and a timestamp and then HMAC-SHA-512 them.)
To get my "random" number, i take both (user and server) hashes and add them as hexadecimal numbers (userhash + serverhash = result). Then I take the result and cut everything except the first 4 digits. (E.g result = CF27)
After that, I convert it to decimal again.
The smallest number I can get from this should be in Hex 1000 (dec=4096), the biggest in Hex FFFF (dec=65535). That means my random number should be in a Range of 4096 - 65535.
Code Snippets:
//Function for getting a dec number from two hashes
function test_Rand(SERVER_SECRET, CLIENT_SECRET){
var client_hash = require('crypto'),
text = CLIENT_SECRET,
key = SERVER_SECRET
// create hash
var hash = client_hash.createHmac('sha512', key);
hash.update(text);
var clientRollAsHex = hash.digest('hex')
var serverRollAsHex = SERVER_SECRET;
//Add the numbers in Hex
var roll_hex = addHex(clientRollAsHex, serverRollAsHex);
//Cut the hex String
roll_hex = roll_hex.substring(0,4);
// Make INT
var roll_dec = parseInt(roll_hex, 16);
return roll_dec;
}
//Function for Hex-adding
function addHex(c1, c2) {
var hexStr = (parseInt(c1, 16) + parseInt(c2, 16)).toString(16);
while (hexStr.length < 6) { hexStr = '0' + hexStr; } // Zero pad.
return hexStr;
}
The SERVER_SECRET comes from the following func.
var secret = function() {
var r1 = Math.random()*10000000 + Math.floor(Date.now() / 1000);
var r2 = Math.random()*1000000 + Math.floor(Date.now() / 2000); //That does not make much sense
var new_hash = require('crypto');
var text = r1;
var key = r2;
// create hahs
var r_hash = new_hash.createHmac('sha512', key.toString());
r_hash.update(text.toString());
var retrn = r_hash.digest('hex');
return retrn;
}
It's because you are taking the first four digits that you get a skewed result.
For 50% of the numbers you will get a result that is 65 digits long instead of 64, and the first digit is 1. For example adding the two numbers in your example:
3CDC3C8C9...
CF27CC73E...
= 10C0409007...
Taking the first four digits from the result gives you 10C0. As you see from your result, there are a lot of numbers between 1000 (4096) and 1FFF (8191). Most of those are numbers where the result is 65 digits instead of 64.
If you instead take any four digits at a specific position (counter from the right), for example the last four digits, you will get a pretty even distribution of numbers between 0000 and FFFF.
A much simplified version of your design:
var a=Math.floor((Math.random() * 10));
var b=Math.floor((Math.random() * 10));
What is the range of a+b? 0-18
Now take only the first digit of the result. Then 0-9 would still be their original value *but 10-18 becomes 1.
To get the result you want, you need to remove the first digit for cases 10-18.

Find out how many thousands and hundreds and tens are there in a amount

I am having a asp application and in that amount column is there. I need to find out how many thousands and hundreds and tens are there in that amount
For example
if i am having amount as 3660 means
1000's - 3
100's - 6
10's - 6
like this i need
Can any body help me
The simple answer is to divide the number by 1000 whatever is the quotient that is the number of 1000's in the amount. Then divide the remainder with the 100's the quotient will be the number of 100's. And then again divide the remainder with 10, the quotient will be the number of 10's
Something like this:
quotient = 3660 / 1000; //This will give you 3
remainder = 3660 % 1000; //This will give you 660
Then,
quotient1 = remainder/ 100; //This will give you 6
remainder1 = remainder % 100; //This will give you 60
And finally
quotient2 = remainder1 / 10; //This will give you 6
Is it not easier to use type coercion and change the data type to string?
Then you can easily check the value by checking the value at selected index position,
var number = 1234;
number2 = new String(number);
var thousands = number2[0];
var hundreds = number2[1];
and so on....
It may not be usable in what you're doing, it was for me :)
If the "javascript" tag is the correct one, then you've already gotten some answers. If the "asp-classic" tag is actually the correct one, then chances are your scripting language is VBScript, not Javascript.
Did you just pick multiples of 10 as an example, or is that the actual multiple you're looking for? Because if it's the latter, then all you need to do is split the number into digits — that's what the base 10 number system means, after all.
Function SplitNum(theNum)
dim L, i, s, n
n = CStr(theNum)
L = Len(n)
s = ""
for i = 1 to 3
if s <> "" then s = "," & s
if i >= L then
s = "0" & s
else
s = Left(Right(n,i+1),1) & s
end if
next
if L > 4 then s = left(n,L-4) & s
SplitNum = s
End Function
If your actual divisors are something other than multiples of 10, you'll need to do arithmetic. The integer division operator in VBScript is \. (Integer division is basically the "opposite" of the modulus function.)
Function GetMultiples(theNum)
dim q, r
q = theNum \ 1000 & ","
r = theNum Mod 1000
q = q & r \ 100 & ","
r = r Mod 100
q = q & r \ 10
GetMultiples = q
End Function
Try this out...
Here is a fiddle that demonstrates how to use the output..
http://jsfiddle.net/Villarrealized/L3AxZ/1/
function getMultiplesOfTen(number){
number = parseInt(number);
if(typeof(number)!=="number") return number;
var result = {};
(function breakDown(num){
if(isNaN(num))return num;//if it's invalid return
if(num<=0)return false;
num = num.toFixed(0);//get rid of decimals
var divisor = Math.pow(10,num.length-1),//ex. when num = 300, divisor = 100
quotient = Math.floor(num/divisor);
result[divisor]=quotient;//add it to our object
breakDown(num % divisor);//break down the remainder
})(number);
//return result as an object
return result;
}
This function will return an object with the multiple of ten as the key and the number as the value
ex. getMultiplesOfTen(150)=={100:1,10:5} == 1 multiple of 100 and 5 multiples of 10.
Let's say we have the number 7354. To find the thousands:
variable a = 7354 / 1000
variable b = a % 10
The number which is stored in variable b now is the number if the thousands.
To find the hundreds:
variable c = 7354 / 100
variable d = a % 10
The number which is stored in variable d now is the number if the hundreds.
To find the tens:
variable e = 7354 / 10
variable f = a % 10
The number which is stored in variable f now is the number if the tens.
To find the ones:
7354 % 10
This works for every number in the place of 7354, even for bigger numbers than 7354.
The first digit in the quotient of 1,592÷64
1
is in the Choose... ones tens hundreds thousands place.
Decide where the first digit of the quotient should be placed. Do not complete the division.
The first digit of the quotient for 2,370÷24
2,370÷24
should be in the Choose... ones tens hundreds thousands place
2021 version here:
Cast your number as a string, spread it and reverse it like so:
x = 1234
x = [...x.toString()].reverse() // [4, 3, 2, 1]
thous = x[3] // 1
hunds = x[2] // 2
tens = x[1] // 3
units = x[0] // 4
y = [...x.toString()].reverse()[3] // 1 because 1000 has 3 zeros
I suppose you can use some fancy system of powers of 10 to get those indexes. So let's do exactly that and get #Villarrealized 15 lines of 2013 code condensed into just a few lines of 2021 code:
function placeValues(someNumber = 1234) {
x = [...someNumber.toString()].reverse().reduce((p, c, i) => {
p[10**i] = c;
return p;
}, {});
return x; // {1000:1, 100:2, 10:3, 1:4}
}

Categories