Skip to content

Instantly share code, notes, and snippets.

@fj1
Created November 12, 2023 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fj1/0af00a3a434e3be8dcc5f38568e9ebd5 to your computer and use it in GitHub Desktop.
Save fj1/0af00a3a434e3be8dcc5f38568e9ebd5 to your computer and use it in GitHub Desktop.
Cassidoo #325
/**
* 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