Javascript Draw pattern - javascript

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

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

Code to print a diamond with a given length in JavaScript

So I am currently learning JavaScript and I am interested in the many different ways one can accomplish something in programming. This is my diamond code, which will work with a given odd number:
const l = 11;
let space = ' ';
let star = '*';
let i = 1;
let k;
let n = 0;
while(i <= l) {
k = (l - i)/2;
console.log(space.repeat(k) + star.repeat(i));
i = i + 2;
}
// i = i - 2;
while(i >= 2) {
i = i - 2;
k = (l - i)/2;
if(i < l) { // To get rid of repeating middle line
console.log(space.repeat(k) + star.repeat(i));
} else {
continue;
}
}
Are there any other more intuitive ways to do this?
You could take a recursive approach and call the function until you got the longest star line.
function diamond(l, i = 1) {
const
STAR = '*',
SPACE = ' ',
LINE = SPACE.repeat((l - i) / 2) + STAR.repeat(i);
console.log(LINE);
if (i >= l) return;
diamond(l, i + 2);
console.log(LINE);
}
diamond(11);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Iterative Approach
If you wanted to use an iterative approach to solving this, you could do:
const makeDiamond = n => {
let total = n, iter = 0
const base = ['*'.repeat(n)] // Start with the middle, build out
while((n-=2) > 0) {
const layer = ' '.repeat(++iter)+'*'.repeat(n)
base.unshift(layer) // Prepend layer
base.push(layer) // Append layer
}
base.forEach(l => console.log(l)) // Print each layer in sequence
}
makeDiamond(11);
Note: this works for diamonds of even or odd sizes.
with reduce:
const n = 11;
Array.from(Array(~-n/2|0), (_,i) => " ".repeat(i+1) + "*".repeat(n+~i*2))
.reduce((a, c) => [c, ...a, c], ["*".repeat(n)])
.forEach(l=>console.log(l))
~-n/2|0 === Math.floor((n-1)/2)
n+~i*2 === n-(i+1)*2
Create a function to make the nth line.
Create the top by creating an array equal half the height and map it with the line function.
Join the top, then reverse the top and use that as the bottom.
const diamond=n=>(n=Array(~~(n/2)).fill().map((v,i)=>" ".repeat((n-i*2+1)/2)+"*".repeat(i*2+1))).join("\n")+"\n"+n.reverse().slice(1).join("\n");
console.log(diamond(10))
I actually managed to create another similar code that keeps i = i + 2 going instead of decreasing it in the second loop.
const l = 11;
let space = ' ';
let star = '*';
let i = 1;
let k;
let n = 0;
while(i <= l) {
k = (l - i)/2;
console.log(space.repeat(k) + star.repeat(i));
i = i + 2;
}
while(i >= l) {
k = (i - l)/2;
n = i - (4 * k);
if (n > 0) {console.log(space.repeat(k) + star.repeat(n));
} else { break; }
i = i + 2;
}

Replace numbers in a string with asterisks, and reveal them again

