Skip to content
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

Esther Annorzie - Sea Turtles #97

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c741f96
Created scoreChart variable to hold letter distribution
estherannorzie Jun 5, 2022
4880f36
Able to draw ten letters from pool and return an array
estherannorzie Jun 5, 2022
29b6ebb
Added shuffle algorithm for drawLetters
estherannorzie Jun 6, 2022
7b3c719
Created frequency map for input and lettersInHand, 1 test passes
estherannorzie Jun 7, 2022
2934cd0
Adjusted input loop to compare input frequencies
estherannorzie Jun 7, 2022
af5d6d0
Implemented scoreChart for scoreWord
estherannorzie Jun 7, 2022
1b5f735
Added uppercasing for wave 3 loop
estherannorzie Jun 7, 2022
a836570
Added assertion for empty input in wave 3
estherannorzie Jun 7, 2022
075cca8
Created score variable to hold scoreWord return value
estherannorzie Jun 7, 2022
9d4dd59
Created an array to hold score and loop to added each word's score to…
estherannorzie Jun 7, 2022
a59e847
Added shuffling algorithm source
estherannorzie Jun 8, 2022
09fd913
Started pseudocode for highestScoreFrom
estherannorzie Jun 9, 2022
ab2fbd4
Formatted pseudocode
estherannorzie Jun 9, 2022
47ee11c
Fixed for loop to create array of word scores in highestScoreFrom
estherannorzie Jun 9, 2022
7d77e1c
Create loop to check for highest score in array, returns object with …
estherannorzie Jun 9, 2022
76e0931
Removed stray import
estherannorzie Jun 9, 2022
1407b18
Changed highestScoreFrom max score looping length
estherannorzie Jun 9, 2022
2ec2f47
Fixed off-by-one error in highestScoreFrom loop
estherannorzie Jun 9, 2022
802f984
Adjusted syntax of return in highestScoreFrom
estherannorzie Jun 9, 2022
f0692cf
Adjusted highestScoreFrom to loops correctly, started working on tie …
estherannorzie Jun 10, 2022
52f0778
Renamed highestScoreFrom variables to camel case
estherannorzie Jun 10, 2022
a02d19d
Deleted some comments and whitespace
estherannorzie Jun 10, 2022
f613888
Added assertion to highestScoreFrom test
estherannorzie Jun 10, 2022
b666e82
Added pseudocode to highestScoreFrom
estherannorzie Jun 10, 2022
c1e7ada
Separated maxWords into new logic/for loop
estherannorzie Jun 10, 2022
6d8a769
Renamed variable name for tied words array
estherannorzie Jun 10, 2022
50d4bad
Changed wordScores loops to iterate forward, passed wave 4
estherannorzie Jun 11, 2022
944c72a
Renamed scoreChart to availableLetters, remove stray file
estherannorzie Jun 11, 2022
22307c0
Edited gitignore
estherannorzie Jun 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a workspace specific settings file. If we see unexpected new files added to a PR, we usually want to double check if they're necessary and remove them from being tracked by git if not. It's not something we need to worry about for our projects, but it can come up when working on a shared code base.

If a file is not already being tracked by git we can list it in the .gitignore file and git will know never to track it, but if git is already tracking a file (like this one), telling it to stop and removing it from tracking takes a step or two. This stack overflow talks about how you can remove a file from being tracked if you're interested: https://stackoverflow.com/questions/1274057/how-can-i-make-git-forget-about-a-file-that-was-tracked-but-is-now-in-gitign

"cSpell.enableFiletypes": [
"!javascript",
"!markdown"
]
}
159 changes: 158 additions & 1 deletion src/adagrams.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,172 @@
export const drawLetters = () => {
// Implement this method for wave 1
const scoreChart = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'd want to rename this something like letterPool or availableLetters to better reflect what it holds.

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,
};

let letters = [];

for (const [letter, inputLetterFreq] of Object.entries(scoreChart)) {
for (let i = 0; i < inputLetterFreq; i++) {
letters.push(letter);
}
};
// not able to create a shuffling algo myself
// Fisher-Yates shuffle algorithm
// https://masteringjs.io/tutorials/fundamentals/shuffle#:~:text=To%20properly%20shuffle%20an%20array%20in%20JavaScript%2C%20use,random%20element%20in%20the%20array%20as%20shown%20below.
for (let i = letters.length - 1; i >= 1; i--) {
let j = Math.floor(Math.random() * (i + 1));
let temp = letters[j];
letters[j] = letters[i];
letters[i] = temp;
};
return letters.slice(0, 10);
Comment on lines +39 to +48

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a proper shuffling algorithm can be a significant problem to solve. We could use the letters array in another approach to create a hand.

If we create an empty list hand, we could fill it by looping 10 times and in each iteration:

  1. create a random number between 0 and the last index of the letters array
  2. Get the letter at our random index from the letter list
  3. Push that letter onto our hand array
  4. Use something like splice to remove the letter at our random index from the letter array so the letter can't be used twice

At the end of our loop we'll have a full hand array and can return it!

};

export const usesAvailableLetters = (input, lettersInHand) => {
// Implement this method for wave 2
let inputLetterFreq = {};

for (const letter of input) {
if (letter.toUpperCase() in inputLetterFreq) {
inputLetterFreq[letter.toUpperCase()] += 1;
} else {
inputLetterFreq[letter.toUpperCase()] = 1;
}
};

let lettersInHandFreq = {};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice use of frequency maps =]


for (const letter of lettersInHand) {
if (letter.toUpperCase() in lettersInHandFreq) {
lettersInHandFreq[letter.toUpperCase()] += 1;
} else {
lettersInHandFreq[letter.toUpperCase()] = 1;
}
};

for (const letter of input) {
/* If the letter does not exist in the `lettersInHandFreq` or the `input` letter
frequency is greater than `lettersInHand`'s frequency, return false. Otherwise,
return true. */
if (typeof(lettersInHandFreq[letter.toUpperCase()]) === 'undefined' ||

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since undefined is a falsy value in javascript, another way we could write typeof(lettersInHandFreq[letter.toUpperCase()]) === 'undefined' is !lettersInHandFreq[letter.toUpperCase()].

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be worth making a variable to hold the uppercased letter before the if-statement, so we only need to call letter.toUpperCase() once.

inputLetterFreq[letter.toUpperCase()] > lettersInHandFreq[letter
.toUpperCase()]) {
Comment on lines +76 to +77

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice splitting this if-statement across lines for readability!

return false;
}
}
return true;
};

export const scoreWord = (word) => {
// Implement this method for wave 3
const scoreChart = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice keeping the scoring and available letter objects inside the functions where they're used!

A: 1,
B: 3,
C: 3,
D: 2,
E: 1,
F: 4,
G: 2,
H: 4,
I: 1,
J: 8,
K: 5,
L: 1,
M: 3,
N: 1,
O: 1,
P: 3,
Q: 10,
R: 1,
S: 1,
T: 1,
U: 1,
V: 4,
W: 4,
X: 8,
Y: 4,
Z: 10
};

let score = 0;

for (const letter of word) {
if (letter.toUpperCase() in scoreChart) {
score += scoreChart[letter.toUpperCase()];
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat implementation of feedback from the python version!

if (word.length >= 7 && word.length <= 10) {
score += 8;
}
return score;
};

export const highestScoreFrom = (words) => {
// Implement this method for wave 1
};
// tests for this loop run eternally in vscode
/*
1) For loop through each word in `words`

2) An string that represents the word and a number representing the score is pushed to `word_scores`

3) Initalize a variable `max_score` where the first object's score is the max
value. Initialize an array called `ties` that hold

4) Loop through `word_scores` from the end to the beginnning with a step of -2.

5) If the `word_score[i]` is is greater than or equal to the `max_score`, reassign `max_score` to `word_scores[i]`.

6) Return an object. The first property has the key word, the value is the index position of `max_score` - 1. The second property has a the key of score and a value of `max_score`.
*/

// // words_scores can be like this = [{X: 8}, {XX: 16}, {XXX: 24}, {XXXX: 32}]
// // or maybe this = ['X', 8, 'XX', 16, 'XXX', 24, 'XXXX', 32]

const word_scores = [];

for (let i = 0; i < words.length; i++) {
// word_scores.push({[words[i]]: scoreWord(words[i])})
word_scores.push(words[i])
word_scores.push(scoreWord(words[i]))
}

let max_score = 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that we can break ties between words with the same score, we might also want to create a list variable that we fill with all the words with a score of max_score.


// something is up with my condition here
for (let i = word_scores.length; i < word_scores.length; i -= 2) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now i starts at word_scores.length, and our loop checks if i < word_scores.length to decide if we should leave the loop. Since we decrement i by 2 each iteration, i is never greater than word_scores.length, so we never leave the loop. Since the last index we want to hit is 1, if we change the condition statement to ensure we stop at 1, we'll leave the loop as expected.

Since javascript arrays also uses 0-based indexing, we would want to start i at word_scores.length - 1 since it would be the last index.

if (word_scores[i + 1] > max_score) {
max_score = word_scores[i + 1];
}
}

return {
word: word_scores.indexOf(max_score) - 1,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.indexOf(max_score) will return us the first word it finds in the list word_scores with the score max_score, even if by our tie breaking rules there might be a shorter string with the same score later in the list we would want to return.

score: max_score
};
};
5 changes: 3 additions & 2 deletions test/adagrams.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ describe("Adagrams", () => {
});

it("returns a score of 0 if given an empty input", () => {
throw "Complete test";
// throw "Complete test";
expectScores({'': 0})
});

it("adds an extra 8 points if word is 7 or more characters long", () => {
Expand All @@ -133,7 +134,7 @@ describe("Adagrams", () => {
});
});

describe.skip("highestScoreFrom", () => {
describe("highestScoreFrom", () => {
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") };
Expand Down