Get binary representation of integer - javascript

I just had an interview question, where I need to get the binary representation of an integer, this is something I should know how to do.. for example, 5 is represented in binary as 101, and the steps look something like:
// 5 % 2 = 1
// 5 / 2 = 2
// result = 1;
// 2 % 2 = 0
// 2 / 2 = 1
// result = 10
// 1 % 2 = 1
// 1 / 2 = 0
// result = 101
the stopping condition is when ~~(1/2) === 0
so I have this:
const getBinary = (v) => {
let remainder, binary = 1;
while (true) {
remainder = v % 2;
v = ~~(v / 2);
if (v === 0) {
return binary;
}
if (remainder === 0) {
binary = binary * 10 + 1;
}
else {
binary = binary * 10;
}
}
};
console.log(getBinary(5));
so that works, but the binary variable is initialized to 1. Is there a way to improve this so it works with negative numbers, or if 0 is passed as the argument to the function?

var integer = 52;
console.log(integer.toString(2));
Simple function native to javascript, no lengthy code required.

If you want to write it from scratch you can use something like this:
function toBinary(n) {
n = Number(n);
if (n == 0) return '0';
var r = '';
while (n != 0) {
r = ((n&1)?'1':'0') + r;
n = n >>> 1;
}
return r;
}
console.log(toBinary(5));
console.log(toBinary(10));
console.log(toBinary(-5));
console.log(toBinary(0));

So here is one way. It has an inner function that handles the basics and an outer one that extends to your special cases. I preferred to do string representations.
const getBinary = v => {
if (v === 0) return '';
let remainder = v % 2;
let quotient = (v - remainder) / 2;
if (remainder === 0) {
return getBinary(quotient) + '0';
}
else {
return getBinary(quotient) + '1';
}
}
const betterGetBinary = v => {
if (v === 0) return '0';
if (v < 0) return '-' + getBinary(-v);
return getBinary(v);
}
console.log(betterGetBinary(-10));

A quick and dirty solution, although it 'might' have two flaws:
- Math.floor()
- no bitwise operator
let getBinary = number => {
let done = false;
let resultInverted = [];
let acc = number;
while (!done) {
let reminder = acc % 2;
if (acc === 1) {
done = true;
}
acc = Math.floor(acc / 2);
resultInverted.push(reminder);
}
return Number(resultInverted.reverse().join(''));
};
console.log(typeof getBinary(2));
console.log(getBinary(5));
console.log(getBinary(127));

Related

Adding Strings With Float Numbers Javascript

I'm trying to solve a question to be able to add strings that include floating point numbers. For example "110.75" + "9" = "119.75".
I have the code below that I have been wrestling with for about an hour now and could appreciate if anybody could point me in the right direction as to where I might be wrong. I am only returning an empty string "" for every test case I write for myself.
var addStrings = function(num1, num2) {
const zero = 0;
let s1 = num1.split(".");
let s2 = num2.split(".");
result = "";
let sd1 = s1.length > 1 ? s1[1] : zero;
let sd2 = s2.length > 1 ? s2[1] : zero;
while(sd1.length !== sd2.length) {
if(sd1.length < sd2.length) {
sd1 += zero
} else {
sd2 += zero;
}
}
let carry = addStringHelper(sd1, sd2, result, 0);
result.concat(".");
addStringHelper(s1[0], s2[0], result, carry);
return result.split("").reverse().join("");
};
function addStringHelper(str1, str2, result, carry) {
let i = str1.length - 1;
let j = str2.length - 1;
while(i >= 0 || j >= 0) {
let sum = carry
if(j >= 0) {
sum += str1.charAt(j--) - '0';
}
if(i >= 0 ) {
sum += str2.charAt(i--) - '0';
}
carry = sum / 10;
result.concat(sum % 10);
}
return carry
}
Convert the strings into Number, add them and then convert them back to String.
const addStrings = (num1, num2) => String(Number(num1) + Number(num2))
console.log(addStrings("110.67", "9"))
Also, try to handle floating point rounding in some way. You can try using toFixed (this will fix the result to two decimal places).
const addStrings = (num1, num2) => String((Number(num1) + Number(num2)).toFixed(2))
console.log(addStrings("0.2", "0.1"))

How to make single digits?

