Need help on Highest and Lowest (codewars) - javascript

Hello I'm stuck on an edge case in a coding challenge: would be great if someone could help;
In this little assignment you are given a string of space separated numbers, and have to return the highest and lowest number.
Example:
highAndLow("1 2 3 4 5"); // return "5 1"
highAndLow("1 2 -3 4 5"); // return "5 -3"
highAndLow("1 9 3 4 -5"); // return "9 -5"
Notes:
All numbers are valid Int32, no need to validate them.
There will always be at least one number in the input string.
Output string must be two numbers separated by a single space, and highest number is first.
Here is my code in Javascript:
function highAndLow(numbers){
numbers2=numbers.split(' ');
var highest =parseInt(numbers2[0]);
var lowest =parseInt(numbers2[0]);
if (numbers2.length==1) {
return numbers;
}
else {
for (i=0;i<numbers2.length;i++) {
if (parseInt(numbers2[i])>highest) {
highest = parseInt(numbers2[i]);
}
else if (parseInt(numbers2[i])<lowest) {
lowest = parseInt(numbers2[i]);
}
}
}
return(highest + " " + lowest);
}
I can pass 17 tests but am stuck on an Expected '42 42' because I am returning '42' which is puzzling to me. Any help appreciated :]

I think you should just add <= and >= instead of > and <so the both conditions are satisfied

You can also do it by sorting the array and then choosing the first and last element from the sorted array.
function highestAndLowest(nums) {
let numbers = nums.split(' ');
let sorted = numbers.sort(function (a, b) {
return Number(a) - Number(b);
});
return sorted[0] + " " + sorted[sorted.length - 1];
}
https://jsbin.com/farapep/edit?js,console
This can be faster depending on the browsers sort implementation, the size of the array, and the initial order of the array.

I think it will work well just like this
function highAndLow(numbers){
numbers = numbers.split(" ");
return Math.max(...numbers) +" "+ Math.min(...numbers);
}

if (numbers2.length==1) {
return numbers;
}
That means if just "42" passed, you return "42". Thats not required here. Just remove that and it should work. How i would write it:
function getMaxMin(numbers){
numbers = numbers.split(" ");
return Math.max(...numbers) +" "+ Math.min(...numbers);
}
or your code a bit beautified:
function getMaxMin(numbers){
var max,min;
numbers = numbers.split(" ");
for( var num of numbers ){
if( !max || num > max ) max = num;
if( !min || num < min ) min = num;
}
return max+" "+min;
}

Kotlin
fun highAndLow(numbers: String): String {
val s = numbers.split(" ").sorted()
return "${s.last()} ${s.first()}"
}
or in one line
fun highAndLow(numbers: String): String = numbers.split(" ").sorted().run { "${first()} ${last()}" }

Let us consider the given example:
highAndLow("1 2 3 4 5"); // return "5 1"
On calling function highAndLow with arguments ("1 2 3 4 5"), output should be "5 1".
So my function takes the argument. Each number is picked upon on the basis of space between them(used split method). I have used ParseInt to specify the datatype, because var can be anything(string/integer). The algorithm used is very basic one which considers the first number as the maximum and compares its with the rest of the arguments. Value of max is updated if it finds a number greater than itself. Same algorithm is used for min value also. The return statement is designed to get the value in specific way as mentioned in the example.
function highAndLow(numbers){
num=numbers.split(' ');
var max = parseInt(num[0]);
var min = parseInt(num[0]);
for (var i = 0; i <= num.length; i++) {
if(parseInt(num[i]) > max){
max = parseInt(num[i]);
}
}
for (var i = 0; i <= num.length; i++) {
if(parseInt(num[i]) < min){
min = parseInt(num[i]);
}
}
return (max + " " + min);
}
You can also use inbuilt methods min and max. I wanted to solve this question without using them.

Related

Trying to find sum of factorial number using big-int npm gives wrong answer

