Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
80ccb92
Add Modular Arithmetic approach to RaindropConverter
habere-et-dispertire Jun 22, 2026
c5802d2
Refactor RaindropConverter default case
habere-et-dispertire Jun 23, 2026
28466a0
Refactor with suggestions
habere-et-dispertire Jun 24, 2026
f4aedf7
Create content.md for modular arithmetic approach
habere-et-dispertire Jun 24, 2026
92267d9
Add modular arithmetic conversion function
habere-et-dispertire Jun 24, 2026
565eaa2
Add modular arithmetic approach to config.json
habere-et-dispertire Jun 24, 2026
66846be
Fix link to Modular Arithmetic approach
habere-et-dispertire Jun 24, 2026
c5232dc
Move to modulus folder
habere-et-dispertire Jun 24, 2026
4478566
Move snippet.txt to modulus folder
habere-et-dispertire Jun 24, 2026
e321a48
Rename slug from 'modular-arithmetic' to 'modulus'
habere-et-dispertire Jun 25, 2026
c1ea104
Reduce to eight lines for configlet
habere-et-dispertire Jun 26, 2026
6e62e0b
Reduce snippet to concept
habere-et-dispertire Jun 26, 2026
227b412
Rename header from 'modular arithmetic' to 'modulus'
habere-et-dispertire Jun 26, 2026
1e4fdfd
Rename 'Modular Arithmetic' to 'Modulus' approach
habere-et-dispertire Jun 26, 2026
5478155
Rename 'Modular Arithmetic' to 'Modulus' in config.json
habere-et-dispertire Jun 26, 2026
f888ffc
Title case header from modulus to Modulus in config.json
habere-et-dispertire Jun 26, 2026
2e983e2
Change 'Modular Arithmetic' to 'Modulus' in introduction.md
habere-et-dispertire Jun 26, 2026
ba8cf8c
Clarify wording on co-prime factors in raindrops
habere-et-dispertire Jun 26, 2026
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
9 changes: 9 additions & 0 deletions exercises/practice/raindrops/.approaches/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@
"authors": [
"bobahop"
]
},
{
"uuid": "d16d4056-2434-44ff-aae6-2bd57eb53dd7",
"slug": "modulus",
"title": "Modulus",
"blurb": "Use modular arithmetic to generalize.",
"authors": [
"habere-et-dispertire"
]
}
]
}
27 changes: 27 additions & 0 deletions exercises/practice/raindrops/.approaches/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,32 @@ class RaindropConverter {

For more information, check the [`Map` approach][approach-map].

## Approach: `Modulus`

```java
import java.math.BigInteger;
import static java.math.BigInteger.valueOf;

class RaindropConverter {

String convert (int n) {
return switch ( valueOf(n).modPow( valueOf(12), valueOf(105) ).intValue() ) {
case 36 -> "Pling";
case 85 -> "Plang";
case 91 -> "Plong";
case 15 -> "PlingPlang";
case 21 -> "PlingPlong";
case 70 -> "PlangPlong";
case 0 -> "PlingPlangPlong";
default -> String.valueOf(n); // 1
};
}

}
```

For more information, check the [Modulus approach][approach-modulus].

## Which approach to use?

Benchmarking with the [Java Microbenchmark Harness][jmh] is currently outside the scope of this document,
Expand All @@ -64,4 +90,5 @@ and no other code would need to be added.
[remainder-operator]: https://www.geeksforgeeks.org/modulo-or-remainder-operator-in-java/
[approach-if-statements]: https://exercism.org/tracks/java/exercises/raindrops/approaches/if-statements
[approach-map]: https://exercism.org/tracks/java/exercises/raindrops/approaches/map
[approach-modulus]: https://exercism.org/tracks/java/exercises/raindrops/approaches/modulus
Comment thread
habere-et-dispertire marked this conversation as resolved.
[jmh]: https://github.com/openjdk/jmh
31 changes: 31 additions & 0 deletions exercises/practice/raindrops/.approaches/modulus/content.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Modulus

```java
import java.math.BigInteger;
import static java.math.BigInteger.valueOf;

class RaindropConverter {

String convert (int n) {
return switch ( valueOf(n).modPow( valueOf(12), valueOf(105) ).intValue() ) {
case 36 -> "Pling";
case 85 -> "Plang";
case 91 -> "Plong";
case 15 -> "PlingPlang";
case 21 -> "PlingPlong";
case 70 -> "PlangPlong";
case 0 -> "PlingPlangPlong";
default -> String.valueOf(n); // 1
};
}

}
```

We can generalize raindrops to any factors if they are [co-prime][co-prime].
In raindrops, the factors 3, 5 and 7 are co-prime (all sets of prime numbers are co-prime), so we can use [Euler's totient function][euler-totient] to calculate `n¹² mod 105`, giving us unique values for the various sounds.
The math behind how we find the right exponent and modulus is explained in an article on the related problem of [Fizz-Buzz][fizz-buzz].

[co-prime]: https://en.wikipedia.org/wiki/Coprime_integers
[euler-totient]: https://en.wikipedia.org/wiki/Euler's_totient_function
[fizz-buzz]: https://philcrissman.net/posts/eulers-fizzbuzz/
8 changes: 8 additions & 0 deletions exercises/practice/raindrops/.approaches/modulus/snippet.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
String convert (int n) {
return switch (BigInteger.valueOf(n).modPow(BigInteger.valueOf(12),BigInteger.valueOf(105)).intValue()) {
case 0 -> "PlingPlangPlong";
case 36 -> "Pling";
// other cases
default -> String.valueOf(n); // 1
};
}
Comment thread
habere-et-dispertire marked this conversation as resolved.