Square text problem looking to loop solution - javascript

So I was tasked to take a string as an input and scramble it into a square code, i.e "If man was meant to stay on the ground god would have given us roots" returns imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau, where each letter in the new string comes from sorting the string into a column and the string is the vertical column of the square. i.e:
ifmanwas
meanttos
tayonthe
groundgo
dwouldha
vegivenu
sroots
I have a solution but it is clunky and if the square if bigger than 8 x 8 my solution breaks down. Looking to simplify just don't have the logic for it yet.
My intuition tells me there is a way I can loop this but I just can't see the method.
const squareCode = function(message) {
let newString = ""
let string = message.replace(/ /g, "");
let root =Math.ceil(Math.sqrt(string.length))
root = Math.round(root)
for (let i = 0; i < string.length; i ++){
if (i % root == 0 || i == 0){
newString += string[i]
}
} newString += " "
for (let i = 0; i < string.length; i ++){
if (i % root == 1 ){
newString += string[i]
}
} newString += " "
for (let i = 0; i < string.length; i ++){
if (i % root ==2){
newString += string[i]
}
} newString += " "
for (let i =0; i < string.length; i ++){
if ( i % root ==3){
newString += string[i]
}
} newString += " "
for (let i =0; i < string.length; i ++){
if ( i % root ==4){
newString += string[i]
}
} newString += " "
for (let i =0; i < string.length; i ++){
if ( i % root ==5){
newString += string[i]
}
} newString += " "
for (let i =0; i < string.length; i ++){
if ( i % root ==6){
newString += string[i]
}
} newString += " "
for (let i =0; i < string.length; i ++){
if ( i % root ==7){
newString += string[i]
}
} newString += " "
return newString
}
console.log(squareCode("chill out"));
console.log(squareCode("feed the dog"));
console.log(squareCode("have a nice day"));
console.log(squareCode("if man was meant to stay on the ground god would have given us roots"));
//my output
//clu hlt io
//fto ehg ee dd
//hae and via ecy
//imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau
I'm getting what I want i'd just prefer to do it in less than 50 lines of code.

One way to do it using Array#reduce
const squareCode = message => {
let string = message.replace(/\s+/g, "").split('');
let length = Math.ceil(Math.sqrt(string.length));
return string.reduce((acc, l, i) => (acc[i%length] += l, acc), new Array(length).fill('')).join(' ');
};
console.log(squareCode("chill out"));
console.log(squareCode("feed the dog"));
console.log(squareCode("have a nice day"));
console.log(squareCode("if man was meant to stay on the ground god would have given us roots"));
If the quest is to do it in as few lines of code as possible, regardless of readability
const squareCode = m => m.replace(/\s+/g, "").split('').reduce((a, l, i) => (a[i%Math.ceil(Math.sqrt(m.replace(/\s+/g, "").split('').length))] += l, a), new Array(Math.ceil(Math.sqrt(m.replace(/\s+/g, "").split('').length))).fill('')).join(' ');
console.log(squareCode("chill out"));
console.log(squareCode("feed the dog"));
console.log(squareCode("have a nice day"));
console.log(squareCode("if man was meant to stay on the ground god would have given us roots"));

Related

Js FOR loop returning 'undefined'

Im trying to add asterisks at the beginning and end of each word but I keep getting undefined at the end of my new string. Thanks for the help in advance.
function solution(s) {
var asterisks = "*"
var newString = ""
for(let i = 0; i <= s.length; i++){
if(s === ""){
return "*";
}else{
newString += asterisks + s[i];}
}
return newString;
}
I think your for loop should be
for(let i = 0; i < s.length; i++)
Cause in the last time of your for loop, i = s.length.
And s[s.length] = undefined
Your issue is for(let i = 0; i <= s.length; i++) the <= should just be < the undefined is coming from the last "length" character not existing.
You can get around adding the final * and the end of the last letter by add this code to the for loop:
if (i == (s.length -1)){
return newString += asterisks;
}
Working example:
function solution(s) {
var asterisks = "*"
var newString = ""
for(let i = 0; i < s.length; i++){
if(s === ""){
return "*";
}else{
newString += asterisks + s[i];}
if (i == (s.length -1)){
return newString += asterisks;
}
}
return newString;
}
document.getElementById("test").innerHTML = solution('hello');
<div id="test"></div>

Issue when creating from scratch toUpperCase function

I've been tasking with creating my own version of the toUpperCase() fucntion in JavaScript. This is what I have come up with. We were given a tester file and denied access to the source code. My output is as follows:
function stringToUppercase(string) {
/*
upper = ['A','B','C', etc...]
compare lowerY to upperY get index numbers of lowercase[y] that matches and use those to
create matching values at upperCase[y]
will print newString based on compared upper and lower values
*/
const upperCase = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
const lowerCase = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
const numbers = ['0','1','2','3','4','5','6','7','8','9'];
const specialChar = ['`','~','!','#','#','$','%','^','&','*','(',')','-','_','+','=','{','}','[',']','|',';',':','"','<'];
let newString = "";
for (let x = 0; x < string.length; x++){
for (let y = 0; y < lowerCase.length; y++) {
if (string[x] === lowerCase[y] || string[x] === upperCase[y]) {
newString += upperCase[y];
} else if (string[x] === '\n' || string[x] === '\t' || string[x] === ' '){
newString += string[x];
} else if (string[x] === numbers[y]) {
newString += string[x];
} else if (string[x] === specialChar[y]) {
newString += string[x];
}
}
}
return newString;
}
I have coded it up again, but this time following your requirements:
function stringToUppercase(string) {
const lowerCase = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
const upperCase = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
var newString = "";
outer:
for (var char = 0; char < string.length; char ++) {
for (var letter = 0; letter < lowerCase.length; letter ++) {
if (string[char] == lowerCase[letter]) {
newString += upperCase[letter];
continue outer;
}
}
newString += string[char];
}
return newString;
}
I have coded up a much more efficient 'stringToUppercase' function for you:
function stringToUppercase(string) {
const lowerCase = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
const upperCase = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
var newString = string;
for (var char = 0; char < lowerCase.length; char += 1) {
for (var x = 0; x < string.split(lowerCase[char]).length; x += 1) {
newString = newString.replace(lowerCase[char], upperCase[char]);
}
}
return newString;
}
Here's probably the most efficient solution.
function stringToUppercase(str) {
let out = "";
for (let i=0; i<str.length; i++) {
let charCode = str.charCodeAt(i);
if (charCode >= 0x61 && charCode <= 0x7A)
out += String.fromCharCode(charCode - 0x20);
else
out += str[i];
}
return out;
}
However, since you can't use built-in functions:
function stringToUppercase(string) {
const caseMap = {"a":"A", "b":"B", "c":"C", "d":"D", "e":"E", "f":"F", "g":"G", "h":"H", "i":"I", "j":"J", "k":"K", "l":"L", "m":"M", "n":"N", "o":"O", "p":"P", "q":"Q", "r":"R", "s":"S", "t":"T", "u":"U", "v":"V", "w":"W", "x":"X", "y":"Y", "z":"Z"}
var newString = "";
for (var i = 0; i < string.length; i += 1) {
const char = string[i];
if (char in caseMap)
newString += caseMap[char];
else
newString += char;
}
return newString;
}

All strings with length of the longest string

Hei, I have this function:
function frame(string) {
var words = string.split(" ");
var longestWord = 0;
var y = "*";
//Find the longest word from the string
for (var i = 0; i < words.length; i++) {
if (words[i].length > longestWord) {
longestWord = words[i].length;
}
}
console.log(y.repeat(longestWord + 4));
for (var i = 0; i < words.length; i++) {
console.log(y + " " + words[i] + " " + y);
//words[i].length = longestWord;
}
console.log(y.repeat(longestWord + 4));
}
I want that all the string has the same length as the longest string. The rest is working good. The code that is commented out is the one i tried last but is not working.
Apparently, the logic is not totally correct, but what I am missing?
Thank you
Strings are immutable in JS, you can't just overwrite the length attribute ;)
Do you mean, that you need padding after the word up to the length of the longest word? If I understood it correctly, then try something like this:
console.log(y + " " + words[i].padEnd(longestWord, " ") + " " + y);
This looks like the easiest way, but consult Can I use, if all your browsers are covered.
I would be tempted to get rid of some of the for loops to help readability. You can use Math.max and map to find the longest word and padEnd to fix the length:
function frame(string, y = '*') {
var words = string.split(" ");
let longestlength = Math.max(...words.map(w => w.length))
let header = y.repeat(longestlength + 4)
return [
header,
...words.map(word => `${y} ${word.padEnd(longestlength, ' ')} ${y}`),
header
]
}
console.log(frame("hello the word javascript is long").join('\n'))
Calculate the space left to fill and repeat it as below.
function frame(string) {
var words = string.split(" ");
var longestWord = 0;
var y = "*";
//Find the longest word from the string
for (var i = 0; i < words.length; i++) {
if (words[i].length > longestWord) {
longestWord = words[i].length;
}
}
console.log(y.repeat(longestWord + 4));
for (var i = 0; i < words.length; i++) {
spaceLeft = longestWord - words[i].length;
console.log(y + " " + words[i] + " ".repeat(spaceLeft) + " " + y);
//words[i].length = longestWord;
}
console.log(y.repeat(longestWord + 4));
}
frame('skfj dslfska sadflkdsflkdsnf ldsknflskdnaf dslkf')
The first loop for finding the max length of word seems right in second loop you can use if statement
All you have to do is that
First define an array
let a=[]
In second loop in the commented part write
if(word[I].length == longestlength){a.push(word[I])}
After that you get array containing word whose length is equal to max length
Hope it helps
function frame(string) {
var words = string.split(" ");
var longestWord = 0;
var y = "*";
//Find the longest word from the string
for (var i = 0; i < words.length; i++) {
if (words[i].length > longestWord) {
longestWord = words[i].length;
}
}
console.log(y.repeat(longestWord));
for (var i = 0; i < words.length; i++) {
console.log(words[i] + y.repeat(longestWord - words[i].length));
//words[i].length = longestWord;
}
}
frame('Lorem ipsum dolor sit amet, consectetur adipiscing elit')
maybe something like this, now every word has same length as the longest one, empty space is filled with *
See comments inline:
function frame(string) {
var words = string.split(" ");
var longestWord = "";
var y = "*";
//Find the longest word from the string
for (var i = 0; i < words.length; i++) {
if (words[i].length > longestWord.length) {
longestWord = words[i];
}
}
console.log("Longest word is: " + longestWord)
console.log(y.repeat(longestWord.length + 4));
for (var i = 0; i < words.length; i++) {
// Get the difference between the word and the longest word
var diff = longestWord.length - words[i].length;
// Pad the words with the right amount of spaces to make up the difference
console.log(y + " " + words[i] + " ".repeat(diff) + y);
}
console.log(y.repeat(longestWord.length + 4));
}
frame("The quick brown fox jumped over the lazy dog.");

