At first I put the return inside the for loop but only the first result was getting displayed.
I've done some research and I realised that at result the loop was meeting the condition and therefore it was stopping at the first result.
I've taken it out of the loop and now it provides only the last result.
It's not the first time I've been having this issue and despite looking for a solution I can't understand what I'm doing wrong.
function diamond(n) {
let space = " "; //spaces
let newLine = "\n"
let aster = "*";
let multi = (n - 1) / 2; //variable in for loop
let result = ""
if ((n % 2 === 0) || n < 1) {
return null
} else if (n === 1) {
return aster
} else {
for (let i = 0; i < multi; i++) {
result = space.repeat(multi - i) + aster.repeat(1 + (i * 2)) + space.repeat(multi - i) + newLine;
}
return result // gives only the last result
}
}
console.log(diamond(7)) // expected " *\n ***\n*****\n ***\n *\n"
console.log(diamond(1)) // expected "*"
console.log(diamond(2)) // expected null
This happens because you reassign a new value at the variable result at each iteration of the loop.
You want to instanciate the variable first as a string.
Then concat datas to it at each iteration.
Something like this :
let result = '';
for (let i = 0; i < multi; i++) {
result += space.repeat(multi - i) + aster.repeat(1 + (i * 2)) + space.repeat(multi - i) + newLine;
}
return result;
Pay attention to the += operator :-)
Hope this would help you.
As others have hinted, use += to append each line to the result.
function diamond(n) {
let space = " "; //spaces
let newLine = "\n"
let aster = "*";
let multi = (n - 1) / 2; //variable in for loop
let result = ""
if ((n % 2 === 0) || n < 1) {
return null
} else if (n === 1) {
return aster
} else {
for (let i = 0; i < multi/2; ++i) {
result += space.repeat(multi - i) + aster.repeat(1 + (i * 2)) + space.repeat(multi - i) + newLine;
}
for (let i = 0; i < multi/2 + 1; ++i) {
result += space.repeat(i+1) + aster.repeat(1 + ((multi-1-i) * 2)) + space.repeat(i+1) + newLine;
}
return result // gives only the last result
}
}
console.log(diamond(7)) // expected " *\n ***\n*****\n ***\n *\n"
console.log(diamond(1)) // expected "*"
console.log(diamond(2)) // expected null
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]));
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)}`)```
I need some function to return pattern like this :
= * = * =
* = * = *
= * = * =
* = * = *
= * = * =
i try this but i cant get it:
function cetakGambar(angka){
let result = ''
for(let i=0; i<=angka; i++){
for(let j=0; j<=i; j++){
result += '= '
}
for(let k=0; k == i; k++){
result += ' *'
}
result += '\n'
}
return result
}
console.log(cetakGambar(5))
what looping i need to get that pattern
You were on the right track with the two nested loops. Here's an example small modification to solve the problem:
function cetakGambar(angka){
let result = ''
for(let i = 0; i < angka; i++){
for(let j = 0; j < angka; ++j) {
result += ((i + j) % 2 == 0) ? '= ' : '* ';
}
result += '\n';
}
return result
}
For each i a row is generated by looping over j. For each j we append either an = or * , depending on if after adding i and j the result is divisible by two (to create the alternating pattern). After each line a \n (newline) is appended.
Here's an ES6 solution w/o explicit iteration. It is not particularly concise and probably not too useful in this case but fun (IMHO), so I wanted to share it.
It uses Array.from to apply a generator function yielding the next symbol (* or =) for each cell and concats cells with spaces and rows with newlines.
// Utility to apply function <fn> <n> times.
function times(n, fn) {
return Array.from({ length: n }, fn);
}
// Generator function yielding the next symbol to be drawn.
//
function cetakGambar(angka) {
let generator = (function*() {
let [i, s1, s2] = [0, "*", "="];
while (true) {
// Make sure to start a new line with a different symbol for
// even rows in case <angka> is even
if (i++ % angka === 0 && angka % 2 === 0) {
[s1, s2] = [s2, s1];
}
// limit the generator to the number of values we actually need
if (i === angka * angka + 1) return;
yield i % 2 === 0 ? s1 : s2;
}
})();
return times(
angka,
() => times(angka, () => generator.next().value).join(" ") // join symbols w/ spaces ...
).join("\n"); // ... and lines w/ newline
}
console.log(cetakGambar(5));
Codesandbox here: https://codesandbox.io/s/wispy-http-mfxgo?file=/src/index.js
Different approach using one loop
function gen(row,col){
var i = 0;
var out="";
do {
if(i%col==0) out+="\n"
out += (i % 2) == 0 ? ' = ' : ' * ';
i++;
}
while (i < row*col);
return out;
}
console.log(gen(5,5));
Trying to take an integer and have it return as a
string with the integers from 1 to the number passed.
Trying to use a loop to return the string but not sure how!
Example of how I want it to look:
count(5) => 1, 2, 3, 4, 5
count(3) => 1, 2, 3
Not really sure where to even start
I would do it with a recursive function. Keep concatenating the numbers until it reaches 1.
var sequence = function(num){
if(num === 1) return '1';
return sequence(num - 1) + ', ' + num;
}
Or just:
var sequence = (num) => num === 1 ? '1' : sequence(num - 1) + ', ' + num;
You can use a for loop to iterate the number of times that you pass in. Then, you need an if-statement to handle the comma (since you don't want a comma at the end of the string).
function count(num) {
var s = "";
for(var i = 1; i <= num; i++) {
s += i;
if (i < (num)) {
s += ', ';
}
}
return s;
}
JSBin
Try this:
function count(n) {
var arr = [];
for (var i = 1; i<=n; i++) {
arr.push(i.toString());
}
return arr.toString();
}
Here's a non-recursive solution:
var sequence = num => new Array(num).fill(0).map((e, i) => i + 1).toString();
here is a goofy way to do it
function count(i)
{
while (i--) {
out = (i + 1) + "," + this.out;
}
return (out + ((delete out) && "")).replace(",undefined", "");
}
Quite possibly the most ridiculous way, defining an iterator:
"use strict";
function count ( i ) {
let n = 0;
let I = {};
I[Symbol.iterator] = function() {
return { next: function() { return (n > i) ? {done:true}
: {done:false, value:n++} } } };
let s = "";
let c = "";
for ( let i of I ) {
s += c + i;
c = ", "
}
return s;
}
let s = count(3);
console.log(s);
It's been a while since I wrote any Javascript. Is there a more elegant way to do this. Specifically want to get rid of the second loop:
<script>
var number = 0;
for (var i=1; i<11; i++) {
for (var x=1; x<11; x++) {
if (i==1) {
number = x;
} else {
number = Math.pow(i, x);
}
document.write(number + " ");
if (x == 10) {
document.write("<br>");
}
}
}
</script>
I would stick with 2 loops but i would change one if statement and move it after the 2nd loop and avoid document.write and insert it all at once to reduce the number of time you change the DOM
let result = ''
for (let i = 1; i < 11; i++) {
for (let x = 1; x < 11; x++)
result += (i==1 ? x : Math.pow(i, x)) + ' '
result += '<br>'
}
document.body.insertAdjacentHTML('beforeend', result)
Edit If you really don't want the 2nd loop:
let result = ''
// you must swap the condition to check for x instead of i
for (let i = 1, x = 1; x < 11; i++) {
result += (x==1 ? i : Math.pow(x, i)) + ' '
// and reset i and increase x yourself
if (i == 10) {
i = 0
x++
result += '<br>'
}
}
document.body.insertAdjacentHTML('beforeend', result)
Edit2 just for the fun: No for loops.
Just a recursive function :P
function build(i = 1, x = 1, res = '') {
res += (x == 1 ? i : Math.pow(x, i)) + ' '
i == 10 ? (x++, i=1, res += '<br>') : i++
return x == 11 ? res : build(i, x, res)
}
document.body.insertAdjacentHTML('beforeend', build())
In terms of 'elegancy', I'd go for for... in loops or map function. That doesn't solve your nested loop though.
On a side note, nested loops are not necessarily bad. If that's the correct way to implement the specific algorithm, then that's how it is.
Using Math.pow() is un-necessary overhead. Nested loops are not necessarily bad.
var number = 0;
for (var i=1; i<11; i++) {
document.write(i + " ");
number = i;
for (var x=2; x<11; x++) {
number = (i == 1) ? x : number * i;
document.write(number + " ");
}
document.write("<br>");
}
Another way of doing it with 1 loop only, tho not as clean:
var number = 0;
var x = 1;
var calc = 0;
var calcx = 1;
var increment = false;
for (var i=1; i<101; i++) {
increment = false;
calc = i % 10;
if(calc == 0){
calc = 10;
increment = true;
}
if (calcx==1) {
number = calc;
} else {
number = Math.pow(calcx, calc);
console.log(calcx+" "+calc);
}
document.write(number + " ");
if (i % 10 == 0) {
document.write("<br>");
}
if(increment){
calcx++;
}
}
Here's another way with only one loop:
[...Array(100)].map((_,i) => {
document.write(((i>9)?Math.pow(Math.floor((i+10)/10),(i%10)+1):i+1) + ' ' + ((i%10==9)?'<br>':''));
});