[48in24 Exercise] [01-30] Raindrops

This issue is a discussion for contributors to collaborate in getting ready to be featured in 48in24. Please refer to this forum topic for more info.

We will be featuring Raindrops from Jan 30 onwards and will be featured in:

  • Ruby
  • R
  • Common Lisp

Staff jobs

These are things for Erik/Jeremy to do:

  • ☐ Check/update exercise in Problem Specifications
  • ☐ Create + schedule video

Community jobs

For each track:

  • Implement Raindrops
  • Add approaches (and an approaches introduction!) for each idiomatic or interesting/educational approach.
  • Add video walkthroughs (record yourself solving and digging deeper into the exercise).
  • Highlight up to 16 different featured exercises (coming soon)

Existing Approaches

You can use these as the basis for approaches on your own tracks. Feel free to copy/paste/reuse/rewrite/etc as you see fit! Maybe ask ChatGPT to translate to your programming language.

Track Statuses

You can see an overview of which tracks have implemented the exercise at the #48in24 implementation status page.

I’ll work on approaches for Racket and Vim script.


Python’s is in process. :smile:


I’ll pick up the approaches for Elixir and Clojure tracks.

1 Like

Still in draft mode but quite close to finish.
Two of the approaches are very similar.
Appreciate any incoming feedback!

I’ve reviewed!

If anyone has any interesting solutions to raindrops that might be nice to feature in the video: let me know!

mhatayama's solution for Raindrops in Kotlin on Exercism shows iterating over a collection of factor/sound rules succinctly.

1 Like

IsaacG’s solution for Raindrops in Bash on Exercism shows the most concise and idiomatic solution


This can be solved in bash with an array and loop, too. I half expected to see that when opening my solution :smile:

1 Like

I’m still looking for some more outlandish/uncommon solutions :)

Not exactly outlandish but I’ve seen people put only the vowel in a map and loop over that map then build the sound using Pl{vowel}ng

Yes those are great! I have one of those solutions :)

A fun Tcl solution, making the variable names do double duty as the strings to concatenate:

proc raindrops {number} {
    set Pling 3
    set Plang 5
    set Plong 7
    set drops ""
    foreach var [info vars P*] {
        if {$number % [set $var] == 0} {
            append drops $var
    expr {$drops eq "" ? $number : $drops}

The info command has several subcommands. It’s one of the main introspection commands in Tcl.

The set command with two arguments assigns the variable name with the given value. The set command with only one argument returns the value of that variable name. In perl for example, you can do “double-dereferencing” ($$var) to get the value, but Tcl doesn’t do that (without using eval)

I saved this as https://exercism.org/tracks/tcl/exercises/raindrops/solutions/glennj. There’s a bash solution that does something like this, but my search-fu could not find it


Fun fact: when Tcl was being developed, using $varname to dereference variables was considered “syntactic sugar” because [set varname] existed.

1 Like

The shortest solution in J i could produce:

raindrop =: ;@( ( ('Pl' , 'ng' ,~ ] ) &.> 'aio' ) #~ [: }. [: 4&q: 105&+.)^:(1 ~: 105&+.)


NB. 1 ~: 105&+.                 -> GCD(105, arg) != 1
NB. ^:                          -> Returns the argument if the condition is false, otherwise it continues the execution
NB. [: }. [: 4&q: 105&+.        -> Returns the exponents of the factors 3, 5 and 7
NB.                                ex:  105 = 2^0 × 3^1 × 5^1 × 7^1 × 11^0 × ... => 1 1 1 
NB.                                ex2.: 21 = 2^0 × 3^1 × 5^0 × 7^1 × ... => 1 0 1
NB. #~                          -> `#` Aplies a bit mask       (arg1: <0|1>[],  arg2 'a[])
NB.                                `~` is the C combinator     (arg1 # arg2 <==> arg2 #~ arg1)
NB. ('Pl','ng',~])&.> 'aio'     -> Creates the array 'Plang Pling Plong' 
NB. ;                           -> Unboxes the results to display
1 Like
def convert(number):
    factors = {
        3 * 5 * 7: "PlingPlangPlong",
        5 * 7: "PlangPlong", 3 * 7: "PlingPlong", 3 * 5: "PlingPlang",
        7: "Plong", 5: "Plang", 3: "Pling"
    return next((sound for factor, sound in factors.items() if not number % factor), str(number))
def convert(number):
    return (f"{'' if number % 3 else 'Pling'}"
            f"{'' if number % 5 else 'Plang'}"
            f"{'' if number % 7 else 'Plong'}") or str(number)

and this one is quite wild, considering how brief other solutions can be:

def convert(number):
    phrase ='PlingPlangPlong'
    factor_array =  [(number % factor) == 0 for factor in (3,5,7)]
    match factor_array:
        case [True, True, True]:
            return phrase
        case [True, True, False]:
            return phrase[:10]
        case [True, False, True]:
            return phrase[:5] + phrase[10:]
        case [False, True, True]:
            return phrase[5:]
        case [True, False, False]:
            return phrase[:5]
        case [False, True, False]:
            return phrase[5:10]
        case [False, False, True]:
            return phrase[10:]
        case _:
            return str(number)
def convert(number):
    return (f"{'' if number % 3 else 'Pling'}"
            f"{'' if number % 5 else 'Plang'}"
            f"{'' if number % 7 else 'Plong'}") or str(number)

I both like and dislike this very much.

1 Like

PR for adding the exercise for the LFE track: Add Raindrops practice exercise by kahgoh · Pull Request #184 · exercism/lfe · GitHub