Christmas tree in Javascript using stars

I have this loop problem, I really don't understand why my code doesn't work, I've even draw this on paper and for my logic it looks good but it's not working, please help me.
function drawTree(h) {
for(var i=0; i<=h; i++){
var star = '';
for(var k=0; k<=1; k++){
star += " ";
};
for(var j=0; j<=i; j++) {
star += "*";
};
};
console.log(star);
};
drawTree(5);
See comments in the code for changes.
function drawTree(h) {
for(var i=0; i<=h; i++){
var star = '';
//Changed to start high then decrease
for(var k = 1; k <= h - i; k++){
//shortened to one space
star += " ";
};
for(var j=0; j<=i; j++) {
//Added space so there is an odd number
//of symbols and the star above fits
//the space
star += " *";
};
//Moved into the loop
console.log(star);
};
};
drawTree(5);
Note that the code can be substantially shortened using String.prototype.repeat:
function drawTree(h) {
for (var i = 0; i <= h; i++){
console.log(" ".repeat(h - i) + " *".repeat(i + 1));
};
};
drawTree(5);
Also note that your example produces a base line with six stars for a call of drawTree(5). I am unsure whether that is intended. The code above reproduces said behavior, editing it to show a line less should not be too hard.
function drawTree(h) {
for (var i = 0; i < h; i++) {
var star = '';
var space = (h - i);
if (i == 0) {
star += ' '.repeat(space + 1) + '\n';
}
star += ' '.repeat(space + 1);
var zero = 2 * i + 1;
star += '*'.repeat(zero);
console.log(star);
}
}
drawTree(5);
You’re re-setting it each line, but printing it only at the end.
Move console.log(star); to the end of the first loop.
Just for fun:
const tree = ({height: h = 5, stumpHeight: sh = 2, branchChar: bc = '*', emptyChar: ec = ' ', stumpChar: sc = '#'} = {}) => [
... Array .from ({length: h}, (_, n) => ec .repeat (h - n - 1) + bc.repeat (2 * n + 1) + ec .repeat (h - n - 1)),
... Array .from ({length: sh}, () => ec .repeat (h - 1) + sc + ec .repeat (h - 1)),
] .join ('\n')
console .log (tree ())
console .log (tree ({height: 6, emptyChar: '_'}))
console .log (tree ({height: 12, stumpHeight: 3, stumpChar: '#'}))
console .log (tree ({branchChar: '#'}))
.as-console-wrapper {max-height: 100% !important; top: 0}
Because, you know, that's how all those JS 101 instructors expect it to be coded.
function drawTree(n) {
let tag = "#";
for (let i = 0, j = "#"; i < n; i++) {
console.log(tag);
tag = tag + j;
}
}
drawTree(10);
You have to place the console.log statement inside first for loop. That should give a half tree.
If you want correct tree, then pre-pend spaces before star.
Calculate the center of the number of rows and add spaces before it.
Hope this not an assignment problem.
function drawTree(h) {
for(var i=0; i<=h; i++){
var star = '';
for(var k=0; k<=1; k++){
star += " ";
};
for(var j=0; j<=i; j++) {
star += "*";
};
console.log(star);
};
};
drawTree(5);

Simple Javascript Christmas Tree