function SingleDigits(num) {
function makeDigits(num) {
let value = 1
let arr = String(num)
for(let i = 0 ; i < arr.length; i++){
value = value * Number(arr[i])
}
return value;
}
value += "";
while(1>=value.length){
let result = 1;
result = result
}
I'm going to do it until I make a single digit..
num = 786
7 * 8 * 6 -> 336
3 * 3 * 6 -> 54
5 * 4 -> 20
2 * 0 -> 0
like that.. how can i setting ?? or , my direction is right ?
You can use recursion to keep on going until the total equals 0.
eg.
function digits(num) {
const nums = num.toString().
split('').map(Number);
const total = nums.reduce(
(a,v) => a * v);
console.log(
nums.join(' * ') +
" => " + total);
if (total > 9)
digits(total);
}
digits(786);
Use recursion. The function can be pretty simple using a reducer to calculate the products.
const singleDigit = num => {
const nums = [...`${num}`];
const product = nums.reduce( (acc, val) => acc * +val, 1);
console.log(`${nums.join(" * ")} -> ${product}`);
return product <= 9 ? product : singleDigit(product);
}
console.log(singleDigit(4328));
You Should use recursive strategy.
function SingleDigits(num) {
if (parseInt(num / 10) > 0) {
let t = 1;
while (num > 0) {
t *= num % 10;
num = parseInt(num / 10);
}
console.log(t);
SingleDigits(t);
}
}
SingleDigits(786);
I am not sure why you have to use string here. You can do the following,
function SingleDigits(num) {
if(num <= 9) {
return num;
}
let res = 1;
while(num) {
res = res * (num % 10);
num = parseInt(num / 10);
}
if(res <= 9) {
return res;
}
return SingleDigits(res);
}
console.log(SingleDigits(786));

How to find nth Fibonacci number using Javascript with O(n) complexity

Trying really hard to figure out how to solve this problem. The problem being finding nth number of Fibonacci with O(n) complexity using javascript.
I found a lot of great articles how to solve this using C++ or Python, but every time I try to implement the same logic I end up in a Maximum call stack size exceeded.
Example code in Python
MAX = 1000
# Create an array for memoization
f = [0] * MAX
# Returns n'th fuibonacci number using table f[]
def fib(n) :
# Base cases
if (n == 0) :
return 0
if (n == 1 or n == 2) :
f[n] = 1
return (f[n])
# If fib(n) is already computed
if (f[n]) :
return f[n]
if( n & 1) :
k = (n + 1) // 2
else :
k = n // 2
# Applyting above formula [Note value n&1 is 1
# if n is odd, else 0.
if((n & 1) ) :
f[n] = (fib(k) * fib(k) + fib(k-1) * fib(k-1))
else :
f[n] = (2*fib(k-1) + fib(k))*fib(k)
return f[n]
// # Driver code
// n = 9
// print(fib(n))
Then trying to port this to Javascript
const MAX = 1000;
let f = Array(MAX).fill(0);
let k;
const fib = (n) => {
if (n == 0) {
return 0;
}
if (n == 1 || n == 2) {
f[n] = 1;
return f[n]
}
if (f[n]) {
return f[n]
}
if (n & 1) {
k = Math.floor(((n + 1) / 2))
} else {
k = Math.floor(n / 2)
}
if ((n & 1)) {
f[n] = (fib(k) * fib(k) + fib(k-1) * fib(k-1))
} else {
f[n] = (2*fib(k-1) + fib(k))*fib(k)
}
return f[n]
}
console.log(fib(9))
That obviously doesn't work. In Javascript this ends up in an infinite loops. So how would you solve this using Javascript?
Thanks in advance
you can iterate from bottom to top (like tail recursion):
var fib_tail = function(n){
if(n == 0)
return 0;
if(n == 1 || n == 2)
return 1;
var prev_1 = 1, prev_2 = 1, current;
// O(n)
for(var i = 3; i <= n; i++)
{
current = prev_1 + prev_2;
prev_1 = prev_2;
prev_2 = current;
}
return current;
}
console.log(fib_tail(1000))
The problem is related to scope of the k variable. It must be inside of the function:
const fib = (n) => {
let k;
You can find far more good implementations here list
DEMO
fibonacci number in O(n) time and O(1) space complexity:
function fib(n) {
let prev = 0, next =1;
if(n < 0)
throw 'not a valid value';
if(n === prev || n === next)
return n;
while(n >= 2) {
[prev, next] = [next, prev+next];
n--;
}
return next;
}
Just use two variables and a loop that counts down the number provided.
function fib(n){
let [a, b] = [0, 1];
while (--n > 0) {
[a, b] = [b, a+b];
}
return b;
}
console.log(fib(10));
Here's a simpler way to go about it, using either iterative or recursive methods:
function FibSmartRecursive(n, a = 0, b = 1) {
return n > 1 ? FibSmartRecursive(n-1, b, a+b) : a;
}
function FibIterative(n) {
if (n < 2)
return n;
var a = 0, b = 1, c = 1;
while (--n > 1) {
a = b;
b = c;
c = a + b;
}
return c;
}
function FibMemoization(n, seenIt = {}) {//could use [] as well here
if (n < 2)
return n;
if (seenIt[n])
return seenIt[n];
return seenIt[n] = FibMemoization(n-1, seenIt) + FibMemoization(n-2, seenIt);
}
console.log(FibMemoization(25)); //75025
console.log(FibIterative(25)); //75025
console.log(FibSmartRecursive(25)); //75025
You can solve this problem without recursion using loops, runtime O(n):
function nthFibo(n) {
// Return the n-th number in the Fibonacci Sequence
const fibSeq = [0, 1]
if (n < 3) return seq[n - 1]
let i = 1
while (i < n - 1) {
seq.push(seq[i - 1] + seq[i])
i += 1
}
return seq.slice(-1)[0]
}
// Using Recursion
const fib = (n) => {
if (n <= 2) return 1;
return fib(n - 1) + fib(n - 2);
}
console.log(fib(4)) // 3
console.log(fib(10)) // 55
console.log(fib(28)) // 317811
console.log(fib(35)) // 9227465

type conversion not working javascript

I created a rather large function that takes in an argument, and based on the number's size, properly formats it. It works as expected for any values with the typeof number, however there are a few instances where I need to convert a string to a numeric value. I am trying to do that by using parseInt if its type is not number. When I console.log after the first if-statement, it says its typeof is now number. However when any string is passed through, say, "10000", it just shows up as 10000, and not the expected output of 10,000 with the proper formatting. Below is my code...are there any glaring ways that I might be going about it wrong?
function formatNumber(number) {
if (typeof number !== 'number') {
number = parseInt(number);
return number;
}
let decimals = 2;
const isNegative = number < 0;
const rounded = (number >= 1e+6) ? Math.round(number) : number;
const isInteger = () => parseInt(number, 10) === parseFloat(number);
const abs = Math.abs(rounded);
if (abs < 1e+6) {
decimals = isInteger(abs) ? 0 : decimals;
}
const formatter = val => {
const string = Math.abs(val).toString();
let formatted = '';
for (let i = string.length - 1, d = 1; i >= 0; i--, d++) {
formatted = string[i] + formatted;
if (i > 0 && d % 3 === 0) {
formatted = `,${formatted}`;
}
}
return formatted;
};
const formatLargeNumbers = (value, decimalPlaces) => {
let adjustedValue;
if (value >= 1e+12) {
adjustedValue = parseFloat((value / 1e+12).toFixed(decimals));
return `<span title=${formatter(value)}>${adjustedValue}T</span>`;
}
if (value >= 1e+9) {
adjustedValue = parseFloat((value / 1e+9).toFixed(decimals));
return `<span title=${formatter(value)}>${adjustedValue}B</span>`;
}
if (value >= 1e+6) {
adjustedValue = parseFloat((value / 1e+6).toFixed(decimals));
return `<span title=${formatter(value)}>${adjustedValue}M</span>`;
}
if (value >= 1e+3 && value < 1e+6) {
return value.toLocaleString('en-EN', {
minimumFractionDigits: decimalPlaces,
maximumFractionDigits: decimalPlaces,
});
}
return value.toFixed(decimals);
};
if (isNegative) {
let negativeNumber = Math.abs(rounded);
if (negativeNumber >= 1e+3) {
negativeNumber = formatLargeNumbers(negativeNumber);
}
return `<span class="negative-value">(${negativeNumber})</span>`;
}
return formatLargeNumbers(rounded, decimals);
}

How can I round to an arbitrary number of significant digits with JavaScript?

I tried below sample code
function sigFigs(n, sig) {
if ( n === 0 )
return 0
var mult = Math.pow(10,
sig - Math.floor(Math.log(n < 0 ? -n: n) / Math.LN10) - 1);
return Math.round(n * mult) / mult;
}
But this function is not working for inputs like
sigFigs(24730790,3) returns 24699999.999999996
and sigFigs(4.7152e-26,3) returns: 4.7200000000000004e-26
If anybody has working example please share.
Thanks.
You can try javascript inbuilt method-
Number( my_number.toPrecision(3) )
For Your case try
Number( 24730790.0.toPrecision(5) )
For your refrence and working example you can see link
First of all thanks to everybody, it would be a hard task without these snippets shared.
My value added, is the following snippet (see below for complete implementation)
parseFloat(number.toPrecision(precision))
Please note that if number is, for instance, 10000 and precision is 2, then number.toPrecision(precision) will be '1.0e+4' but parseFloat understands exponential notation.
It is also worth to say that, believe it or not, the algorithm using Math.pow and logarithms posted above, when run on test case formatNumber(5, 123456789) was giving a success on Mac (node v12) but rising and error on Windows (node v10). It was weird so we arrived at the solution above.
At the end I found this as the definitive implementation, taking advantage of all feedbacks provided in this post. Assuming we have a formatNumber.js file with the following content
/**
* Format number to significant digits.
*
* #param {Number} precision
* #param {Number} number
*
* #return {String} formattedValue
*/
export default function formatNumber (precision, number) {
if (typeof number === 'undefined' || number === null) return ''
if (number === 0) return '0'
const roundedValue = round(precision, number)
const floorValue = Math.floor(roundedValue)
const isInteger = Math.abs(floorValue - roundedValue) < Number.EPSILON
const numberOfFloorDigits = String(floorValue).length
const numberOfDigits = String(roundedValue).length
if (numberOfFloorDigits > precision) {
return String(floorValue)
} else {
const padding = isInteger ? precision - numberOfFloorDigits : precision - numberOfDigits + 1
if (padding > 0) {
if (isInteger) {
return `${String(floorValue)}.${'0'.repeat(padding)}`
} else {
return `${String(roundedValue)}${'0'.repeat(padding)}`
}
} else {
return String(roundedValue)
}
}
}
function round (precision, number) {
return parseFloat(number.toPrecision(precision))
}
If you use tape for tests, here there are some basic tests
import test from 'tape'
import formatNumber from '..path/to/formatNumber.js'
test('formatNumber', (t) => {
t.equal(formatNumber(4, undefined), '', 'undefined number returns an empty string')
t.equal(formatNumber(4, null), '', 'null number return an empty string')
t.equal(formatNumber(4, 0), '0')
t.equal(formatNumber(4, 1.23456789), '1.235')
t.equal(formatNumber(4, 1.23), '1.230')
t.equal(formatNumber(4, 123456789), '123500000')
t.equal(formatNumber(4, 1234567.890123), '1235000')
t.equal(formatNumber(4, 123.4567890123), '123.5')
t.equal(formatNumber(4, 12), '12.00')
t.equal(formatNumber(4, 1.2), '1.200')
t.equal(formatNumber(4, 1.234567890123), '1.235')
t.equal(formatNumber(4, 0.001234567890), '0.001235')
t.equal(formatNumber(5, 123456789), '123460000')
t.end()
})
How about automatic type casting, which takes care of exponential notation?
f = (x, n) => +x.toPrecision(n)
Testing:
> f (0.123456789, 6)
0.123457
> f (123456789, 6)
123457000
> f (-123456789, 6)
-123457000
> f (-0.123456789, 6)
-0.123457
> f (-0.123456789, 2)
-0.12
> f (123456789, 2)
120000000
And it returns a number and not a string.
Unfortunately the inbuilt method will give you silly results when the number is > 10, like exponent notation etc.
I made a function, which should solve the issue (maybe not the most elegant way of writing it but here it goes):
function(value, precision) {
if (value < 10) {
value = parseFloat(value).toPrecision(precision)
} else {
value = parseInt(value)
let significantValue = value
for (let i = value.toString().length; i > precision; i--) {
significantValue = Math.round(significantValue / 10)
}
for (let i = 0; significantValue.toString().length < value.toString().length; i++ ) {
significantValue = significantValue * 10
}
value = significantValue
}
return value
}
If you prefer having exponent notation for the higher numbers, feel free to use toPrecision() method.
if you want to specify significant figures left of the decimal place and replace extraneous placeholders with T B M K respectively
// example to 3 sigDigs (significant digits)
//54321 = 54.3M
//12300000 = 12.3M
const moneyFormat = (num, sigDigs) => {
var s = num.toString();
let nn = "";
for (let i = 0; i <= s.length; i++) {
if (s[i] !== undefined) {
if (i < sigDigs) nn += s[i];
else nn += "0";
}
}
nn = nn
.toString()
.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")
.replace(",000,000,000", "B")
.replace(",000,000", "M")
.replace(",000", "k");
if (
nn[nn.length - 4] === "," &&
nn[nn.length - 2] === "0" &&
nn[nn.length - 1] === "0"
) {
let numLetter = "K";
if (parseInt(num) > 999999999999) numLetter = "T";
else if (parseInt(num) > 999999999) numLetter = "B";
else if (parseInt(num) > 999999) numLetter = "M";
console.log("numLetter: " + numLetter);
nn = nn.toString();
let nn2 = ""; // new number 2
for (let i = 0; i < nn.length - 4; i++) {
nn2 += nn[i];
}
nn2 += "." + nn[nn.length - 3] + numLetter;
nn = nn2;
}
return nn;
};

Categories

Resources