I am doing euler problem where you need to find the sum of integers of a factorial number. so for example 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.
I wrote this using big-int library to deal with large numbers.
factorialize =(num)=> {
if (num < 0) {
return -1;
}
else if (num == 0) {
return 1;
}
else {
return (num * factorialize(num - 1));
}
}
findFactorialSum=(x)=>{
let total=0;
let result = bigInt(factorialize(x));
// let result=factorialize(x).toString().split("").map(el => parseInt(el));
// result.split("");
let converted = result.toString().split("").map(el => parseInt(el));
console.log(converted);
for(let i=0;i<=converted.length-1;i++)
{
total=total+converted[i]
}
console.log(total);
return total;
}
this works for small factorials and gives right answers but as soon as you go for something bigger then 12 it gives wrong answers, for example for 100 I get 683 but the answer according to the site should be 648 ><. I am guessing the big int library i am using returns wrong number but it worked for smaller numbers so I don't see what the issue can be.
I'm assuming the BigInt library you are using takes a big number as a string. Something like
bigint("23837458934509644434537504952635462348")
You are doing
let result = bigInt(factorialize(x));
The call to factorialize(100) has already overflowed Javascript's MAX_SAFE_INTEGER and passes the wrong string to the bigInt call.
You have to use BigInts to calculate the factorial as well.
Additionally to Jeril's answer which is your curlpit, you can also use reduce to calculate the sum of an Array. Demo:
const factorialize = (bigNum) => {
if (bigNum.lt(0)) {
return bigInt(-1);
} else if (bigNum.eq(0)) {
return bigInt(1);
} else {
return bigNum.times(factorialize(bigNum.minus(1)));
}
};
const findFactorialSum = (x) => {
const result = factorialize(bigInt(x)),
total = result.toString().split('')
.reduce((sum, digit) => sum + +digit, 0);
console.log(result.toString().split('').join('+') + ' = ' + total);
return total;
};
findFactorialSum(10); // 27
findFactorialSum(15); // 45
findFactorialSum(20); // 54
<script src="https://peterolson.github.io/BigInteger.js/BigInteger.min.js"></script>

C++ to javascript conversion