I created a half of the Christmas Tree but here I got blocked. Some one please help me to understand how to do the left side too.
for (var i = 0; i < 8; i++) {
for (var j = 0; j <= i; j++) {
document.write("^");
}
document.write("<br>");
}
<pre>
<script>
//Reads number of rows to be printed
var n = 8;
for(i=1; i<=n; i++)
{
//Prints trailing spaces
for(j=i; j<n; j++)
{
document.write(" ");
}
//Prints the pyramid pattern
for(j=1; j<=(2*i-1); j++)
{
document.write("*");
}
document.write("<br>");
}
</script>
</pre>
Source: http://codeforwin.org/2015/07/equilateral-triangle-star-pattern-program-in-c.html
C to JavaScript by me.
I wrote the following code for this problem.
I also added a nice extra, christmas-tree ornaments :-)
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
private static Random RND = new Random(System.currentTimeMillis()); // useful for placing balls
private static char[] BALLS = {'o','⌾','⛣','⏣','◍'}; // symbols being used as balls
public static void main (String[] args) throws java.lang.Exception
{
int w = 27; // width of the tree
int b = 10; // number of balls in the tree
String tree = ""; // this will end up containing the tree
// build tree
w = ( w % 2 == 1 ) ? w : 13; // check whether width is odd
for(int i=1;i<=w;i+=2){
int s = (w - i) / 2;
tree += repeat(' ', s) + repeat('*', i) + repeat(' ', s) + "\n";
}
// randomly replace some parts by balls
int i=0;
while(i < b){
int j = RND.nextInt(tree.length());
if(tree.charAt(j) == '*'){
tree = tree.substring(0, j) + BALLS[RND.nextInt(BALLS.length)] + tree.substring(j+1);
i++;
}
}
// build trunk
tree += repeat(' ', (w - 4) / 2) + repeat('*', 4) + "\n" + repeat(' ', (w - 4) / 2) + repeat('*', 4);
// output
System.out.println(tree);
}
// this function builds a String by repeating a given character a couple of times
private static String repeat(char c, int l){
String s = "";
for(int i=0;i<l;i++)
s += c;
return s;
}
}
The output should look something like this:
⏣
***
*o***
**⌾*o**
*****⛣**⛣
*****⌾****⏣
**◍*◍********
****
****
The keyword is think.
var x = 8;
for (let i = 0; i < x; i++) {
for (let j=x-1; j>i; j--) {
document.write("&nbsp&nbsp");
}
for (let k=0; k<=(i*2); k++) {
document.write("^");
}
document.write("<br>");
}
for (let i=0; i<2; i++) {
for (let j=0; j<(x*2)-3; j++) {
document.write("&nbsp");
}
document.write("^<br>");
}
Constraints: Only looks good starting from x = 5.
Original code by me
The answers above heavily rely on nested loops, thought I post another approach with "modern" JS (of course still using a single loop with the map function given to Array.from()):
function xmas(height) {
// add 1 more level for the trunk, e.g. height+1
return Array.from({length: height+1}, (v, i) => {
return i === height
// that's for the trunk of the tree
? '*'.padStart(Math.round((2 * i)/2), ' ')
// the actual tree "levels"
: '*'.repeat(2 * i + 1).padStart(2 * i + height-i, ' ');
}).join('\n');
}
document.write(`<pre>${xmas(10)}</pre>`);
maybe the attempt to make it work with .padStart() is not optimal because the math gets a bit ugly, but anyways, just for fun =)...
Here's a solution with a simple for loop without any nested loop.
let row = ""
let l = 9
for (let i = 0; i < l; i++) {
row += " ".repeat(l - i) + "*" + "*".repeat(i * 2) + `\n`;
}
console.log(row);
Simple christmas tree function:
function christmasTree(x) {
if(x < 3) {
return "";
}
let tree = "";
for(let i = 1; i <= x; i++) {
for(let j = 1; j <= x + x - 1; j++) {
if(j <= x - i || j >= x + i) {
tree += " ";
} else {
tree += "*";
}
}
tree += "\n";
}
return tree;
}
Incase you are looking for how to do this in a function for javascript or typescript
Use 3 for loops,
1 - Number of rows
2 - Number of spaces
3 - Number of characters
function christmas(n) {
let tree = '';
for (let i = 1; i <= n; i++) {
for (let j=0; j <= n-i; j++) {
tree += ' ';
}
for (k = 0; k< (i*2)-1; k++) {
tree += '*';
}
tree += '\n';
}
return tree;
}
console.log(christmas(3));
<pre>
<script>
//Reads number of rows to be printed
var n = 8;
for(i=1; i<=n; i++)
{
//Prints trailing spaces
for(j=i; j<n; j++)
{
document.write(" ");
}
//Prints the pyramid pattern
for(j=1; j<=(2*i-1); j++)
{
document.write("*");
}
document.write("<br>");
}
</script>
</pre>

Categories

Resources