Created
November 12, 2023 19:22
-
-
Save fj1/0af00a3a434e3be8dcc5f38568e9ebd5 to your computer and use it in GitHub Desktop.
Cassidoo #325
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* https://buttondown.email/cassidoo/archive/quality-is-not-an-act-it-is-a-habit-will-durant/ | |
* | |
* Given a list of words and a dictionary of letter scores, | |
* find the word with the highest score according to the rules: | |
* score = word_length * (sum of letter scores in the word). | |
* | |
* If there are multiple words with the same highest score, | |
* return the lexicographically smallest one. | |
* | |
* Example: | |
* | |
* const letterScores = [...Array(26).keys()].reduce( | |
* (scores, i) => ((scores[String.fromCharCode(97 + i)] = i + 1), scores), | |
* {} | |
* ); | |
* // This produces { 'a': 1, 'b': 2, 'c': 3, 'd': 4, ... } | |
* | |
* const wordList = ["apple", "banana", "cherry", "date", "fig"]; | |
* scoreWordGame(wordList, letterScores); // 'cherry' | |
*/ | |
// This produces { 'a': 1, 'b': 2, 'c': 3, 'd': 4, ... } | |
const letterScores = [...Array(26).keys()].reduce( | |
(scores, i) => ((scores[String.fromCharCode(97 + i)] = i + 1), scores), | |
{} | |
); | |
// not supported in all browsers: | |
// https://caniuse.com/mdn-javascript_builtins_intl_listformat_format | |
const formatList = new Intl.ListFormat('en', { | |
style: 'long', | |
type: 'conjunction' | |
}); | |
// in a tie, the winners have the shortest word length | |
const breakTieScore = words => { | |
const sortedByLength = words.sort((a, b) => a.length - b.length); | |
const shortestWordLength = sortedByLength[0].length; | |
const winners = sortedByLength.filter(word => word.length === shortestWordLength); | |
return `${formatList.format(winners)} win${winners.length > 1 ? '' : 's'}! 🎉`; | |
} | |
const scoreWordGame = (wordList, letterScores) => { | |
let highScores = [{ | |
score: 0, | |
word: '', | |
}]; | |
wordList.forEach(word => { | |
const splitWord = word.split(''); | |
const score = splitWord.reduce((acc, currChar) => { | |
return acc + letterScores[currChar]; | |
}, 0); | |
// console.log(`${word}'s score is ${score}`); | |
if (score > highScores[0].score) { | |
// keep track of high scores | |
highScores = [{ | |
score, | |
word | |
}]; | |
} else if (score === highScores[0].score) { | |
// keep track of high score ties | |
highScores = [ | |
...highScores, | |
{ | |
score, word | |
} | |
]; | |
} | |
}); | |
if (highScores.length === 1) { | |
return `${highScores[0].word} wins! 🎉`; | |
} | |
// more than one winning word | |
const tieWords = highScores.map(item => item.word); | |
return breakTieScore(tieWords); | |
}; | |
const wordList1 = ['apple', 'banana', 'cherry', 'date', 'fig']; | |
console.log(scoreWordGame(wordList1, letterScores)); // cherry | |
// 'jiffy' and 'miso' have the same score | |
// but 'miso' wins because it is shorter | |
const wordList2 = [ | |
'jiffy', | |
'miso', | |
]; | |
console.log(scoreWordGame(wordList2, letterScores)); // miso | |
// all the words have the same score of 6 | |
// and there is a 3 way tie | |
const wordList3 = [ | |
'abc', | |
'aaaaaa', | |
'cba', | |
'bbb', | |
]; | |
console.log(scoreWordGame(wordList3, letterScores)); // abc, cba, bbb | |
// all the words have the same score of 6 | |
// but only 1 winner because 'cc' is the shortest word | |
const wordList4 = [ | |
'abc', | |
'aaaaaa', | |
'cc', | |
'bbb', | |
]; | |
console.log(scoreWordGame(wordList4, letterScores)); // cc |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment