-
Notifications
You must be signed in to change notification settings - Fork 44
C22 Phenix Luqi Xie #33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,126 @@ | ||
const LETTER_POOL = { | ||
A: 9, | ||
B: 2, | ||
C: 2, | ||
D: 4, | ||
E: 12, | ||
F: 2, | ||
G: 3, | ||
H: 2, | ||
I: 9, | ||
J: 1, | ||
K: 1, | ||
L: 4, | ||
M: 2, | ||
N: 6, | ||
O: 8, | ||
P: 2, | ||
Q: 1, | ||
R: 6, | ||
S: 4, | ||
T: 6, | ||
U: 4, | ||
V: 2, | ||
W: 2, | ||
X: 1, | ||
Y: 2, | ||
Z: 1, | ||
}; | ||
|
||
const SCORE_CHART = { | ||
A: 1, | ||
E: 1, | ||
I: 1, | ||
O: 1, | ||
U: 1, | ||
L: 1, | ||
N: 1, | ||
R: 1, | ||
S: 1, | ||
T: 1, | ||
D: 2, | ||
G: 2, | ||
B: 3, | ||
C: 3, | ||
M: 3, | ||
P: 3, | ||
F: 4, | ||
H: 4, | ||
V: 4, | ||
W: 4, | ||
Y: 4, | ||
K: 5, | ||
J: 8, | ||
X: 8, | ||
Q: 10, | ||
Z: 10 | ||
}; | ||
|
||
export const drawLetters = () => { | ||
// Implement this method for wave 1 | ||
const letterList = []; | ||
for (const [letter, count] of Object.entries(LETTER_POOL)) { | ||
for (let i = 0; i < count; i++) { | ||
letterList.push(letter); | ||
} | ||
} | ||
const drawLetters = []; | ||
for (let i = 0; i < 10; i++) { | ||
const letterIndex = Math.floor(Math.random() * letterList.length); | ||
const lastPos = letterList.length - 1; | ||
[letterList[letterIndex], letterList[lastPos]] = [letterList[lastPos], letterList[letterIndex]]; | ||
drawLetters.push(letterList.pop()); | ||
Comment on lines
+70
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice approach of swapping the picked letter to the end, which then allows us to |
||
} | ||
return drawLetters; | ||
}; | ||
|
||
|
||
export const usesAvailableLetters = (input, lettersInHand) => { | ||
// Implement this method for wave 2 | ||
const letterFrequencyMap = {}; | ||
for (const letter of lettersInHand) { | ||
if (letterFrequencyMap[letter]) { | ||
letterFrequencyMap[letter] += 1; | ||
} else { | ||
letterFrequencyMap[letter] = 1; | ||
} | ||
} | ||
|
||
for (const letter of input.toUpperCase()) { | ||
if (!letterFrequencyMap[letter] || letterFrequencyMap[letter] === 0) { | ||
return false; | ||
} else { | ||
letterFrequencyMap[letter] -= 1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Even though JS doesn't use indentation to control the flow of logic, we should still make sure to follow good indentation practice to help with readability. So we'd want to indent this line. |
||
} | ||
} | ||
Comment on lines
+87
to
+93
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice use of a frequency map to check the validity of the owrd against th hand. We can build the map in a single iteration over the hand, then validate the word in a single iteration over the word, resulting in time complexity O(m + n), where m is the size of the hand and n is the size of the word. |
||
return true; | ||
}; | ||
|
||
export const scoreWord = (word) => { | ||
// Implement this method for wave 3 | ||
let totalScore = 0; | ||
for (const letter of word.toUpperCase()) { | ||
totalScore += SCORE_CHART[letter]; | ||
} | ||
Comment on lines
+98
to
+101
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great use of a score lookup table to keep this simple. We could also use let totalScore = word.toUpperCase().split('').reduce((acc, letter) => acc + SCORE_CHART[letter], 0); Personally, I find the loop approach you used more readable, but the reduce approach is also popular with JS programmers. |
||
if (word.length >= 7 && word.length <= 10) { | ||
totalScore += 8; | ||
} | ||
Comment on lines
+102
to
+104
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider creating global constants to use instead of the magic numbers, to make this code more self-documenting. const MIN_BONUS_LENGTH = 7;
const MAX_WORD_LENGTH = 10;
const LENGTH_BONUS = 8; then if (word.length >= MIN_BONUS_LENGTH && word.length <= MAX_WORD_LENGTH) {
totalScore += LENGTH_BONUS;
} |
||
return totalScore; | ||
}; | ||
|
||
export const highestScoreFrom = (words) => { | ||
// Implement this method for wave 4 | ||
let highestScore = 0; | ||
let bestWord = ""; | ||
|
||
for (const word of words) { | ||
const score = scoreWord(word); | ||
if (score > highestScore) { | ||
highestScore = score; | ||
bestWord = word; | ||
} else if (score === highestScore && bestWord.length !== 10) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Each of the nested cases would only apply if the best word wasn't already of length 10, so moving that up to this condition helps simplify the nested conditions. |
||
if (word.length === 10) { | ||
bestWord = word; | ||
} else if (word.length < bestWord.length) { | ||
bestWord = word; | ||
} | ||
} | ||
} | ||
return { word: bestWord, score: highestScore }; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -120,7 +120,10 @@ describe("Adagrams", () => { | |
}); | ||
|
||
it("returns a score of 0 if given an empty input", () => { | ||
throw "Complete test"; | ||
// throw "Complete test"; | ||
expectScores({ | ||
"": 0, | ||
}); | ||
Comment on lines
+124
to
+126
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
}); | ||
|
||
it("adds an extra 8 points if word is 7 or more characters long", () => { | ||
|
@@ -133,7 +136,7 @@ describe("Adagrams", () => { | |
}); | ||
}); | ||
|
||
describe.skip("highestScoreFrom", () => { | ||
describe("highestScoreFrom", () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
it("returns a hash that contains the word and score of best word in an array", () => { | ||
const words = ["X", "XX", "XXX", "XXXX"]; | ||
const correct = { word: "XXXX", score: scoreWord("XXXX") }; | ||
|
@@ -145,7 +148,8 @@ describe("Adagrams", () => { | |
const words = ["XXX", "XXXX", "X", "XX"]; | ||
const correct = { word: "XXXX", score: scoreWord("XXXX") }; | ||
|
||
throw "Complete test by adding an assertion"; | ||
// throw "Complete test by adding an assertion"; | ||
expect(highestScoreFrom(words)).toEqual(correct); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
}); | ||
|
||
describe("in case of tied score", () => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The order of the letters aren't important to JS, but we can make it a little easier to double check that the scores are all present and accounted for if we wrote this in alphabetical order.