Print smallest name with javascript [closed] - javascript

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I am facing a problem with javascript problem-solving.
I am now trying to print out the smallest name from a named array. But I cannot print out it. It shows the different names. Would you mind helping me, please?
see the codes.
var tinyFriend = ["hasan", "md", "mdhasan", "zahdhasan"];
var tiny = tinyFriend[0];
for (var i = 0; i < tinyFriend.length; i++) {
var char = tinyFriend[i];
if (char < tiny) {
tiny = char;
}
}
console.log(tiny);
please tell me where to make the correction

Just use the Reduce Method
var tinyFriend = ['hasan' , 'md' , 'mdhasan' , 'zahdhasan'];
var tiny = tinyFriend.reduce(function(a, b) {
return a.length <= b.length ? a : b;
});
console.log(tiny)

use the inbuilt sort method
var tinyFriend = ["hasan", "md", "mdhasan", "zahdhasan"];
var tiny = tinyFriend.sort((a, b) => a.length - b.length)[0];
console.log(tiny);
fix for original code
var tinyFriend = ["hasan", "md", "mdhasan", "zahdhasan"];
var tiny = tinyFriend[0];
for (var i = 0; i < tinyFriend.length; i++) {
var char = tinyFriend[i];
if (char.length < tiny.length) { // use length
tiny = char;
}
}
console.log(tiny);

You can simply use for-of loop here to get the smallest string in an array
var tinyFriend = ["hasan", "md", "mdhasan", "zahdhasan"];
let smallest;
for (let word of tinyFriend) {
if (smallest !== undefined) smallest = word.length < smallest.length ? word : smallest;
else smallest = word;
}
console.log(smallest);

