Skip to content

Commit

Permalink
add mentoring notes for go/pig-latin
Browse files Browse the repository at this point in the history
  • Loading branch information
bernot-dev committed Jan 10, 2024
1 parent 8316a43 commit c21f520
Showing 1 changed file with 72 additions and 0 deletions.
72 changes: 72 additions & 0 deletions tracks/go/exercises/pig-latin/mentoring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Pig Latin

### Reasonable solutions:

There is a (somewhat) reasonable solution using regular expressions, however most students are likely to use a combination of `strings` funtions or string slicing to solve this problem.

Solutions vary considerably, but most reasonable solutions should demonstrate these three insights:

1. Decoupled logic to break down a sentence into words and reform the Pig Latin sentence.

```
func Sentence(sentence string) string {
words := strings.Fields(sentence)
pigWords := make([]string, 0, len(words))
for _, w := range words {
pigWords = append(pigWords, pigWord(w))
}
return strings.Join(pigWords, " ")
}
```

2. Identify that some number of consonants (according to the rules) will be added moved to the end of the word and "ay" will be added to the end of the word.

```
func pigWord(word string) string {
consonants := consonantCount(word)
return fmt.Sprintf("%s%say", word[consonants:], word[:consonants])
}
```

3. Identify how many letters count as consonants without overly convoluted logic.

```
func consonantCount(word string) int {
if strings.HasPrefix(word, "xr") || strings.HasPrefix(word, "yt") {
return 0
}
for i, r := range word {
switch r {
case 'a', 'e', 'i', 'o':
return i
case 'u':
if i > 0 && word[i-1] == 'q' {
// When a 'qu' is together, the u is also moved to the end of the word
return i + 1
}
return i
case 'y':
if i == 0 {
// Leading y is not considered a vowel
continue
}
return i
}
}
return 0
}
```

It is possible to combine parts 2 and 3, but this often leads to less readable code that repeats parts of the logic to form the pig latin word.

### Common suggestions:
* Avoid complex, deeply nested logic.
* Are all of the conditions treated as special cases in code actually special cases? For instance, does a leading vowel need to be treated differently than a first vowel in the middle of the word?
* Prefer switch/case to long if/else chains.
* Add explanatory comments when the intent of the code might not be clear to the reader.
* `gofmt` ensures consistent formatting, and is standard across most of the Go community.

### Talking points
* `rune` vs `byte` and why iterating over a string with `range` returns runes: [Strings, bytes, runes and characters in Go](https://blog.golang.org/strings)
* The test cases do not include uppercase letters. How would the student's solution have to change to handle uppercase letters?
* `fmt.Sprintf` and `strings.Builder` are more common than using the `+` operator to concatenate strings.

0 comments on commit c21f520

Please sign in to comment.