The question I'm doing is:
Write a JavaScript program to create a function which returns the number of times required to replace a given number with the sum of its digits until it converts to a single digit number. Like if given number is 123, number of times required to convert it into a single digit number is 1 (1+2+3=6). Your output code should be in the format console.log("Result is ", variableName)
I could not find the solution to this problem so I googled it and found this page.
The code on this page is in C/C++ ,Java etc...I took the C++ code and tried to convert it to javascript myself and this is the result:
var num=prompt("Enter a number");
var a= num.toString();
function test(x)
{var temporary_sum = 0, count = 0;
while (x.length() > 1)
{
temporary_sum = 0;
// computing sum of its digits
for (var i = 0; i < x.length(); i++)
temporary_sum += ( x[ i ] - '0' ) ;
// converting temporary_sum into string
// x again .
x = temporary_sum.toString() ;
// increase the count
count++;
}
return count;
}
var output = test(a) ;
console.log("Result is: ", output);
This code does not give any output at all. How can I fix this? Is there a better way to do this question?
Here is a better way to do that using recursion. And reduce
function test(x,count=0){
if(String(x).length === 1) return count;
let sum = String(x).split('').reduce((ac,a) => Number(a) + ac,0);
return test(sum,++count);
}
console.log(test(123)) //1
console.log(test(456)) //2
console.log(test(99999999999)) //3
I'll answer your last question - yes, there is a better way to do this question. You want to use recursion. You can also split the string on '' to convert its digits into an array, and you want to use parseInt to turn it back into a number.
I will use a different approach (I don't say it would be better). First, I will skip the mapping from number to string and wraps the logic that sums the digits of some number into a function called sumDigits(). This way you have a resusable method you can use for other purposes later. The second step is to define your test function using the previously created sumDigits mainly using the while loop you already have but testing with another condition and generalized to accept also integer negative numbers:
const sumDigits = (num) =>
{
let sum = 0;
while (num)
{
sum += num % 10, num = Math.floor(num / 10);
}
return sum;
}
const test = (num) =>
{
let counter = 0;
num = Math.abs(num);
while (num >= 10)
{
num = sumDigits(num), counter++;
}
return counter;
}
console.log(test(123));
console.log(test(456));
console.log(test(-789));

Truncating a String in Javascript (with constraints)

I'm working on this coding challenge from freecodecamp https://www.freecodecamp.com/challenges/truncate-a-string.
To complete this my code must fulfil the following 3 conditions:
Truncate a string (first argument) if it is longer than the given maximum string length (second argument). Return the truncated string with a ... ending.
The inserted three dots at the end should also add to the string length.
However if the given maximum string length is less than or equal to 3, then the addition of the three dots does not add to the string length in determining the truncated string.
I'm able to fulfil the first 2 conditions, but for some reason my code throws up an error when I give a test case where length of the string is less than or equal to 3...
Example:
truncateString("Absolutely Longer", 2) should return "Ab..." but instead returns "Absolutely Longe..."
Please help. My code is at https://gist.github.com/adityatejas/7857c0866f67783e71a1c9d60d3beed8.
function truncateString(str, num)
{
var truncatedStr = '';
if (str.length > num)
{
truncatedStr = str.slice(0, num-3) + "...";
return truncatedStr;
}
else if (num <= 3)
{
truncatedStr = str.slice(0, num) + "...";
return truncatedStr;
}
else return str;
}
truncateString("Adi", 1);
You want to create a function that takes in two parameters, a string of your choice and a maximum length. Based on the conditions, we need three scenarios.
When the given string exceeds the maximum and the maximum is less than or equal to 3. In this case, the ellipsis is not added to the end of the string. We take a slice of the string from the first character (position zero) until three less than the max and add the ellipses.
When the given string exceeds the maximum and the maximum is greater than 3. In this case, our strings inherently get longer. We update the slice parameters to go from the first index to the length of the string and add the ellipses on top of that.
Otherwise, just return the string as it is, because it does not exceed the maximum length.
var truncatedString = document.getElementById("truncated-string");
function truncateString(myString, strLength) {
if (myString.length > strLength) {
if (strLength <= 3) {
return myString.slice(0, strLength - 3) + "...";
}
else {
return myString.slice(0, strLength) + "...";
}
}
else {
return myString;
}
}
var userInput = prompt("Please enter a string");
var lengthLimit = prompt("Enter a maximum length");
truncatedString.innerHTML = truncateString(userInput, lengthLimit);
<p id="truncated-string"></p>
You could use a conditional (ternary) operator ?: and String#slice
function truncateString(str, num) {
return str.length > num ?
str.slice(0, num > 3 ? num - 3 : num) + "..." :
str;
}
console.log(truncateString("Abcdefghijk", 5));
console.log(truncateString("A-", 1));
console.log(truncateString("Alpha", 5));
console.log(truncateString("Beta", 5));
console.log(truncateString("Epsilon", 3));
Here is a simple solution:
function truncateString(str, num) {
if (str.length > num) {
return str.slice(0, num) + "...";}
else {
return str;}}

Need help writing code to convert decimal to binary without the use of the toString

I'm trying to create my own decimal to binary converter with the method of decrementing the inputted variable (decimal value), by dividing it by 2 and storing the remainder (like 2nd grade math remainder), which is always either 0 or 1. Each of the remainder values i thin should be stored in an array and I think maybe put in backwards so that the most significant digit is first in the array (this is because when decrementing the remainer values are filled in left to right). Soooo yea i dont really know how to store the remainder values in an array using a function
Thanks in advance and if something is confusing then feel free to ask because im not even sure if this is the best method of doing this its just what i came up with
function decimalToBinary(num) {
var bin = 0;
while (num > 0) {
bin = num % 2 + bin;
num >>= 1; // basically /= 2 without remainder if any
}
alert("That decimal in binary is " + bin);
}
Your code is almost correct. The main problem is that bin starts out as 0; when you add a digit, they are added numerically, so your code ends up just counting the binary 1s: in this manner, 10 is initial 0, and +1+0+1+0, resulting in 2. You want to handle it as a string: ""+1+0+1+0 results in 1010. So, the only needed change is:
var bin = "";
If you want to solve it using arrays, with minimal changes to your code, it would be:
function decimalToBinary(num) {
var bin = [];
while (num > 0) {
bin.unshift(num % 2);
num >>= 1; // basically /= 2 without remainder if any
}
alert("That decimal in binary is " + bin.join(''));
}
Here, I use .unshift to add an element to the head of the array (and renumbering the remaining elements); .join() to collect them all into a string.
Or this:
function decimalToBinary(num) {
var bin = [];
while (num > 0) {
bin[bin.length] = num % 2;
num >>= 1; // basically /= 2 without remainder if any
}
alert("That decimal in binary is " + bin.reverse().join(''));
}
This is not as good, but illustrates some more things you can do with arrays: taking their length, setting an arbitrary element, and flipping them around.
I have written a custom Decimal to Binary method:
function toBinary (input) {
let options = [1];
let max = 0;
let i = 1;
while(i) {
max = Math.pow(2, i);
if (max > input) break;
options.push(max);
i++;
}
let j = options.length;
let result = new Array(j);
result.fill("0");
while(j >= 0) {
if (options[j] <= input) {
result[j] = "1"
input = input - options[j];
}
j--;
}
return [...result].reverse().join("");
}
//Test the toBin method with built-in toString(2)
toBinary(100) === (100).toString(2) // true
toBinary(1) === (1).toString(2) // true
toBinary(128) === (128).toString(2) // true

Fibonacci Sequence - Find the number of digits - JavaScript

So, I have successfully written the Fibonacci sequence to create an array with the sequence of numbers, but I need to know the length (how many digits) the 500th number has.
I've tried the below code, but its finding the length of the scientific notation (22 digits), not the proper 105 it should be returning.
Any ideas how to convert a scientific notation number into an actual integer?
var fiblength = function fiblength(nth) {
var temparr = [0,1];
for(var i = 2; i<=nth; i++){
var prev = temparr[temparr.length-2],
cur = temparr[temparr.length-1],
next = prev + cur;
temparr.push(next);
}
var final = temparr[temparr.length-1].toString().length;
console.log(temparr[temparr.length-1]);
return final;
};
a = fiblength(500);
console.log(a);
Why not use the simple procedure of dividing the number by 10 until the number is less than 1.
Something as simple as this should work (a recursive def obv works as well)
function getDigits(n) {
var digits = 0;
while(n >= 1) {
n/=10;
digits += 1;
}
return digits;
}
getDigits(200);//3
getDigits(3.2 * 10e20);//=>22
Here's a solution in constant time:
function fiblength(n) {
return Math.floor((n>1)?n*.2089+.65051:1);
}
Let's explain how I arrived to it.
All previous solutions will probably not work for N>300 unless you have a BigNumber library in place. Also they're pretty inneficient.
There is a formula to get any Fibonacci number, which uses PHI (golden ratio number), it's very simple:
F(n) = ABS((PHI^n)/sqrt(5))
Where PHI=1.61803399 (golden ratio, found all over the fibonacci sequence)
If you want to know how many digits a number has, you calculate the log base 10 and add 1 to that. Let's call that function D(n) = log10(n) + 1
So what you want fiblength to be is in just the following function
fiblength(n) = D(F(n)) // number of digits of a fibonacci number...
Let's work it out, so you see what the one liner code will be like once you use math.
Substitute F(n)
fiblength(n) = D(ABS((PHI^n)/sqrt(5)))
Now apply D(n) on that:
fiblength(n) = log10(ABS((PHI^n)/sqrt(5))) + 1
So, since log(a/b) = log(a) - log(b)
fiblength(n) = log10(ABS((PHI^n))) - log10(sqrt(5))) + 1
and since log(a^n) = n * log(a)
fiblength(n) = n*log10(PHI) - log10(sqrt(5))) + 1
Then we evaluate those logarithms since they're all on constants
and add the special cases of n=0 and n=1 to return 1
function fiblength(n) {
return Math.floor((n>1)?n*.2089+.65051:1);
}
Enjoy :)
fiblength(500) => 105 //no iterations necessary.
Most of the javascript implementations, internally use 64 bit numbers. So, if the number we are trying to represent is very big, it uses scientific notation to represent those numbers. So, there is no pure "javascript numbers" based solution for this. You may have to look for other BigNum libraries.
As far as your code is concerned, you want only the 500th number, so you don't have to store the entire array of numbers in memory, just previous and current numbers are enough.
function fiblength(nth) {
var previous = 0, current = 1, temp;
for(var i = 2; i<=nth; i++){
temp = current;
current = previous + current;
previous = temp;
}
return current;
};
My Final Solution
function fiblength(nth) {
var a = 0, b = 1, c;
for(var i=2;i<=nth;i++){
c=b;
b=a+b;
a=c;
}
return Math.floor(Math.log(b)/Math.log(10))+1;
}
console.log(fiblength(500));
Thanks for the help!!!
The problem is because the resulting number was converted into a string before any meaningful calculations could be made. Here's how it could have been solved in the original code:
var fiblength = function fiblength(nth) {
var temparr = [0,1];
for(var i = 2; i<=nth; i++){
var prev = temparr[temparr.length-2],
cur = temparr[temparr.length-1],
next = prev + cur;
temparr.push(next);
}
var x = temparr[temparr.length-1];
console.log(x);
var length = 1;
while (x > 1) {
length = length + 1;
x = x/10;
}
return length;
};
console.log ( fiblength(500) );

Categories

Resources