Doing an assignment for my JavaScript class that requires me to create a function that adds every other index starting with the first and subtracting all the indexes not previously added and produces the sum. I believe the function below should work but it seems to return undefined.
function questionSix(){
let result = 0;
for(let i = 0; i < arguments.length; i++){
if(i == 0){
result += arguments[i];
}else{
if(i % 2 != 0){
result += arguments[i];
}
if(i % 2 == 0){
result -= arguments[i];
}
}
}
}
Because you aren't returning anything (there is no return statement in your code) :
function questionSix(){
let result = 0;
for(let i = 0; i < arguments.length; i++) {
if(i == 0){
result += arguments[i];
}else{
if(i % 2 != 0){
result += arguments[i];
}
if(i % 2 == 0){
result -= arguments[i];
}
}
}
return result;
}
console.log(questionSix(1,6,5,7,8,9,9,8,4,5));
However, it looks like your code isn't doing exactly what it should, here's a solution to your problem :
function questionSix(){
let result = 0; // the sum
let array = []; // the numbers added
for(let i = 0; i < arguments.length; i++) {
// was the number added ?
if(array.indexOf(i) > -1){ // Yes
result += arguments[i]; // add it to the sum
}else{ // No
result -= arguments[i]; // subtract it from the sum
array.push(arguments[i]); // add it to the array
}
}
return result; // return the sum
}
console.log(questionSix(1,6,5,7,8,9,9,8,4,5));
You haven't included a "return" statement
The clue to this (apart from there being no return statement!) is that you start with a result=0 statement, and yet you are receiving undefined.
You don't have to do a special case for i==0
When i==0, i % 2 will equal 0, so the "inner" if-then-else will do the job adequately, without the if (i==0) segment.
Swap the += and -=
However I wonder whether you have reversed the += and -= ? You want to add the 0th and all even-indexed values, don't you? And subtract the odd ones?
Related
I am trying to insert dashes ('-') between each two odd numbers and insert asterisks ('*') between each two even numbers, but I am only getting the last result.
I want to print out all the elements in the array.
For example: if num is 4546793 the output should be 454*67-9-3. I Did not count zero as an odd or even number.
function StringChallenge(num) {
let result = "";
for (let i = 0; i < num.length; i++) {
if (num[i] === 0) {
continue;
}
if (num[i - 1] % 2 == 0 && num[i] % 2 == 0) {
result = num[i - 1] + "*" + num[i];
continue;
}
if (num[i - 1] % 2 == !0 && num[i] % 2 == !0) {
result = num[i - 1] + "-" + num[i];
continue;
}
}
return result;
}
console.log(StringChallenge([4,5,4,6,7,9,3]));
You do not need to check as if&continue. Inserting given numbers to the result string and only adding "-" when index and previous are odd, and "*" when index and previous are even.
function StringChallenge(num) {
let result = "";
for (let i = 0; i < num.length; i++) {
if (num[i]%2 ===0) {// even
if(i !== 0 && num[i-1]%2===0){// previous is even either
result+="*"+num[i];
}else{
result+=num[i];
}
}else{// odd
if(i !== 0 && num[i-1]%2===1){// previous is odd either
result+="-"+num[i];
}else{
result+=num[i];
}
}
}
return result;
}
console.log(StringChallenge([4,5,4,6,7,9,3]));
Try this :)
function test(a){
let result=""
for(let i=0; i < a.length; i++){
if(a[i] != 0 && a[i-1] % 2 == 0 && a[i] % 2 == 0){
result = result + '*' + a[i]
}
else if (a[i] != 0 && a[i-1] % 2 != 0 && a[i] % 2 != 0){
result = result + '-' + a[i]
}
else{
result = result + a[i]
}
}
return result
}
console.log(test([4,5,4,6,7,9,3]));
As everyone has identified, the problem is you are not adding to result.
But here is a suggestion to make your code easier to read
// These one line functions make your code easier to read
function IsEven(num){
return num % 2 === 0;
}
function IsOdd(num){
return num % 2 !== 0;
}
function StringChallenge(numArray) {
// return empty string if not an array or empty array
if(!Array.isArray(numArray) || numArray.length === 0) return "";
let result = "" + numArray[0]; // use "" to coerce first element of numArray from number to string
for (let i = 1; i < numArray.length; i++) {
// focus on the conditions to determine the separator you want between each element
separator = "";
if (numArray[i] !== 0) {
if (IsEven(numArray[i]) && IsEven(numArray[i - 1])) {
separator = "*";
} else if (IsOdd(numArray[i]) && IsOdd(numArray[i - 1])){
separator = "-";
}
}
// build the result
result += separator + numArray[i];
}
return result;
}
I will do that this way :
== some advices for 2 cents ==
1 - try to make your code as readable as possible.
2 - use boolean tests rather than calculations to simply do a parity test
3 - ES7 has greatly improved the writing of JS code, so take advantage of it
console.log(StringChallenge([4,5,4,6,7,9,3])); // 454*67-9-3
function StringChallenge( Nums = [] )
{
const
isOdd = x => !!(x & 1) // Boolean test on binary value
, isEven = x => !(x & 1) && x!==0 // zero is not accepted as Even value
;
let result = `${Nums[0]??''}`; // get first number as
// result if Nums.length > 0
for (let i=1; i<Nums.length; i++)
{
if ( isOdd(Nums[i-1]) && isOdd(Nums[i]) ) result += '-';
if ( isEven(Nums[i-1]) && isEven(Nums[i]) ) result += '*';
result += `${Nums[i]}`; // same as Nums[i].toString(10);
}
return result
}
I hope this helps. I tried to keep it as simple as possible.
function StringChallenge(num) {
//start with a string to concatenate, or else interpreter tries to do math
operations
let result = num[0].toString();
function checkOdd(num){ //helper function to check if odd
return num % 2
}
for (let i = 0; i < num.length - 1; i++) {
if (checkOdd(num[i]) && checkOdd(num[i+1])) { //checks if both odd
result += `-${num[i+1]}`; //adds - and next number
} else if (!checkOdd(num[i]) && !checkOdd(num[i+1])) { //checks if both even
result += `*${num[i+1]}`; //adds * and next number
} else { //otherwise
result += num[i+1]; //just add next number
}
}
return result;
}
console.log(StringChallenge([4,5,4,6,7,9,3]));
Use +=. And, change your logic, your code prints out "4*67-99-3".
The zero check was pretty hard for me I hope the variables in my code explain itself. If not, let me know.
function even(num) {
return num % 2 === 0;
}
function odd(num) {
return num % 2 !== 0;
}
function StringChallenge(num) {
let result = "";
for (let i = 0; i < num.length; i++) {
var currentZero = num[i] === 0
var previousZero = num[i-1] === 0
var bothEven = even(num[i]) && even(num[i-1])
var bothOdd = odd(num[i]) && odd(num[i-1])
var firstNumber = (i === 0)
if (!currentZero) {
if (firstNumber) {
result += num[i]
} else {
if (bothEven && !previousZero) {
result += "*" + num[i]
} else if (bothOdd && !currentZero) {
result += "-" + num[i]
} else {
result += num[i]
}
}
}
}
return result;
}
console.log(StringChallenge([0,4,5,0,4,6,7,9,3]));
I have an issue with a recursive algorithm, that solves the problem of finding the happy numbers.
Here is the code:
function TestingFunction(number){
sumNumberContainer = new Array(0);
CheckIfNumberIsHappy(number);
}
function CheckIfNumberIsHappy(number){
var sumOfTheNumbers = 0;
for (var i = 0; i < number.length; i++) {
sumOfTheNumbers += Math.pow(parseInt(number[i]), 2);
}
console.log(sumOfTheNumbers);
if(sumOfTheNumbers == 1){
return CheckIfNumberIsHappy(sumOfTheNumbers.toString());
//return true;
} else {
sumNumberContainer.push(sumOfTheNumbers);
if(sumNumberContainer.length > 1){
for (var i = 0; i < sumNumberContainer.length - 1; i++) {
for (var j = i + 1; j < sumNumberContainer.length; j++) {
if(sumNumberContainer[i] == sumNumberContainer[j]){
return CheckIfNumberIsHappy(sumOfTheNumbers.toString());
//return false;
}
}
}
}
CheckIfNumberIsHappy(sumOfTheNumbers.toString());
}
}
Algorithm is working ALMOST fine. I've tested it out by calling function with different numbers, and console was displaying correct results. The problem is that I almost can't get any value from the function. There are only few cases in which I can get any value: If the number is build out of ,,0", and ,,1", for example 1000.
Because of that, I figured out, that I have problem with returning any value when the function is calling itself again.
Now I ended up with 2 results:
Returning the
return CheckIfNumberIsHappy(sumOfTheNumbers.toString());
which is giving an infinity looped number. For example when the number is happy, the function is printing in the console number one again and again...
Returning the
//return true
or
//return false
which gives me an undefined value
I'm a little bit in check by this problem, and I'm begging you guys for help.
I would take a step back and reexamine your problem with recursion in mind. The first thing you should think about with recursion is your edge cases — when can you just return a value without recursing. For happy numbers, that's the easy case where the sum of squares === 1 and the harder case where there's a cycle. So test for those and return appropriately. Only after that do you need to recurse. It can then be pretty simple:
function sumSq(num) {
/* simple helper for sums of squares */
return num.toString().split('').reduce((a, c) => c * c + a, 0)
}
function isHappy(n, seen = []) {
/* seen array keeps track of previous values so we can detect cycle */
let ss = sumSq(n)
// two edge cases -- just return
if (ss === 1) return true
if (seen.includes(ss)) return false
// not an edge case, save the value to seen, and recurse.
seen.push(ss)
return isHappy(ss, seen)
}
console.log(isHappy(23))
console.log(isHappy(22))
console.log(isHappy(7839))
Here's a simplified approach to the problem
const digits = x =>
x < 10
? [ x ]
: [ ...digits (x / 10 >> 0), x % 10 ]
const sumSquares = xs =>
xs.reduce ((acc, x) => acc + x * x, 0)
const isHappy = (x, seen = new Set) =>
x === 1
? true
: seen.has (x)
? false
: isHappy ( sumSquares (digits (x))
, seen.add (x)
)
for (let n = 1; n < 100; n = n + 1)
if (isHappy (n))
console.log ("happy", n)
// happy 1
// happy 7
// happy 10
// ...
// happy 97
The program above could be improved by using a technique called memoization
Your code is almost correct. You just forgot to return the result of the recursive call:
function TestingFunction(number){
sumNumberContainer = new Array(0);
if (CheckIfNumberIsHappy(number))
console.log(number);
}
function CheckIfNumberIsHappy(number){
var sumOfTheNumbers = 0;
for (var i = 0; i < number.length; i++) {
sumOfTheNumbers += Math.pow(parseInt(number[i]), 2);
}
if(sumOfTheNumbers == 1){
return true;
} else {
sumNumberContainer.push(sumOfTheNumbers);
if(sumNumberContainer.length > 1){
for (var i = 0; i < sumNumberContainer.length - 1; i++) {
for (var j = i + 1; j < sumNumberContainer.length; j++) {
if(sumNumberContainer[i] == sumNumberContainer[j]){
return false;
}
}
}
}
return CheckIfNumberIsHappy(sumOfTheNumbers.toString());
}
}
for (let i=0; i<100; ++i)
TestingFunction(i.toString()); // 1 7 10 13 ... 91 94 97
I've got the solution, which was given to me in the comments, by the user: Mark_M.
I just had to use my previous
return true / return false
also I had to return the recursive statement in the function, and return the value of the CheckIfTheNumberIsHappy function, which was called in TestingFunction.
The working code:
function TestingFunction(number){
sumNumberContainer = new Array(0);
return CheckIfNumberIsHappy(number);
}
function CheckIfNumberIsHappy(number){
var sumOfTheNumbers = 0;
for (var i = 0; i < number.length; i++) {
sumOfTheNumbers += Math.pow(parseInt(number[i]), 2);
}
console.log(sumOfTheNumbers);
if(sumOfTheNumbers == 1){
return true;
} else {
sumNumberContainer.push(sumOfTheNumbers);
if(sumNumberContainer.length > 1){
for (var i = 0; i < sumNumberContainer.length - 1; i++) {
for (var j = i + 1; j < sumNumberContainer.length; j++) {
if(sumNumberContainer[i] == sumNumberContainer[j]){
return false;
}
}
}
}
return CheckIfNumberIsHappy(sumOfTheNumbers.toString());
}
}
Thanks for the great support :)
I'm looking for the sum of a range but I keep getting "undefined." I believe something's in the wrong spot but I'm not sure as to what it is.
Part 1: "Write a range function that takes two arguments, start and end, and returns an array containing all of the numbers from start up to (and including) end:
Part 2: "Next, write a sum function that takes an array of numbers and returns the sum of these numbers. Run the previous program and see whether it does indeed return 55."
// Part 1
function deRange(start, end, step) {
if (step === null) {
step = 1;
var blank = [];
if (step > 0) {
for (var i = start; i <= end; i += step)
blank.push(i);
} else {
for (var i = start; i >= end; i += step)
blank.push(i);
}
}
return blank;
}
// Part 2
function theSum(blank) {
var total = 0;
for (var i = 0; i < blank.length; i++)
total += blank[i];
return total;
}
console.log(deRange(1, 10));
console.log(deRange(5, 2, -1));
console.log(theSum(deRange(1, 10)));
You have misplaced your curly brackets. This works:
function range(start, end, step) {
if (step === null) {
step = 1;
}
var blank = [];
if (step > 0) {
for (var i = start; i <= end; i += step)
blank.push(i);
} else {
for (var i = start; i >= end; i += step)
blank.push(i);
}
return blank;
}
console.log(range(1, 5, null));
Note that you are checking if step is null, so the user still needs to explicitly give null as argument. If you want to set a default value if no third argument is provided, use e.g.:
step = step || 1;
(This also treats 0 as a missing argument, which is good.)
Below I fixed your code and commented some errors you have in it. Check the demo.
// Part 1
function deRange(start, end, step) {
/**
* If you want to make sure 'step' is not 0 (zero) either,
* change the if like this:
* if(!step) { step = 1; }
*/
if (step === null || typeof step === 'undefined') { // <- also check when 'step' was not passed as argument
step = 1;
} // <-- curly brace here!
var blank = [];
if (step > 0) {
for (var i = start; i <= end; i += step)
blank.push(i);
} else {
for (var i = start; i >= end; i += step)
blank.push(i);
}
return blank;
}
// Part 2
function theSum(blank) {
var total = 0;
for (var i = 0; i < blank.length; i++)
total += blank[i];
return total;
}
console.log(deRange(1, 10));
console.log(deRange(5, 2, -1));
console.log(theSum(deRange(1, 10)));
how to transform every 3rd character to uppercase. for example this string pifedvcbtauzkwgnxyjrhmq converted into piFedVcbTauKkwGnxYjrHmq.
here is what i've done so far
function up3rdletter(str){
var i, result = '';
for(i = 0; i < str.length; i++){
if(i > 0 && i % 3 == 0){
result += str[i].toUpperCase();
}else{
result += str[i];
}
}
return result;
}
the script above return pifEdvCbtAuzKwgNxyJrhMq, it start converting from 4th letter. if I change the modulo number to 2 it become piFeDvCbTaUzKwGnXyJrHmQ
It's rather trivial: indexing in JS starts from 0, but you want to change letters based on 1-based index, natural for human beings. ) Solution? Either shift the remainder check:
result += i % 3 === 2 ? str[i].toUpperCase() : str[i];
... or go on checking against 0, but advance i instead:
result += (i + 1) % 3 ? str[i] : str[i].toUpperCase();
But actually, I'd probably write it as follows:
result = str.replace(/(..)(.)/g, function(_, m1, m2) {
return m1 + m2.toUpperCase();
});
function up3rdletter(str){
var i, result = '';
var counter = 1;
for(i = 0; i < str.length; i++){
if(i > 0 || counter % 3 == 0){
result += str[i].toUpperCase();
}else{
result += str[i];
}
counter++;
}
return result;
}
I made a function that counts the occurances of x's and o's in a given string and returns true if they are equal.
function ExOh(str) {
var x_count = 0;
var o_count = 0;
for (var i = 0;i < str.length-1;i++){
if (str[i] === 'x'){
x_count = x_count + 1;
}
else if (str[i] === 'o'){
o_count = o_count + 1;
}
}
console.log(o_count);
console.log(x_count);
if (x_count === o_count){
return true;}
else{
return false;
}
}
// keep this function call here
// to see how to enter arguments in JavaScript scroll down
ExOh(readline());
I added the lines of code
console.log(o_count);
console.log(x_count);
To see if it was counting correctly and I discovered that was the issue. After testing it I realized that this function is not testing the last element in the string. I tried changing the length of the for loop, but I can't think of what else could be wrong.
Any advice?
Thanks mates
JavaScript arrays are 0 index based objects. So, your loop should be like this
for (var i = 0; i < str.length; i++) {
otherwise the last element will be skipped.
Consider that the length of the string is 5. So, i starts from 0 and if you had your original condition
for (var i = 0; i < str.length - 1; i++) {
following are the comparisons happening in the loop
0 < 4
1 < 4
2 < 4
3 < 4
4 < 4 -- Fails
So it breaks out of the loop. But the last element will be at index 4. But when you have the condition like this
for (var i = 0; i < str.length; i++) {
the comparisons go like this
0 < 5
1 < 5
2 < 5
3 < 5
4 < 5
5 < 5 -- Fails
It breaks out of the loop only after comparing all the elements.
So, your actual program can be written like this
function ExOh(str) {
var x_count = 0, o_count = 0;
for (var i = 0; i < str.length; i++) {
if (str[i] === 'x') {
x_count = x_count + 1;
} else if (str[i] === 'o') {
o_count = o_count + 1;
}
}
return x_count === o_count;
}
alternate method to count characters:
var s = 'example';
s.split('').filter(function (i) { return i === 'e'; }).length; // 2
Your for loop is running one too short. Try this instead.
for (var i = 0;i < str.length;i++){
if (str[i] === 'x'){
x_count = x_count + 1;
}
else if (str[i] === 'o'){
o_count = o_count + 1;
}
}
Your problem is in for loop. Try changing to this.
for (var i = 0; i < str.length; i++) {
If you want to avoid using for loops, you can use this much shorter version of ExOh function.
function ExOh(str) {
return str.match(/o/g).length == str.match(/x/g).length
}
Rather than looping over the whole String with for, I'd see if using indexOf achieves a faster result
function countOccurance(haystack, needle) {
var total = 0, pos = -1;
while (-1 !== (pos = haystack.indexOf(needle, pos + 1)))
total += 1;
return total;
}
Then
var x_count = countOccurance(str, 'x'),
o_count = countOccurance(str, 'o');
return x_count === o_count;
EDIT looks like I might have been wrong about it being faster! jsperf
function indexOfMethod(haystack, needle) {
var total = 0, pos = -1;
while (-1 !== (pos = haystack.indexOf(needle, pos + 1)))
total += 1;
return total;
}
function splitMethod(haystack, needle) {
return haystack.split(needle).length - 1;
}
function forMethod(haystack, needle) {
var total = 0, i;
for (i = 0; i < haystack.length; ++i)
if (haystack.charAt(i) === needle)
total += 1;
return total;
}
The forMethod will only work with char needle, whereas the other two should work with any String as needle, if that matters.