You are making mistake in these two lines for (var i = 0; i <tinyFriend.length; i++) { & if (char < tiny) {
You have assigned tinyFriend[0]; to tiny so no need to start loop from 0. Instead start from 1. Secondly here if (char < tiny) { you need to check length
Here is my solution. Inside the loop just check if the length of the current name is smaller than the previous, then assign that name to tiny
var tinyFriend = ["hasan", "md", "mdhasan", "zahdhasan"];
var tiny = tinyFriend[0];
for (var i = 1; i < tinyFriend.length; i++) {
tiny = tiny.length > tinyFriend[i].length ? tinyFriend[i] : tiny;
}
console.log(tiny);

Related

Can i make this code more efficient / shorter to run?

So Im pretty new to javascript and coding in general. Im making a Wordle algorithm just for fun to build my skills in coding. and while making this algorithm i realized that i was going to have to kind of recreate Wordle. so i looked online for wordle recreations in java script, and all the ones I found I saw one flaw that I didn't want to have.
The flaw that I saw was in the IF statement for checking a letter in the wordle answer. Specifically when the letter is in the word but not in the right spot. The recreations that i saw had an IF statement that looked something like this.
IF (answerWord.includes(guessLetter[i])) {
guessLetter[i] = color.(yellow)
}
(this isnt exactly how they wrote it, but its the main idea)
My main focus is on the .includes. This would not work because say our guess word is "agree" and the answer word "ready". the 2 E's in "agree" would be yellow, and we dont want that because their is is only 1 E in "ready. So we only want the first E in "agree" to be yellow and not the second E.
So i decided to figure it out on my own, and i was able to come up with this and it works. At least Im pretty sure it works, base on the the many words i tested it on.
So my question is, since Im making an algorithm im going to be making alot of calculations, is this the most efficient i could write this or can i make it better?
let guessWord = "agree"; // the first word thats inputed
let answerWord = "ready"; // the answer to the wordle
/*
'letterCheck' is an array that tells what condition each letter in 'startLetter' is, based on the answer word
2 = the letter is in the word and in the correct place (GREEN)
1 = the letter is in the word but not in the correct place (YELLOW)
0 = the letter in not in the word (GREY)
*/
var letterCheck = ["0", "0", "0", "0", "0"];
var guessLetter = ["A", "A", "A", "A", "A"]; // the separated letters of 'startword' in a array
var answerLetter = ["A", "A", "A", "A", "A"]; // the separated letters of 'answord' in a array
//adds the start word and the answer world to the arrays
for (var i = 0; i < 5; i++) {
guessLetter[i] = guessWord.substring(i, i + 1);
answerLetter[i] = answerWord.substring(i, i + 1);
}
console.log(guessLetter);
console.log(letterCheck);
console.log(answerLetter);
//this loops goes though every letter one by one
for (var i = 0; i < 5; i++) {
//checks if the letter is in the right spot
if (guessLetter[i] == answerLetter[i]) {
letterCheck[i] = "2";
console.log(guessLetter[i]);
console.log(letterCheck);
} else if (answerWord.includes(guessLetter[i])) {
//checks if there is more than one letter in start word or its the first letter
if (guessWord.split(guessLetter[i]).length - 1 == 1 || i == 0) {
letterCheck[i] = "1";
console.log(guessLetter[i]);
console.log(letterCheck);
//checks if the the amount of same letters in start words is equel to the amount of same letters in answer word
} else if (guessWord.split(guessLetter[i]).length - 1 == answerWord.split(guessLetter[i]).length - 1) {
letterCheck[i] = "1";
console.log(guessLetter[i]);
console.log(letterCheck);
//opposite of above
} else if (guessWord.split(guessLetter[i]).length - 1 != answerWord.split(guessLetter[i]).length - 1) {
letterCheck[i] = "1";
console.log(guessLetter[i]);
console.log(letterCheck);
// checks if any of the letters infront of it are the same as it
for (var j = 0; j < i; j++) {
if (guessLetter[i] == guessLetter[j]) {
letterCheck[i] = "0";
console.log(guessLetter[i]);
console.log(letterCheck);
}
}
}
} else {
letterCheck[i] = "0";
console.log(guessLetter[i]);
console.log(letterCheck);
}
}
console.log(guessLetter);
console.log(letterCheck);
console.log(answerLetter);
( I will remove the console.log's later they just helped my to debug.)
Sorry if my code might be confusing, im not the best at keeping my code clean. if you have any confusion or questions, I'll try my best in clear up any confusion.
To get all of the states (in precedence order: correct, wrong-position, incorrect), you should check in that precedence order, and remove letters from contention once the state in that letter's position has been set.
function check(guess, targetWord) {
const checkStates = new Array(5).fill("incorrect");
const letters = guess.split('');
const targetLetters = targetWord.split('');
for (let i=0; i<5; i++) {
if (targetLetters[i] === letters[i]) {
checkStates[i] = "correct";
targetLetters[i] = '';
letters[i] = '';
}
}
for (let i=0; i<5; i++) {
if (!letters[i]) continue;
let fi = targetLetters.findIndex(t => t===letters[i]);
if (fi > -1) {
checkStates[i] = "contains";
targetLetters[fi] = '';
}
}
return checkStates;
}
let solution = "ready"
console.log(`solution is ${solution}`);
let guess = "agree";
console.log(`checking ${guess}... ${check(guess, solution)}`);
guess = "roars";
console.log(`checking ${guess}... ${check(guess, solution)}`);
guess = "boars";
console.log(`checking ${guess}... ${check(guess, solution)}`);
solution = "beast"
console.log(`\nsolution is ${solution}`);
guess = "treat";
console.log(`checking ${guess}... ${check(guess, solution)}`);
Well, here's something to consider in simplifying. You can use a simple MAP loop to determine which letters are incorrect, then later highlight those in the word.
let guessWord = "agree"; // the first word thats inputed
let answerWord = "ready"; // the answer to the wordle
let tmpGuess = guessWord.split('');
let incorrects = answerWord.split('').map(e => {
let i = tmpGuess.indexOf(e);
if (i > -1) { // found it!
tmpGuess.splice(i, 1); // remove
return '';
}
return e;
}).filter(f => f);
console.log(incorrects);

Remove duplicate values from flat ARRAY

I'm wanting to remove duplicate values from the array tabData produced by the script below.
I've found numerous posts here that mention "removing duplicates from array", but don't seem to be relevant to my exact goal.
I've tried filter, I've tried using this answer and adjusting the variables to fit my script, but it did not remove the duplicates.
Surely there is a simple function that does exactly what I'm looking for, I'm just not finding it.
function getTabArray() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var version = ss.getRangeByName("version").getValue().toString();
var updateTabsName = "updateTabs";
var updateTabsSheet = ss.getSheetByName(updateTabsName);
var tabDataRows = updateTabsSheet.getLastRow();
var tabDataCols = updateTabsSheet.getMaxColumns() - 1;
var tabDataRange = updateTabsSheet.getRange(1, 2, tabDataRows, tabDataCols);
var tabData = tabDataRange.getValues(); // <-- REMOVE DUPLICATES
for (var i = 0; i < tabData.length; i++) {
if (tabData[0][i] != "" && tabData[0][i] > version) {
for (var j = 0; j < tabData.length; j++) {
if (tabData[j][i] != "" && j > 0) {
Logger.log("tabData[j][i] = " + tabData[j][i]); // tabData[j][i] = all values in column
}
}
}
}
}
This is the array it currently produces:
2.20200514.2,2.20200514.0,2.20200513.2,2.20200513.1,2.20200513.0,2.20200512.0,1.20200405.1,,tabDefinitions,Sheet6,Sheet6,changeLog,Sheet6,Index,,,,Sheet7,,Sheet7,settings,,,,Sheet8,,Sheet8,tabDefinitions,,,,,,,changeLog,,,,,,,updateTabs
I want to remove all duplicates (Sheet6, Sheet7, Sheet8, etc.) from the array.
EDIT:
After one more search, I found this answer which contains exactly what was answered below, but when I use any method in that answer, I still get all duplicates. Not sure what I'm doing wrong or not doing right.
var unique = tabData.filter((v, i, a) => a.indexOf(v) === i);
EDIT 2:
I realized my array was not actually "flat", so I added var tabData = tabDataRange.getValues().flat(); and now everything works!
You can use ES6 Set() function to remove the duplicates
const newArray = [...new Set(arrayWithDuplicates)];

Logical error keeps for loop looping infinite, Why?

I'm trying to build a JavaScript devowelizer, but I'm producing an infinite loop.
I'm hoping someone on Stack Overflow can help?
The code =>
let userWord = prompt("Type a word to devowelize: ");
userWord = Devowelize(userWord);
alert(userWord);
function Devowelize(word) {
for (let i = 0; i <= word.length; i++) {
let eatChars = "aeiou"
for (let i2 = 0; i2 <= eatChars.length;) {
if (word[i] == eatChars[i2] &&
word[i] != "") {
word = word.replace(word[i], "");
} else {
i2++;
}
}
}
return word
}
You are using here for (let i = 0; i <= word.length; i++) this part i <= word.length isn't correct because you will try to access the array word using the i index after that in your code so in the last iteration you will access an index which is not defined by your array the last index of an array in javascript is always arrayLength-1 if you access an item which is out of the array you will get an undefined as value which will generates an infinte loop in your case you have done the same thing here for (let i2 = 0; i2 <= eatChars.length;) but the first loop is the responsible of the infinite loop in your code
Your solution is almost there, but you're trying to solve this problem in a very roundabout way. Let's make it a bit easier to understand.
In JavaScript, you can easily check if a string contains another string. For example, if we wanted to check if a character was in a string, we could do this:
let eatChars = "aeiou"
eatChars.includes('e') === true
So knowing that we can do that in a single statement, let's reuse some of the code you've got and substitute the character 'e' for the characters in your word.
let outWord = ""
const eatChars = "aeiou"
// '<= word.length' becomes this, because the string positions only go up to 'word.length - 1
for (let i = 0; i < word.length; i++) {
if (!eatChars.includes(word[i])) { // so the character isn't a vowel
outWord += word[i]
}
}
return outWord
The comments mention learning about 'map' and 'filter'. I'd recommend using a reducer for this if you wanted to be fancy! You could try something like this:
const devowel = (word) => Array.from(word).reduce((out, currentCharacter) => ...)

Using search method from string

I'm trying to count the number of times certain words appear in the strings. Every time I run it I get a
uncaught TypeErro: undefined is not a function
I just actually need to count the number of times each "major" appears.
Below is my code:
for(var i = 0; i < sortedarray.length; i++)
{
if(sortedarray.search("Multimedia") === true)
{
multimedia += 1;
}
}
console.log(multimedia);
Here is my csv file which is stored in a 1d array.
"NAME","MAJOR","CLASS STANDING","ENROLLMENT STATUS"
"Smith, John A","Computer Science","Senior","E"
"Johnson, Brenda B","Computer Science","Senior","E"
"Green, Daisy L","Information Technology","Senior","E"
"Wilson, Don A","Information Technology","Junior","W"
"Brown, Jack J","Multimedia","Senior","E"
"Schultz, Doug A","Network Administration","Junior","E"
"Webber, Justin","Business Administration","Senior","E"
"Alexander, Debbie B","Multimedia","Senior","E"
"St. John, Susan G","Information Technology","Junior","D"
"Finklestein, Harold W","Multimedia","Freshman","E"
You need to search inside each string not the array. To only search inside the "Major" column, you can start your loop at index 1 and increment by 4 :
var multimedia = 0;
for(var i = 1; i < sortedarray.length; i += 4)
{
if(sortedarray[i].indexOf("Multimedia") > -1)
{
multimedia += 1;
}
}
console.log(multimedia);
What you're probably trying to do is:
for(var i = 0; i < sortedarray.length; i++)
{
if(sortedarray[i].indexOf("Multimedia") !== -1)
{
multimedia++;
}
}
console.log(multimedia);
I use indexOf since search is a bit of overkill if you're not using regexes.
Also, I replaced the += 1 with ++. It's practically the same.
Here's a more straightforward solution. First you count all the words using reduce, then you can access them with dot notation (or bracket notation if you have a string or dynamic value):
var words = ["NAME","MAJOR","CLASS STANDING","ENROLLMENT STATUS"...]
var count = function(xs) {
return xs.reduce(function(acc, x) {
// If a word already appeared, increment count by one
// otherwise initialize count to one
acc[x] = ++acc[x] || 1
return acc
},{}) // an object to accumulate the results
}
var counted = count(words)
// dot notation
counted.Multimedia //=> 3
// bracket notation
counted['Information Technology'] //=> 3
I don't know exactly that you need this or not. But I think its better to count each word occurrences in single loop like this:
var occurencesOfWords = {};
for(var i = 0; i < sortedarray.length; i++)
{
var noOfOccurences = (occurencesOfWords[sortedarray[i]]==undefined?
1 : ++occurencesOfWords[sortedarray[i]]);
occurencesOfWords[sortedarray[i]] = noOfOccurences;
}
console.log(JSON.stringify(occurencesOfWords));
So you'll get something like this in the end:
{"Multimedia":3,"XYZ":2}
.search is undefined and isn't a function on the array.
But exists on the current string you want to check ! Just select the current string in the array with sortedarray[i].
Fix your code like that:
for(var i = 0; i < sortedarray.length; i++)
{
if(sortedarray[i].search("Multimedia") === true)
{
multimedia += 1;
}
}
console.log(multimedia);

How To Reverse an Algorithm [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am trying to find a math based way to find a password that makes the if statement in the below code true. I have written some stuff that brutes its way to an answer but that does not help me to understand how to solve this problem mathematically. The actual password I need to make the if statement true is irrelevant and not what I am asking for. I specifically want some code to get me started or even complete code that I can study to show me how to reverse engineer this algorithm to arrive at the answer using JavaScript.
var passed = false;
function checkPass(password) {
var total = 0;
var charlist = "abcdefghijklmnopqrstuvwxyz";
for (var i = 0; i < password.length; i++) {
var countone = password.charAt(i);
var counttwo = (charlist.indexOf(countone));
counttwo++;
total *= 17;
total += counttwo;
}
if (total == 248410397744610) {
passed = true;
alert(password);
}
}
Here's a simple code snippet that will do it:
function invertPass(n) {
var all = 'abcdefghijklmnopqrstuvwxyz',
out = '',
offset;
while (n > 0) {
offset = n % 17;
out = all.charAt(offset - 1) + out;
n = (n - offset) / 17;
}
return out;
}
function createPass(password) {
var total = 0;
var charlist = "abcdefghijklmnopqrstuvwxyz";
for (var i = 0; i < password.length; i++) {
var countone = password.charAt(i);
var counttwo = (charlist.indexOf(countone));
counttwo++;
total *= 17;
total += counttwo;
}
return total;
}
var orig = 'gdclhpdhbied',
num = createPass(orig);
console.log(invertPass(num) === orig);
Take a look at what the function actually does to total depending on its input: It multiplies by 17 and adds the position of the current char in the alphabet.
Therefore your expectedTotal (e.g. 248410397744610) will be a number divisible by 17 plus the alphabet position of the password's last letter. Use % (the modulus operator) to find said position (simply put, the number you need to subtract from expectedTotal to make it divisible by 17), then divide by 17 and repeat.

Categories