# Tom Dalling - FizzBuzz In Too Much Detail - My Take - In Go

Click to see the full article. This is my take, in Go.

## Goal

``````1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
``````

## Easy

``````package main

import "fmt"

func main() {
for i := 1; i <= 15; i++ {
if (i % 3 == 0 && i % 5 == 0) {
fmt.Println("FizzBuzz")
} else if (i % 3 == 0) {
fmt.Println("Fizz")
} else if (i % 5 == 0) {
fmt.Println("Buzz")
} else {
fmt.Println(i);
}
}
}
``````

## Less duplication

``````func main() {
for i := 1; i <= 15; i++ {
res := ""
if (i % 3 == 0) {
res += "Fizz"
}
if (i % 5 == 0) {
res += "Buzz"
}
if (res == "") {
res = fmt.Sprint(i);
}
fmt.Println(res)
}
}
``````

Avoid duplicating `3, 5, Fizz, Buzz, Println`.

## Parameterized with numbers and strings

``````func run(max int, triggers map[int]string) []string {
all := []string{}
for i := 1; i <= max; i++ {
res := ""
for number, word := range triggers {
if (i % number == 0) {
res += word
}
}
if (res == "") {
res = fmt.Sprint(i);
}
all = append(all, res)
}
return all
}

func main() {
all := run(15, map[int]string{
3: "Fizz",
5: "Buzz",
})
for _, word := range all {
fmt.Println(word)
}
}
``````

## Parameterized with functions

``````type Trigger func(res *string, i int)

func run(max int, triggers []Trigger) []string {
all := []string{}
for i := 1; i <= max; i++ {
res := ""
for _, trigger := range triggers {
trigger(&res, i)
}
all = append(all, res)
}
return all
}

func main() {
all := run(15, []Trigger{
func(res *string, i int) {
if (i % 3 == 0) {
*res += "Fizz"
}
},
func(res *string, i int) {
if (i % 5 == 0) {
*res += "Buzz"
}
},
func(res *string, i int) {
if (*res == "") {
*res = fmt.Sprint(i)
}
},
})
for _, word := range all {
fmt.Println(word)
}
}
``````

## Function that returns a function

``````type Trigger func(res *string, i int)

func run(max int, triggers []Trigger) []string {
all := []string{}
for i := 1; i <= max; i++ {
res := ""
for _, trigger := range triggers {
trigger(&res, i)
}
all = append(all, res)
}
return all
}

func create(number int, word string) Trigger {
return func(res *string, i int) {
if (i % number == 0) {
*res += word
}
}
}

func main() {
all := run(15, []Trigger{
create(3, "Fizz"),
create(5, "Buzz"),
func(res *string, i int) {
if (*res == "") {
*res = fmt.Sprint(i)
}
},
})
for _, word := range all {
fmt.Println(word)
}
}
``````

Avoid duplicating the `Trigger` creation.

## Channel

``````type Trigger func(res *string, i int)

func run(max int, all chan string, triggers []Trigger) {
for i := 1; i <= max; i++ {
res := ""
for _, trigger := range triggers {
trigger(&res, i)
}
all <- res
}
close(all)
}

func create(number int, word string) Trigger {
return func(res *string, i int) {
if (i % number == 0) {
*res += word
}
}
}

func main() {
all := make(chan string)
go run(15, all, []Trigger{
create(3, "Fizz"),
create(5, "Buzz"),
func(res *string, i int) {
if (*res == "") {
*res = fmt.Sprint(i)
}
},
})
for word := range all {
fmt.Println(word)
}
}
``````