Skip to content

Instantly share code, notes, and snippets.

@tendstofortytwo
Created June 27, 2025 17:40
Show Gist options
  • Save tendstofortytwo/7e811fc28c16043c33185d519a8f8e63 to your computer and use it in GitHub Desktop.
Save tendstofortytwo/7e811fc28c16043c33185d519a8f8e63 to your computer and use it in GitHub Desktop.
fizzbuzz florper
package main
import (
"fmt"
"io"
"log"
"os"
"strings"
"unicode"
)
// A Florper[T] takes a value of type T, and maybe writes it to the io.Writer
// based on a well-defined condition. It returns whether it printed the value.
type Florper[T any] interface {
Florped(T, io.Writer) (bool, error)
}
// A FizzBuzzer buzzes fizzes based on the provided list of Florpers.
type FizzBuzzer[T any] struct {
Florpers []Florper[T]
Writer io.Writer
}
func (fb *FizzBuzzer[T]) Florp(things []T) error {
for _, t := range things {
florped := false
for _, f := range fb.Florpers {
florpedThisTime, err := f.Florped(t, fb.Writer)
if err != nil {
return err
}
florped = florped || florpedThisTime
}
if !florped {
_, err := fb.Writer.Write([]byte(fmt.Sprint(t)))
if err != nil {
return err
}
}
_, err := fb.Writer.Write([]byte("\n"))
if err != nil {
return err
}
}
return nil
}
// Modder implements Florper[int]. It florps if the provided int is divisible
// by Base, writing Word to the destination.
type Modder struct {
Base int
Word string
}
func (m *Modder) Florped(v int, dst io.Writer) (bool, error) {
if v%m.Base == 0 {
_, err := dst.Write([]byte(m.Word))
return true, err
}
return false, nil
}
// Lowerer implements Florper[string]. It florps if the provided string is all
// lowercase, writing its uppercase version to the destination.
type Lowerer struct{}
func (Lowerer) Florped(v string, dst io.Writer) (bool, error) {
for _, r := range v {
if unicode.IsLetter(r) && !unicode.IsLower(r) {
return false, nil
}
}
_, err := dst.Write([]byte(strings.ToUpper(v)))
return true, err
}
// SpacerOuter implements Florper[string]. It florps if the provided string contains
// a whitespace character, writing a version of the string with all the whitespace
// tripled.
type SpacerOuter struct{}
func (SpacerOuter) Florped(v string, dst io.Writer) (ok bool, err error) {
for _, r := range v {
if unicode.IsSpace(r) {
ok = true
break
}
}
if !ok {
return
}
for _, r := range v {
if unicode.IsSpace(r) {
_, err = dst.Write([]byte(fmt.Sprintf("%c%c%c", r, r, r)))
if err != nil {
return
}
}
_, err = dst.Write([]byte(fmt.Sprintf("%c", r)))
if err != nil {
return
}
}
return
}
func main() {
numbers := []int{}
for i := 1; i <= 20; i++ {
numbers = append(numbers, i)
}
fb1 := &FizzBuzzer[int]{
Florpers: []Florper[int]{
&Modder{Base: 3, Word: "Fizz"},
&Modder{Base: 5, Word: "Buzz"},
},
Writer: os.Stdout,
}
err := fb1.Florp(numbers)
if err != nil {
log.Fatalf("fb1 exited with err: %v", err)
}
strings := []string{"hello", "World", "HOW aRe", "you", "ON", "this", "Lovely dAy"}
fb2 := &FizzBuzzer[string]{
Florpers: []Florper[string]{
&Lowerer{},
&SpacerOuter{},
},
Writer: os.Stderr,
}
err = fb2.Florp(strings)
if err != nil {
log.Fatalf("fb2 exited with err: %v", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment