How to make single digits? - javascript

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));

Related

generate random numbers in specific range and using specific numbers?

How to generate random numbers in specific range and using specific numbers?
Example
given numbers [7,8];
given range [100-900];
output must be one of them 777, 787, 788, 878, 877, 888 etc...
Help me
const randomGenerateNumber = (maxRange:number, minRange:number, numbers:number[]) => {
//...what should i do in there??? Help me? Any Idea?
}
I think you don't want random numbers. It seems that you want a set of numbers based on some rules. Random means something else.
If I understand well your question you want to generate all possible numbers containing only a set of digits from a range of numbers. Is this an accurate description?
If so, this is similar with what you want: Generate random numbers only with specific digits
Edit:
You are right, so you want only one number.
In javascript you could do something like this:
I edited the algorithm to take into account min and max in probably the most lazy way. I didn't take into account cases where numbers can't be generated, it will return undefined.
There are so many ways to do this. Your algorithm can work too and maybe more efficient but it seems to have an issue with 0, it will generate numbers with 0 even if it's not in the digits array.
function randomGenerateNumber(minRange, maxRange, digits){
noTries = 0;
while(noTries++ < 100000)
{
var num = 0;
//get a random number from your range
len = Math.floor(Math.random() * (maxRange - minRange) + minRange);
//get the lenght of that random number
len = len.toString().length;
//generate a number with that length using only your set of digits
while(len--)
{
num = num * 10 + digits[Math.floor(Math.random() * digits.length)];
}
if(num >= minRange && num<= maxRange)
{
return num;
break;
}
}
}
//your testing cases
console.log(randomGenerateNumber(100,900,[7,8]))
console.log(randomGenerateNumber(299,300,[1,2,3,4,5,6,7,8,9]));
i did it. Is there any improvement. Little bit messy.
const getRandomNumber = (min: number, max: number, numbers: number[]): number => {
if (numbers.length === 9) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
let result = '';
//split maxDigits 100 => [1, 0, 0]
const maxDigits = max
.toString()
.split('')
.map(i => parseInt(i, 10));
//split minDigits 100 => [1, 0, 0]
const minDigits = min
.toString()
.split('')
.map(i => parseInt(i, 10));
//length of random number [minDigit, maxDigit] inclusive
const randomDigit = Math.floor(Math.random() * (maxDigits.length - minDigits.length + 1) + minDigits.length);
let alreadyHigh = false;
let alreadyLow = false;
let equal = true;
//4 conditions
//1. minDigits.length === maxDigits.length
//2. randomDigit === minDigits.length
//3. randomDigit === maxDigits.length
//4. randomDigit > minDigits.length && randomDigit < maxDigits.length
for (let i = 0; i < randomDigit; i++) {
const numbersToUse = i === 0 ? numbers : [...numbers, 0];
let availableNumbers = [];
if (minDigits.length === maxDigits.length) {
if (equal) {
for (let k = 0; k < numbersToUse.length; k++) {
if (minDigits[i] > maxDigits[i]) {
if (numbersToUse[k] >= 0 && numbersToUse[k] <= maxDigits[i]) {
availableNumbers.push(numbersToUse[k]);
}
} else if (numbersToUse[k] >= minDigits[i] && numbersToUse[k] <= maxDigits[i]) {
availableNumbers.push(numbersToUse[k]);
} else {
availableNumbers.push(maxDigits[i]);
}
}
} else {
if (!alreadyHigh) {
for (let k = 0; k < numbersToUse.length; k++) {
if (numbersToUse[k] >= minDigits[i]) {
availableNumbers.push(numbersToUse[k]);
}
}
} else {
availableNumbers = numbersToUse;
}
}
} else if (randomDigit === minDigits.length) {
if (!alreadyHigh) {
for (let k = 0; k < numbersToUse.length; k++) {
if (numbersToUse[k] >= minDigits[i]) {
availableNumbers.push(numbersToUse[k]);
}
}
} else {
availableNumbers = numbersToUse;
}
} else if (randomDigit === maxDigits.length) {
if (!alreadyLow) {
for (let k = 0; k < numbersToUse.length; k++) {
if (numbersToUse[k] <= maxDigits[i]) {
availableNumbers.push(numbersToUse[k]);
}
}
} else {
availableNumbers = numbersToUse;
}
} else {
availableNumbers = numbersToUse;
}
availableNumbers = [...new Set(availableNumbers)];
const randomIndex = Math.floor(Math.random() * availableNumbers.length);
result += `${availableNumbers[randomIndex]}`;
alreadyHigh = !alreadyHigh ? availableNumbers[randomIndex] > minDigits[i] : true;
alreadyLow = !alreadyLow ? availableNumbers[randomIndex] < maxDigits[i] : true;
equal = equal ? availableNumbers[randomIndex] === maxDigits[i] : false;
}
return parseInt(result, 10);
};

How do I join this numbers together?

function expandedForm(num) {
let len = num.toString().length;
let n = num.toString().split("");
let result = "";
for (let i = 0; i < len; i++) {
result += n[i] + "0".repeat(len -1 -i).join(" + ");
}
return result;
}
What I am trying to do is to separate numbers like this:
1220 = "1000 + 200 + 20"
221 = "200 + 20 + 1"
I have written the code (not the perfect one) where it gets me all the necessary values but I struggle with joining them together with "+". I tried using .join() but it did not work.
.join works on arrays only
function expandedForm(num) {
let len = num.toString().length;
let n = num.toString().split("");
let result = "";
let arr=[];
for (let i = 0; i < len; i++) {
arr[i] = n[i] + '0'.repeat(len-1-i);
console.log(arr[i]);
}
let ans=arr.join('+');
return ans;
}
console.log(expandedForm(1220))
Although there are a variety of approaches, here are some general tips for you:
Probably don't want to output a 0 term unless the input number is exactly 0 (only a leading 0 term is relevant, because it will be the only such term)
str.split('') can also be [...str]
No need to split a string into an array to access a character str.split('')[0] can also be just str[0]
Might want to assert that num is a whole number.
Make sure you provide enough test cases in your question to fully define the behaviour of your function. (How to handle trailing zeros, interstitial zeros, leading zeros, etc. Whether the input can be a string.)
function expandedForm(num) {
const s = num.toString();
const n = s.length - 1;
const result = [...s]
.map((char, index) => char + '0'.repeat(n - index))
.filter((str, index) => !index || +str)
.join(' + ');
return result;
}
console.log(expandedForm(1220));
console.log(expandedForm(221));
console.log(expandedForm(10203));
console.log(expandedForm(0));
console.log(expandedForm(2n**64n));
Join works with an array, not string. It stringifies two subsequent indexes for all indexes and you can decide what to add between them.
function expandedForm(num) { // num = 321
let len = num.toString().length; // len = 3
let n = num.toString().split(""); // [3,2,1]
let result = [];
for (let i = 0; i < len; i++) {
result.push(n[i] + "0".repeat(len -1 -i)); // pushing till result = ['300','20','10']
}
return num + ' = ' + result.join(' + ');
// connection result[0] + ' + ' result[1] + ' + ' result[2]
}
expandedForm(321); // output: "321 = 300 + 20 + 1"
Here's one way of doing it
let num = 221;
function expandedForm(num) {
let len = num.toString().length;
let n = num.toString().split("");
let result = "";
for (let i = 0; i < len; i++) {
let t = "0"
t = t.repeat(len-1-i)
if(result.length > 0){
n[i] !== '0'? result += '+'+ n[i] + t : result
} else {
n[i] !== '0'? result += n[i] + t : result
}
}
return result;
}
console.log(expandedForm(2200))
console.log(expandedForm(num))
below would be my approach in a more mathimatical but clean code that you can adjust to your needs.
let result = parseInt(num / 1000);
return result ;
}
function x100( num ) {
num = num % 1000;
let result = parseInt( num / 100);
return result;
}
function x10(num ) {
num = num % 1000;
num = num % 100;
let result = parseInt(num /10);
return result;
}
function x1( num ) {
num = num % 1000;
num = num % 100;
num = num % 10;
return num
}
num = 12150
console.log(num = `1000 x ${x1000(num)}, 100 x ${x100(num)}, 10 x ${x10(num)}`)```

if a positive number is equal to its reverse

I'm making a program to receive a positive number and output "yes" if it's equal to its reverse;
otherwise, output "no".
What I've done so far:
HTML
<div class="column1">
<div class="input">
<button onclick="problem()"> Run the program </button>
</div>
<strong><p id="output"> </p></strong>
</div>
JS
function problem() {
var outputObj = document.getElementById("output");
var a = parseInt(prompt("Please enter a number: ", ""));
outputObj.innerHTML = "number: " + a + "<br><br>";
var reverse = 0;
while (a > 0){
num = a % 10; // the last digit
reverse = (reverse *10) + num; // calculating the reverse
a = Math.floor(a / 10); // go to next digit
}
if ( reverse == a){
outputObj.innerHTML = "yes";
}
else {
outputObj.innerHTML = "no";
}
outputObj.innerHTML = outputObj.innerHTML + "<br><br>" + "program ended";
document.getElementsByTagName("button")[0].setAttribute("disabled","true");
}
function isPalindrome(number){
return +number.toString().split("").reverse().join("") === number
}
Art for art
function palindrom(x)
{
let len = Math.floor(Math.log(x)/Math.log(10) +1);
while(len > 0) {
let last = Math.abs(x - Math.floor(x/10)*10);
let first = Math.floor(x / Math.pow(10, len -1));
if(first != last){
return false;
}
x -= Math.pow(10, len-1) * first ;
x = Math.floor(x/10);
len -= 2;
}
return true;
}
You should search for plaindromic numbers. For example the following code:
const isPalindrome = x => {
if (x < 0) return false
let reversed = 0, y = x
while (y > 0) {
const lastDigit = y % 10
reversed = (reversed * 10) + lastDigit
y = (y / 10) | 0
}
return x === reversed
}
const isPalindrome = num => {
const len = Math.floor(Math.log10(num));
let sum = 0;
for(let k = 0; k <= len; k++) {
sum += (Math.floor(num / 10 ** k) % 10) * 10 ** (len - k);
}
return sum === num;
}
console.log(isPalindrome(12321));

Find all possible combinations which make a specific number JavaScript

My problem is I have a number for example 17; I also have three other constant numbers: 2, 5, 7;
I need to find all possible combinations which make the specific number 17 or any other number;
5 + 5 + 7 = 17 (1 combination)
5 + 5 + 5 + 2 = 17 (2 combinations)
2 + 2 + 2 + 2 + 2 + 7 = 17 (3 combinations)
2 + 2 + 2 + 2 + 2 + 2 + 5 = 17 (4 combinations)
So the answer is 4.
I created my script which working correctly with the number 17 but wrong with bigger numbers as 20 or 30. How to make it working with all numbers ?
const seek = 30;
const firstNum = 2;
const secondNum = 5;
const thirdNum = 7;
let combinations = 0;
const maxDivisor = Math.round(seek / 2);
for (let i = 1; i <= maxDivisor; i += 1) {
if (secondNum * i + thirdNum === seek) {
combinations++
} else if (secondNum * i + firstNum === seek) {
combinations++
} else if (firstNum * i + secondNum === seek) {
combinations++
} else if (firstNum * i + thirdNum === seek) {
combinations++
} else if (thirdNum * i + firstNum === seek || thirdNum * i + secondNum === 0) {
combinations++
} else if (firstNum + secondNum + thirdNum === seek) {
combinations++
} else if (firstNum * i === seek || thirdNum * i === seek || secondNum * i === seek) {
combinations++
}
}
console.log(combinations);
Simple solution is to first calculate max multipliers for each number and then keep summing all the possible combinations.
/** LOGIC **/
function getCombinations(inputNumber, pieceNumbers) {
const combinations = []
const initial = maxes(inputNumber, pieceNumbers);
let divs = initial;
const sum = createSum(pieceNumbers);
while (!allZeros(divs)) {
if (sum(divs) === inputNumber) {
combinations.push(divs);
}
divs = decrement(divs, initial);
}
return combinations;
}
/**
* returns max multiplier for each number
* that is less than input number
* ie. for [2, 5] and input 17
* you get [8 (17 / 2); 3 (17 / 5)]
*/
function maxes(inputNumber, pieceNumbers) {
return pieceNumbers.map((num, i) =>
inputNumber / num | 0
)
}
/**
* decrements list of numbers till it contains only zeros
* if we have divs [2, 0] and initial [2, 5] the result
* will be [1, 5]
*/
function decrement(divs, initial) {
const arr = divs.slice();
let i = arr.length;
while (i--) {
if (arr[i] > 0) {
return [...arr.slice(0, i), arr[i] - 1, ...initial.slice(i + 1)];
}
}
}
function allZeros(divs) {
return divs.every(div => div === 0);
}
function createSum(pieceNumbers) {
return (divs) => divs.reduce((acc, itm, i) => acc + itm * pieceNumbers[i], 0);
}
function toPrint(combinations, pieceNumbers) {
const printable = combinations.map(nums =>
nums.map(
(n, i) => Array(n).fill(pieceNumbers[i]).join(" + ")
)
.filter(x => x)
.join(" + ")
).join("\n");
return printable;
}
/** VIEW **/
const addPieceEl = document.querySelector(".js-add-piece-number");
const removePieceEl = document.querySelector(".js-remove-piece-number");
const calculateEl = document.querySelector(".js-calculate");
const displayEl = document.querySelector(".js-display-result");
addPieceEl.addEventListener("click", () => {
addPieceEl.insertAdjacentHTML("beforebegin", ` <input type="number" class="js-piece-number number" value="7" /> `)
})
removePieceEl.addEventListener("click", () => {
addPieceEl.previousElementSibling.remove()
})
calculateEl.addEventListener("click", () => {
const inputNumber = Number(document.querySelector(".js-input-number").value);
const pieceNumbers = Array.from(document.querySelectorAll(".js-piece-number")).map(el => Number(el.value))
const combinations = getCombinations(inputNumber, pieceNumbers);
const total = `There are ${combinations.length} combinations for ${inputNumber} with ${pieceNumbers.join(", ")}:\n`;
displayEl.textContent = total + toPrint(combinations, pieceNumbers);
});
.number {
width: 30px;
}
Input Number: <input type="number" class="js-input-number number" value="17"/>
<br/>
<br/>
Piece Numbers:
<input type="number" class="js-piece-number number" value="2"/>
<input type="number" class="js-piece-number number" value="5"/>
<input type="number" class="js-piece-number number" value="7"/>
<button class="js-add-piece-number">+</button>
<button class="js-remove-piece-number">-</button>
<br/>
<br/>
<button class="js-calculate">calculate</button>
<pre class="js-display-result"/>
You can test all combinations
const n = 30;
console.log('Number to reach: n = ' + n);
const k = [7, 5, 2];
console.log('Numbers to use: k = ' + k);
console.log('n can be wrote: n = a*k[0] + b*k[1] + c*k[2]');
console.log('Let\'s found all combinations of [a, b, c]');
let t = [];
for (let a = 0; n >= a*k[0]; a++)
for (let b = 0; n >= a*k[0] + b*k[1]; b++)
for (let c = 0; n >= a*k[0] + b*k[1] + c*k[2]; c++)
if (n == a*k[0] + b*k[1] + c*k[2])
t.push([a, b, c]);
console.log('Number of combinations: ' + t.length);
for (let i = 0; i < t.length; i++)
console.log(
n + ' = ' + new Array()
.concat(new Array(t[i][0]).fill(k[0]).join(' + '))
.concat(new Array(t[i][1]).fill(k[1]).join(' + '))
.concat(new Array(t[i][2]).fill(k[2]).join(' + '))
.filter(e => e.length > 0)
.join(' + ')
);
I am assuming you only want solutions that are unique in the sense that 2+5 and 5+2 aren't unique.
Using recursion you can create an algorithm that can solve this problem for every number and every list of constants.
const seek = 17;
const numbs = [2,5,7];
const minNum = Math.min(...numbs);
let numberOfCombinations = 0;
seekCombinations(seek, numbs);
function seekCombinations (toSeek, numbs) {
for (let i = 0; i < numbs.length; i++) {
let newToSeek = toSeek - numbs[i];
if (newToSeek === 0) { //you found a combination
numberOfCombinations++;
} else if (newToSeek >= minNum) { //The new number to seek can still form a combination
//remove numbers from your list of constants that are smaller then then the number that is already in your current combination so you'll only get unique solutions.
let index = numbs.indexOf(numbs[i]);
let newNumbs = numbs.slice(index, numbs.length);
//recursively call seekCombinations
seekCombinations (newToSeek, newNumbs, currentCombination)
}
}
}
so whats the question?
whats wrong with your script or how to do it?
in case you missed it,
multiplying the number with i doesnt solve this problem. because:
30 = 2 + 2 + 5 + 7 + 7 + 7
30 = 2 + 2 + 2 + 5 + 5 + 7 + 7
any number of one of those 3 constants can appear there.
these cases are not covered by your script

Get binary representation of integer

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));

Categories

Resources