How to make triangle with '&' and '+' symbol in JavaScript? - javascript

How to make a pyramid like this one in javascript?
👇
&
+++
&&&&&
+++++++
I've tried this one but didn't get the exact output.
function pyramid(n) {
for (let i = 1; i <= n; i++) {
let str = ' '.repeat(n - i);
let symb1 = '&'.repeat(i * 2 - 1);
let symb2 = '+'.repeat(i * 2 - 1);
console.log(str + symb1 + str);
console.log(str + symb2 + str);
}
}
pyramid(4)

You could do something like this:
Declare a variable res which gonna store in it, lines.
loop over number of lines and in each one switch between two symbols by using modulo %
function pyramid(n) {
let res = '';
for (let i = 1; i <= n; i++) {
let str = ' '.repeat(n - i);
let line = ['+', '&'][i % 2].repeat(i * 2 - 1);
res += str + line + "\n";
}
return res;
}
console.log(pyramid(4));
Note: \n character for a line break to add a new line into result string.

You're outputting both lines on every iteration of the loop:
let symb1 = '&'.repeat(i * 2 - 1);
let symb2 = '+'.repeat(i * 2 - 1);
console.log(str + symb1 + str);
console.log(str + symb2 + str);
Instead, conditionally output one or the other. You can check whether i is even or odd for the condition:
if (i % 2 == 1) {
let symb1 = '&'.repeat(i * 2 - 1);
console.log(str + symb1 + str);
} else {
let symb2 = '+'.repeat(i * 2 - 1);
console.log(str + symb2 + str);
}
(You can of course refactor this into something shorter, reduce repetition, etc. The point here is to demonstrate the goal of outputting one or the other instead of both.)

Use a ternary and test for even using remainder
You can push into an array and join with newlines
function pyramid(n) {
const lines = [];
for (let i = 1; i <= n; i++) {
let str = ' '.repeat(n - i);
let symb = (i%2===0 ? '+' : '&').repeat(i * 2 - 1);
lines.push(str + symb + str);
}
console.log(lines.join("\n"));
}
pyramid(4)

Related

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)}`)```

Javascript Draw pattern

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

for loop provides only first or last result

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

Javascript Math.random() and conditional expressions

I would like to share with you my thoughts about this code:
for (var i = 1, max = 5; i < max; i++) {
let random = Math.random();
let expression = (random < 1 / (i + 1));
if (expression){
console.log('random is: ' + random + ' and the expression is: ' + expression + ', i is: ' + i);
}else{
console.log('random was: ' + random + ' and the expression was: ' + expression + ', i was: ' + i);
}
}
I was studying this example taken from GitHub: https://github.com/chuckha/ColorFlood
And I had trouble trying to know what was the meaning of the expression inside the if().
I used the JS repl: https://jscomplete.com/repl/
The context of this example is that this function would take a random index from 0 to 5, to map a random color to a Node.
Here we have a sample output from the repl:
"random was: 0.7118559117992413 and the expression was: false, i was: 1"
"random was: 0.478919411809795 and the expression was: false, i was: 2"
"random was: 0.4610390397998597 and the expression was: false, i was: 3"
"random was: 0.7051121468181564 and the expression was: false, i was: 4"
The syntax:
let expression = (random < 1 / (i + 1));
Means:
(i + 1) first add 1 to var i
Next, 1 / (i + 1) divide 1 by the sum (i + 1)
Let say result = 1 / (i + 1)
random < result, if the random value less than above division result than return true, else false.
So, something simple like:
for (var i = 1, max = 5; i < max; i++) {
let random = Math.random();
let expression = (random < 1 / (i + 1));
console.log(
i,
random.toFixed(2),
(1 / (i + 1)).toFixed(2),
expression
)
}
I first thought that it would be evaluated random < 1 so then as random uses Math.random() which gets a number between 0 and 1, excluding the one; I thought that part of the expression would be alway true.
But in fact after putting it into the repl I discovered that the 1 / (i+1) part is done first, and then it is done all together: random / result.
I have also read:
https://www.w3schools.com/js/js_comparisons.asp
https://www.w3schools.com/js/js_arithmetic.asp
https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Math/random
Please note that in the original post I simplified the code, the original code is:
var randomIndexFromCollection = function randomIndexFromCollection(collection) {
var index = 0;
for (var i = 1, max = collection.length; i < max; i++) {
if (Math.random() < 1 / (i + 1)) {
index = i;
debugger;
}
}
return index;
};

Convert string of time to cleaner format

There's usually some magical way to do something in javascript.
Take for example the string
10h49m02s
and wanting to convert it to
10 hours, 49 minutes, 2 seconds
while avoid empty hours/minutes/seconds
eg2
00h10m20s
This is what I'm doing which is probably hilarious
var arr = time.split('');
var hourMaj = arr[0];
var hourMin = arr[1];
var minMaj = arr[3];
var minMin = arr[4];
var secMaj = arr[6];
var secMin = arr[7];
var str = "";
if(hourMaj !== '0'){
str += hourMaj;
str += hourMin;
}else if (hourMin !== '0'){
str += hourMin;
}
if(hourMaj !== '0' || hourMin !== '0')
str += "hours, ";
... and on
You can actually use a regex to match your values and replace h, m and s with expanded words only if the captured texts are not zeros, like this:
var re = /\b0*(\d{1,2})h0*(\d{1,2})m0*(\d{1,2})s\b/g;
var str = '10h49m02s';
var str2 = '00h10m20s';
function func(match, h, m, s) {
var p = '';
if (h !== '0') {
p += h + " hours"
}
if (m !== '0') {
p += (p.length > 0 ? ", " : "") + m + " minutes"
}
if (s !== '0') {
p += (p.length > 0 ? ", " : "") + s + " seconds"
}
return p;
}
var res = str.replace(re, func);
document.write(res + "<br/>");
res = str2.replace(re, func);
document.write(res);
The regex - \b0*(\d{1,2})h0*(\d{1,2})m0*(\d{1,2})s\b - matches:
\b - word boundary
0* - 0 or more leading zeros
(\d{1,2}) - hours, 1 or 2 digits
h0* - h literally and 0 or more zeros
(\d{1,2}) - minutes, 1 or 2 digits
m0* - m literally and 0 or more zeros
(\d{1,2}) - seconds, 1 or 2 digits
s\b - s at the end of the "word".
Similar to stribizhev's answer, but with a much simpler regular expression. I've used reduce but a for loop is no more code and would probably be faster:
function parseTime(s) {
// Match sequences of numbers or letters
var b = s.match(/\d+|[a-z]+/gi);
var words = {h:'hour', m:'minute', s:'second'};
var result;
// If some matches found
if (b) {
// Do replacement
result = b.reduce(function(acc, p, i) {
// Only include values that aren't zero
// and skip letters - +p => NaN
if (+p) {
// Change letters to words, add plural and store in array
acc.push(+p + words[b[i+1]] + (p==1? '' : 's'));
}
// Pass the accumulator array to the next iteration
return acc;
},[])
}
// Format the result
return result.join(', ');
}
document.write(parseTime('00h00m02s') + '<br>');
document.write(parseTime('10h40m02s') + '<br>');
document.write(parseTime('10h00m51s') + '<br>');
document.write(parseTime('01h32m01s'));

Categories

Resources