I have a problem with the following task. I want to achieve this output for n = 5:
* 2 3 4 5
* * 3 4 5
* * * 4 5
* * * * 5
* * * * *
* * * * *
* * * * 5
* * * 4 5
* * 3 4 5
* 2 3 4 5
I'm stuck in the second part of the exercise. My code for now:
var n = 5;
var numbers = '';
for (var i = 1; i <= n; i++) {
numbers += i;
}
for (var i = 0; i < n; i++) {
numbers = numbers.replace(numbers[i], '*');
console.log(numbers);
}
So far I have this result:
*2345
**345
***45
****5
*****
So now I need to add the spaces between numbers/stars, and make a reverse loop. I have no idea how to do it.
In addition, there is probably a faster solution to this task than I did.
You can save each of the numbers you generate on a stack (an array), and then pop them from the stack in reverse order:
var n = 5;
var numbers = '';
var stack = []; // <--- add this
for (var i = 1; i <= n; i++) {
numbers += i + ' '; // add a space here
}
for (var i = 0; i < n; i++) {
numbers = numbers.replace(i, '*'); // find/replace the digit
console.log(numbers);
stack.push(numbers); // <--- push on stack
}
while (stack.length > 0) {
numbers = stack.pop(); // <--- pull in reverse order
console.log(numbers); // <--- and print
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
A similar way, without the use of a stack, delays the output, and gathers all the strings in two longer strings which each will have multiple lines of output:
var n = 5;
var numbers = '';
var stack = [];
var output1 = ''; // <-- add this
var output2 = ''; //
for (var i = 1; i <= n; i++) {
numbers += i + ' ';
}
numbers += '\n'; // <-- add a newline character
for (var i = 0; i < n; i++) {
numbers = numbers.replace(i, '*');
output1 += numbers;
output2 = numbers + output2; // <-- add reversed
}
console.log(output1 + output2); // <-- output both
.as-console-wrapper { max-height: 100% !important; top: 0; }
Sticking with something similar to your approach:
var n = 5;
var numbers = '';
for (var i = 1; i <= n; i++) {
numbers += i + ' ';
}
for (var i = 0; i < n; i++) {
numbers = numbers.substr (0, i * 2) + '*' + numbers.substr (i * 2 + 1);
console.log(numbers);
};
for (var i = n - 1; i >= 0; i--) {
console.log(numbers);
numbers = numbers.substr (0, i * 2) + (i + 1) + numbers.substr (i * 2 + 1);
};
The disadvantage of this approach is that it only works for 0-9 because the string positions break when the numbers aren't single digits.
The way I might approach the problem is by having a variable that keeps track of up to which number needs to be an asterisk, doing the first half, then using a whole new for loop to do the second half.
For instance,
String result = '';
String line = '';
int counter = 1;
for (int line = 1; line =< 5; line++) {
for (int i = 1; i =< 5; i++) { // note that we start at 1, since the numbers do
if (i <= counter) {
line += '*'; // use asterisk for positions less than or equal to counter
else {
line += i; // otherwise use the number itself
}
line += ' '; // a space always needs to be added
}
result += line + '\n'; // add the newline character after each line
counter++; // move the counter over after each line
}
Then you can do the same loop, but make the counter go backwards. To do that, set counter to 5 before you begin the loop (since Strings are zero-indexed) and do counter-- after each line.
Alternatively if you don't want to write two loops, you can increase the outer for loop's limit to 10 and have an if statement check if you should be subtracting from counter instead of adding, based on the value of line
Decided to use this as an excuse to get more practice with immutable mapping and reducing. I used an array to hold all the rows, and reduce them at the end to a string. Each row starts as an array holding 1 to n, and each column number is then mapped to an asterisk based on the case:
if rowIndex <= number:
rowIndex.
else:
rowIndex - (2 * (rowIndex - number) - 1)
Essentially, [n + 1, n * 2] maps to (1, 3, 5, ..., n - 3, n - 1), which subtracted from the original range becomes [n, 1]. For the row, check if the currently selected column is less than or equal to its row's translated index, and return an asterisk or the number.
// expansion number (n by 2n)
const maxNum = 5;
// make an array to size to hold all the rows
const result = Array(maxNum * 2)
// Fill each row with an array of maxNum elements
.fill(Array(maxNum).fill())
// iterate over each row
.map((row, rowIndex) =>
// iterate over each column
row.map((v, column) => (
// check if the column is less than the translated rowIndex number (as mentioned above)
column < ((rowIndex <= maxNum) ?
rowIndex + 1 :
2 * maxNum - rowIndex
// if it is, replace it with an asterisk
)) ? "*" : column + 1)
// combine the row into a string with each column separated by a space
.reduce((rowAsString, col) => rowAsString + " " + col)
// combine all rows so they're on new lines
).reduce((rowAccum, row) => rowAccum + "\n" + row);
console.log(result);

How do you iterate over an array every x spots and replace with letter?

/Write a function called weave that accepts an input string and number. The function should return the string with every xth character replaced with an 'x'./
function weave(word,numSkip) {
let myString = word.split("");
numSkip -= 1;
for(let i = 0; i < myString.length; i++)
{
numSkip += numSkip;
myString[numSkip] = "x";
}
let newString = myString.join();
console.log(newString);
}
weave("weave",2);
I keep getting an infinite loop. I believe the answer I am looking for is "wxaxe".
Here's another solution, incrementing the for loop by the numToSkip parameter.
function weave(word, numToSkip) {
let letters = word.split("");
for (let i=numToSkip - 1; i < letters.length; i = i + numToSkip) {
letters[i] = "x"
}
return letters.join("");
}
Well you need to test each loop to check if it's a skip or not. Something as simple as the following will do:
function weave(word,numSkip) {
var arr = word.split("");
for(var i = 0; i < arr.length; i++)
{
if((i+1) % numSkip == 0) {
arr[i] = "x";
}
}
return arr.join("");
}
Here is a working example
Alternatively, you could use the map function:
function weave(word, numSkip) {
var arr = word.split("");
arr = arr.map(function(letter, index) {
return (index + 1) % numSkip ? letter : 'x';
});
return arr.join("");
}
Here is a working example
Here is a more re-usable function that allows specifying the character used for substitution:
function weave(input, skip, substitute) {
return input.split("").map(function(letter, index) {
return (index + 1) % skip ? letter : substitute;
}).join("");
}
Called like:
var result = weave('weave', 2, 'x');
Here is a working example
You dont need an array, string concatenation will do it, as well as the modulo operator:
function weave(str,x){
var result = "";
for(var i = 0; i < str.length; i++){
result += (i && (i+1)%x === 0)?"x":str[i];
}
return result;
}
With arrays:
const weave = (str,x) => str.split("").map((c,i)=>(i&&!((i+1)%x))?"x":c).join("");
You're getting your word greater in your loop every time, so your loop is infinite.
Try something like this :
for(let k = 1; k <= myString.length; k++)
{
if(k % numSkip == 0){
myString[k-1]='x';
}
}
Looking at what you have, I believe the reason you are getting an error is because the way you update numSkip, it eventually becomes larger than
myString.length. In my code snippet, I make i increment by numSkip which prevents the loop from ever executing when i is greater than myString.length. Please feel free to ask questions, and I will do my best to clarify!
JSFiddle of my solution (view the developer console to see the output.
function weave(word,numSkip) {
let myString = word.split("");
for(let i = numSkip - 1; i < myString.length; i += numSkip)
{
myString[i] = "x";
}
let newString = myString.join();
console.log(newString);
}
weave("weave",2);
Strings are immutable, you need a new string for the result and concat the actual character or the replacement.
function weave(word, numSkip) {
var i, result = '';
for (i = 0; i < word.length; i++) {
result += (i + 1) % numSkip ? word[i] : 'x';
}
return result;
}
console.log(weave("weave", 2));
console.log(weave("abcd efgh ijkl m", 5));
You can do this with fewer lines of code:
function weave(word, numSkip) {
word = word.split("");
for (i = 0; i < word.length; i++) {
word[i] = ((i + 1) % numSkip == 0) ? "x" : word[i];
}
return word.join("");
}
var result = weave("weave", 2);
console.log(result);

A code wars challenge

I have been struggling with this challenge and can't seem to find where I'm failing at:
Some numbers have funny properties. For example:
89 --> 8¹ + 9² = 89 * 1
695 --> 6² + 9³ + 5⁴= 1390 = 695 * 2
46288 --> 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51
Given a positive integer n written as abcd... (a, b, c, d... being digits) and a positive integer p we want to find a positive integer k, if it exists, such as the sum of the digits of n taken to the successive powers of p is equal to k * n. In other words:
Is there an integer k such as : (a ^ p + b ^ (p+1) + c ^(p+2) + d ^ (p+3) + ...) = n * k
If it is the case we will return k, if not return -1.
Note: n, p will always be given as strictly positive integers.
digPow(89, 1) should return 1 since 8¹ + 9² = 89 = 89 * 1
digPow(92, 1) should return -1 since there is no k such as 9¹ + 2² equals 92 * k
digPow(695, 2) should return 2 since 6² + 9³ + 5⁴= 1390 = 695 * 2
digPow(46288, 3) should return 51 since 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51
I'm new with javascript so there may be something off with my code but I can't find it. My whole purpose with this was learning javascript properly but now I want to find out what I'm doing wrong.I tried to convert given integer into digits by getting its modulo with 10, and dividing it with 10 using trunc to get rid of decimal parts. I tried to fill the array with these digits with their respective powers. But the test result just says I'm returning only 0.The only thing returning 0 in my code is the first part, but when I tried commenting it out, I was still returning 0.
function digPow(n, p){
// ...
var i;
var sum;
var myArray= new Array();
if(n<0)
{
return 0;
}
var holder;
holder=n;
for(i=n.length-1;i>=0;i--)
{
if(holder<10)
{
myArray[i]=holder;
break;
}
myArray[i]=holder%10;
holder=math.trunc(holder/10);
myArray[i]=math.pow(myArray[i],p+i);
sum=myArray[i]+sum;
}
if(sum%n==0)
{
return sum/n;
}
else
{
return -1;
}}
Here is the another simple solution
function digPow(n, p){
// convert the number into string
let str = String(n);
let add = 0;
// convert string into array using split()
str.split('').forEach(num=>{
add += Math.pow(Number(num) , p);
p++;
});
return (add % n) ? -1 : add/n;
}
let result = digPow(46288, 3);
console.log(result);
Mistakes
There are a few problems with your code. Here are some mistakes you've made.
number.length is invalid. The easiest way to get the length of numbers in JS is by converting it to a string, like this: n.toString().length.
Check this too: Length of Number in JavaScript
the math object should be referenced as Math, not math. (Note the capital M) So math.pow and math.trunc should be Math.pow and Math.trunc.
sum is undefined when the for loop is iterated the first time in sum=myArray[i]+sum;. Using var sum = 0; instead of var sum;.
Fixed Code
I fixed those mistakes and updated your code. Some parts have been removed--such as validating n, (the question states its strictly positive)--and other parts have been rewritten. I did some stylistic changes to make the code more readable as well.
function digPow(n, p){
var sum = 0;
var myArray = [];
var holder = n;
for (var i = n.toString().length-1; i >= 0; i--) {
myArray[i] = holder % 10;
holder = Math.trunc(holder/10);
myArray[i] = Math.pow(myArray[i],p+i);
sum += myArray[i];
}
if(sum % n == 0) {
return sum/n;
} else {
return -1;
}
}
console.log(digPow(89, 1));
console.log(digPow(92, 1));
console.log(digPow(46288, 3));
My Code
This is what I did back when I answered this question. Hope this helps.
function digPow(n, p){
var digPowSum = 0;
var temp = n;
while (temp > 0) {
digPowSum += Math.pow(temp % 10, temp.toString().length + p - 1);
temp = Math.floor(temp / 10);
}
return (digPowSum % n === 0) ? digPowSum / n : -1;
}
console.log(digPow(89, 1));
console.log(digPow(92, 1));
console.log(digPow(46288, 3));
You have multiple problems:
If n is a number it is not going to have a length property. So i is going to be undefined and your loop never runs since undefined is not greater or equal to zero
for(i=n.length-1;i>=0;i--) //could be
for(i=(""+n).length;i>=0;i--) //""+n quick way of converting to string
You never initialize sum to 0 so it is undefined and when you add the result of the power calculation to sum you will continually get NaN
var sum; //should be
var sum=0;
You have if(holder<10)...break you do not need this as the loop will end after the iteration where holder is a less than 10. Also you never do a power for it or add it to the sum. Simply remove that if all together.
Your end code would look something like:
function digPow(n, p) {
var i;
var sum=0;
var myArray = new Array();
if (n < 0) {
return 0;
}
var holder;
holder = n;
for (i = (""+n).length - 1; i >= 0; i--) {
myArray[i] = holder % 10;
holder = Math.trunc(holder / 10);
myArray[i] = Math.pow(myArray[i], p + i);
sum = myArray[i] + sum;
}
if (sum % n == 0) {
return sum / n;
} else {
return -1;
}
}
Note you could slim it down to something like
function digPow(n,p){
if( isNaN(n) || (+n)<0 || n%1!=0) return -1;
var sum = (""+n).split("").reduce( (s,num,index)=>Math.pow(num,p+index)+s,0);
return sum%n ? -1 : sum/n;
}
(""+n) simply converts to string
.split("") splits the string into an array (no need to do %10 math to get each number
.reduce( function,0) call's the array's reduce function, which calls a function for each item in the array. The function is expected to return a value each time, second argument is the starting value
(s,num,index)=>Math.pow(num,p+index+1)+s Fat Arrow function for just calling Math.pow with the right arguments and then adding it to the sum s and returning it
I have created a code that does exactly what you are looking for.The problem in your code was explained in the comment so I will not focus on that.
FIDDLE
Here is the code.
function digPow(n, p) {
var m = n;
var i, sum = 0;
var j = 0;
var l = n.toString().length;
var digits = [];
while (n >= 10) {
digits.unshift(n % 10);
n = Math.floor(n / 10);
}
digits.unshift(n);
for (i = p; i < l + p; i++) {
sum += Math.pow(digits[j], i);
j++;
}
if (sum % m == 0) {
return sum / m;
} else
return -1;
}
alert(digPow(89, 1))
Just for a variety you may do the same job functionally as follows without using any string operations.
function digPow(n,p){
var d = ~~Math.log10(n)+1; // number of digits
r = Array(d).fill()
.map(function(_,i){
var t = Math.pow(10,d-i);
return Math.pow(~~((n%t)*10/t),p+i);
})
.reduce((p,c) => p+c);
return r%n ? -1 : r/n;
}
var res = digPow(46288,3);
console.log(res);

Categories

Resources