Implementing fizz buzz of higher order using maps in go lang? - dictionary

I am trying to implement the fizz buzz problem using maps in go lang. However, this code requires improvement in its working. It keeps on printing undesired and redundant results due to the for loop that iterates over the map. I tried a lot of solutions but failed. Is it feasible without using any help of a slice of keys?
package main
import "fmt"
func fizzbuzz(i int) {
myMap:= make(map[int]string)
myMap[3] = "fizz"
myMap[5] = "buzz"
myMap[15] = "fizzbuzz"
for k,v:= range myMap{
if i%k==0 {fmt.Printf("%v \n",v)
} else {fmt.Printf("%v \n",i)}
}
}
func main() {
for i:=1;i<10000;i++ {
fizzbuzz(i)
}
}

With a map
With your rule set, the entire for loop should be to decide if the i number is to be replaced with a word. But you emit a result in each iteration. At most one result should be emitted by the for. If i is not dividable by any of the keys, then i should be emitted.
Keys may be multiples of others (e.g. 15 = 3 * 5), and if the i number is dividable by such a key, we want to emit the word associated with the greatest key. So the for loop should not emit anything, because if you find a good key, there may be a greater one. So the loop should just find the greatest good key.
After the loop you can check if any good key was found, and if so, emit the word associated with it, else emit the number:
var rules = map[int]string{
3: "fizz",
5: "buzz",
15: "fizzbuzz",
}
func fizzbuzz(i int) {
max := -1
for k := range rules {
if i%k == 0 && k > max {
max = k
}
}
if max < 0 {
fmt.Println(i)
} else {
fmt.Println(rules[max])
}
}
func main() {
for i := 1; i < 100; i++ {
fizzbuzz(i)
}
}
Output (try it on the Go Playground):
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
17
fizz
19
buzz
fizz
...
With an ordered slice
You can get better performance if the rules are sorted by the keys descending, in which case you can check the keys in that order (greatest first), and then the first that qualifies will be the greatest. So you can emit the result immediately, and return.
If execution continues after the loop, we know no keys were good, we can emit the i number:
var rules = []struct {
n int
word string
}{
{15, "fizzbuzz"},
{5, "buzz"},
{3, "fizz"},
}
func fizzbuzz(i int) {
for _, rule := range rules {
if i%rule.n == 0 {
fmt.Println(rule.word)
return
}
}
fmt.Println(i)
}
Try this on the Go Playground.
General (excluding multiples from rules)
Although you started with a rule set where 15 = 3 * 5 was included in the rules, this should not be the case; you should only list 3 and 5, 15 should be implicit.
In this case, you have to check all the rules of course, because each good key should emit a word. And you have to remember if a good key was found, and only emit the i number otherwise.
This is how you can do it:
var rules = []struct {
n int
word string
}{
{3, "fizz"},
{5, "buzz"},
}
func fizzbuzz(i int) {
found := false
for _, rule := range rules {
if i%rule.n == 0 {
found = true
fmt.Print(rule.word)
}
}
if !found {
fmt.Print(i)
}
fmt.Println()
}
Try it on the Go Playground.
Note: in this solution you could also use a map instead of the slice; the reason why I used a slice is so that in case of multiple good keys the emitted words will always be in the same order (defined by increasing keys), as iteration order of keys in a map is not defined. For details, see Why can't Go iterate maps in insertion order?

As mentioned, the order of items in a map, is not deterministic in Go. Though here are some simple solutions:
func fizzbuzz(n int) {
for i := 1; i <= n; i++ {
switch {
case i%15 == 0:
println("fizzbuzz")
case i%5 == 0:
println(`buzz`)
case i%3 == 0:
println(`fizz`)
default:
println(i)
}
}
}
func fizzbuzzList(n int) []string {
var res []string
for i := 1; i <= n; i++ {
switch {
case i%15 == 0:
res = append(res, `fizzbuzz`)
case i%5 == 0:
res = append(res, `buzz`)
case i%3 == 0:
res = append(res, `fizz`)
default:
res = append(res, strconv.Itoa(i))
}
}
return res
}
func fizzbuzzLazy(n int) chan string {
var res = make(chan string)
go func() {
for i := 1; i <= n; i++ {
switch {
case i%15 == 0:
res <- `fizzbuzz`
case i%5 == 0:
res <- `buzz`
case i%3 == 0:
res <- `fizz`
default:
res <- strconv.Itoa(i)
}
}
close(res)
}()
return res
}
And usage:
fizzbuzz(20)
for _, v := range fizzbuzzList(20) {
println(v)
}
for v := range fizzbuzzLazy(20) {
println(v)
}

Related

How to find out if 'map[string][][]int' has a value

Given this code:
var a map[string][][]int
var aa map[string][][]int = map[string][][]int{"a": [][]int{{10, 10}, {20, 20}}}
var bb map[string][][]int = map[string][][]int{"b": [][]int{{30, 30}, {40, 40}}}
fmt.Println(aa) // >> map[a:[[10 10] [20 20]] b:[[30 30] [40 40]]]
how do I know if '[30, 30]' is in 'aa'?
I want to check, whether 'aa' has '[30 30]'.
You'll have to iterate over the contents of your map to check whether an element is contained in that map or not.
For example:
target := []int{30, 30}
for _, v := range myMap {
for _, sub := range v {
if len(sub) == len(target) && sub[0] == target[0] && sub[1] == target[1] {
fmt.Println("yeah")
}
}
}
With myMap as aa you'll get no output, and with myMap as bb you'll get "Yeah" printed.
If your inner-most slices get longer, you should do the check step as a loop as well instead of hard-coded like that.
Maps are only indexed by key. This means its cheap and easy (ideally constant time complexity) to find a or b, but its harder to look for a value (linear time complexity).
Therefore, it's a few for loops:
func find(searchFor [][]int, m map[string][][]int) bool {
for _, v := range m {
if sliceEq(v, searchFor) {
return true
}
}
return false
}
func sliceEq(a, b [][]int) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}

own len function with recursion in Go

I'm trying to build simple function to count elements in slice (like len) It must be simple (without additional libs) and with recursion. The problem is when i try to check is slice is empty (is nul).
package main
import "fmt"
func main() {
x := []int{1, 2, 3}
fmt.Println(len2(x))
}
func len2(s []int) int {
if s == nil {
return 0
}
return 1 + len2(s[1:])
}
the result it should be in this example '3'.
It's broken in if s == nil:
panic: runtime error: slice bounds out of range
It panics because you have no valid termination condition.
When your len2() is called with a non-nil empty slice, it attempts to slice it like s[1:], which will be a runtime panic.
Instead of checking for nil slice, check if the slice is empty by comparing its length to 0:
func len2(s []int) int {
if len(s) == 0 {
return 0
}
return 1 + len2(s[1:])
}
Try it on the Go Playground.
If you can't use the builtin len() function (which you already did in your solution), you may use the for ... range:
func len2(s []int) int {
size := 0
for i := range s {
size = i + 1
}
return size
}
Try this on the Go Playground.
And if it must be recursive, then for example:
func len2(s []int) int {
size := 0
for range s {
size = 1 + len2(s[1:])
break
}
return size
}
Try this on the Go Playground.
But know that these are awful solutions compared to using the builtin len().
The following is not a solution with better performance than len but an implementation that does not use any extra libraries and depends on recursion to find length
func len2(s []int) (count int) {
defer func() {
if r := recover(); r != nil {
count = 0
}
}()
return 1 + len2(s[1:])
}
Here is sample code
package main
import "fmt"
func main() {
var x []int = nil
var x1 = []int{1, 2, 3, 4}
var x2 = []int{}
var x3 = make([]int, 10, 20)
fmt.Println(len2(x))
fmt.Println(len2(x1))
fmt.Println(len2(x2))
fmt.Println(len2(x3))
}
func len2(s []int) (count int) {
defer func() {
if r := recover(); r != nil {
count = 0
}
}()
return 1 + len2(s[1:])
}
Checkout the same in playground
If you can leave without recursion here is a function that does not use len() and should be faster then re-slicing recursively.
func len2(s []int) (count int) {
for i := range s {
count = i + 1
}
}
If you do not want to use len() func, you can use cap()
func main() {
x := []int{1, 2, 3}
fmt.Println(len2(x))
}
func len2(s []int) int {
if cap(s) == 0 {
return 0
}
return 1 + len2(s[1:])
}
Try it again
Original Answer:
In order to check if an array (slice) is empty, you should use the function len()
if len(s) == 0 {
return 0
}
Try it

trouble using pointer in Golang

I am new to golang, here I am using BubleSort and InsertionSort and generating a rando slice for the functions. Can I use pointers some how to hand both functions the unsorted slice? because when I run the program the first function sorts the slice and the the second function uses that sorted slice. I know there are different ways to give both functions the unsorted slice, but I want to see how can I use pointers to do this. Thank you.
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
slice := generateSlice(4)
fmt.Println(BubleSort(slice))
fmt.Println(InsertionSort(slice))
}
func generateSlice(size int) []int {
slice := make([]int, size, size)
rand.Seed(time.Now().UnixNano())
for i := 0; i < size; i++ {
slice[i] = rand.Intn(10)
}
return slice
}
func BubleSort(slice []int) []int {
fmt.Println("unsorted Buble", slice)
for i := 1; i <= len(slice); {
for j := 0; j < len(slice)-i; {
if slice[j] > slice[j+1] {
slice[j], slice[j+1] = slice[j+1], slice[j]
}
j++
}
i++
}
return slice
}
func InsertionSort(slice []int) []int {
fmt.Println("unsorted Insertion", slice)
for i := 1; i <= len(slice)-1; {
// Check j and j-1 and swap the smaller number to left in each
itteartion to reach the first 2 elements of the slice
for j := i; j >= 1; {
if slice[j] < slice[j-1] {
slice[j], slice[j-1] = slice[j-1], slice[j]
}
j--
}
i++
}
return slice
}
Andy is correct
As an alternative, you can copy the slice before sorting it, as in here (on Play):
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
slice := generateSlice(4)
fmt.Println(BubleSort(copySlice(slice)))
fmt.Println(InsertionSort(copySlice(slice)))
}
func copySlice(src []int) []int {
dest := make([]int, len(src))
copy(dest, src)
return dest
}
func generateSlice(size int) []int {
slice := make([]int, size, size)
rand.Seed(time.Now().UnixNano())
for i := 0; i < size; i++ {
slice[i] = rand.Intn(10)
}
return slice
}
func BubleSort(slice []int) []int {
fmt.Println("unsorted Buble", slice)
for i := 1; i <= len(slice); {
for j := 0; j < len(slice)-i; {
if slice[j] > slice[j+1] {
slice[j], slice[j+1] = slice[j+1], slice[j]
}
j++
}
i++
}
return slice
}
func InsertionSort(slice []int) []int {
fmt.Println("unsorted Insertion", slice)
for i := 1; i <= len(slice)-1; {
// Check j and j-1 and swap the smaller number to left in each itteartion to reach the first 2 elements of the slice
for j := i; j >= 1; {
if slice[j] < slice[j-1] {
slice[j], slice[j-1] = slice[j-1], slice[j]
}
j--
}
i++
}
return slice
}
I am learning Go as well. I think the fact that you are using slice is what causing the unwanted behaviour (when I run the program the first function sorts the slice and the the second function uses that sorted slice). As explained here:
A slice does not store any data, it just describes a section of an underlying array.
Changing the elements of a slice modifies the corresponding elements of its underlying array.
Other slices that share the same underlying array will see those changes.
I don't think passing pointer will produce different results as slices point to the same array. What you can do is maybe receive an array instead of slice?
Hope it helps! :)

How to store recursively obtained combinations in a slice in GO?

Combinations can be printed using the following recursive code (inspired from Rosetta)
I thought it would be easy to store the intermediate results in an []int or the set of combination in an [][]int. But, because the function is recursive, it is not so easy than replacing the
fmt.Println(s)
by a
return s
with a minor modification of the function output for example. I also tried to feed a pointer like
p *[][]int
with the variable "s" inside the recursive function, but I failed :-/
I think it is a general problem with recursive functions so if you have some advises to solve this problem it will help me a lot !
Many thanks in advance ! ;)
package main
import (
"fmt"
)
func main() {
comb(5, 3)
}
func comb(n, m int) {
s := make([]int, m)
last := m - 1
var rc func(int, int)
rc = func(i, next int) {
for j := next; j < n; j++ {
s[i] = j
if i == last {
fmt.Println(s)
} else {
rc(i+1, j+1)
}
}
return
}
rc(0, 0)
}
Seems to me that s is being reused by each rc call so you just need to ensure that when storing s into an [][]int you store its copy, so as to not overwrite its contents during the next iteration.
To copy a slice you can use append like this:
scopy := append([]int{}, s...)
https://play.golang.org/p/lggy5JFL0Z
package main
import (
"fmt"
)
func main() {
out := comb(5, 3)
fmt.Println(out)
}
func comb(n, m int) (out [][]int) {
s := make([]int, m)
last := m - 1
var rc func(int, int)
rc = func(i, next int) {
for j := next; j < n; j++ {
s[i] = j
if i == last {
out = append(out, append([]int{}, s...))
} else {
rc(i+1, j+1)
}
}
return
}
rc(0, 0)
return out
}

Golang: How to create unknown (dynamic) Map length

I can create a "static" map via
type m map[int]map[int]map[int]bool
but the length of "keys" will be dynamic:
|---unknown len--|
m[1][2][3][4][2][0] = true
or
|---unk len--|
m[1][2][3][4] = true
How I can create this map in Go? Or any way exists?
Added: Hierarchical is IMPORTANT
Thanks in advance!
The map type:
A map is an unordered group of elements of one type, called the element type, indexed by a set of unique keys of another type, called the key type.
A map type must have a specific value type and a specific key type. What you want does not qualify for this: you want a map where the value is sometimes another map (of the same type), and sometimes it's a bool.
Your options:
1. With a wrapper value type
The idea here is to not use just a simple (bool) value type, but a wrapper which holds both of your potential values: both a map and the simple value (bool):
type Value struct {
Children MapType
V bool
}
type MapType map[int]*Value
var m MapType
This is basically what user3591723 suggested, so I won't detail it further.
2. With a tree
This is a variant of #1, but this way we clearly communicate it's a tree.
The cleanest way to implement your hierarchical structure would be to use a tree, where a node could look like this:
type KeyType int
type ValueType string
type Node struct {
Children map[KeyType]*Node
Value ValueType
}
This has the advantage that you may choose the value type (which is bool in your case, but you can change it to whatever type - I used string for presentation).
For easily build / manage your tree, we can add some methods to our Node type:
func (n *Node) Add(key KeyType, v ValueType) {
if n.Children == nil {
n.Children = map[KeyType]*Node{}
}
n.Children[key] = &Node{Value: v}
}
func (n *Node) Get(keys ...KeyType) *Node {
for _, key := range keys {
n = n.Children[key]
}
return n
}
func (n *Node) Set(v ValueType, keys ...KeyType) {
n = n.Get(keys...)
n.Value = v
}
And using it: 1. build a tree, 2. query some values, 3. change a value:
root := &Node{Value: "root"}
root.Add(0, "first")
root.Get(0).Add(9, "second")
root.Get(0, 9).Add(3, "third")
root.Get(0).Add(4, "fourth")
fmt.Println(root)
fmt.Println(root.Get(0, 9, 3))
fmt.Println(root.Get(0, 4))
root.Set("fourthMod", 0, 4)
fmt.Println(root.Get(0, 4))
Output (try it on the Go Playground):
&{map[0:0x104382f0] root}
&{map[] third}
&{map[] fourth}
&{map[] fourthMod}
3. With a recursive type definition
It may be surprising but it is possible to define a map type in Go which has unlimited or dynamic "depth", using a recursive definition:
type X map[int]X
It is what it says: it's a map with int keys, and values of the same type as the map itself.
The big downside of this recursive type is that it can't store any "useful" data in the value type. It can only store the "fact" whether a value is present which is identical to a bool-like information (bool type: true or false), which may be enough in rare cases, but not in most.
Let's see an example building a "tree":
var x X
x = map[int]X{}
x[0] = map[int]X{}
x[0][9] = map[int]X{}
x[0][9][3] = map[int]X{}
x[0][4] = map[int]X{}
fmt.Println(x)
Output:
map[0:map[9:map[3:map[]] 4:map[]]]
If we want to test if there is a "value" based on a series of keys, we have 2 options: either use the special v, ok := m[i] indexing (which reports if a value for the specified key exists), or test if the value is not nil, e.g. m[i] != nil.
Let's see some examples testing the above built map:
var ok bool
_, ok = x[0][9][3]
fmt.Println("x[0][9][3] exists:", ok, "; alternative way:", x[0][9][3] != nil)
_, ok = x[0][9][4]
fmt.Println("x[0][9][4] exists:", ok, "; alternative way:", x[0][9][4] != nil)
_, ok = x[0][4]
fmt.Println("x[0][4] exists:", ok, "; alternative way:", x[0][4] != nil)
_, ok = x[0][4][9][9][9]
fmt.Println("x[0][4][9][9][9] exists:", ok, "; alternative way:", x[0][4][9][9][9] != nil)
Output:
x[0][9][3] exists: true ; alternative way: true
x[0][9][4] exists: false ; alternative way: false
x[0][4] exists: true ; alternative way: true
x[0][4][9][9][9] exists: false ; alternative way: false
Try these on the Go Playground.
Note: Even though x[0][4] is the last "leaf", indexing further like x[0][4][9][9][9] will not cause a panic as a nil map can be indexed and yields the zero value of the value type (which is nil in case the value type is a map type).
Ok I had some fun playing with this a bit. Here is a much better implementation than what I did before:
type mymap map[int]*myentry
type myentry struct {
m mymap
b bool
}
func (mm mymap) get(idx ...int) *myentry {
if len(idx) == 0 {
return nil
}
entry, ok := mm[idx[0]]
if !ok {
return nil
} else if len(idx) == 1 {
return entry
}
for i := 1; i < len(idx); i++ {
if entry == nil || entry.m == nil {
return nil
}
entry = entry.m[idx[i]]
}
return entry
}
func (mm mymap) setbool(v bool, idx ...int) {
if len(idx) == 0 {
return
}
if mm[idx[0]] == nil {
mm[idx[0]] = &myentry{m: make(mymap), b: false}
} else if mm[idx[0]].m == nil {
mm[idx[0]].m = make(mymap)
}
if len(idx) == 1 {
mm[idx[0]].b = v
return
}
entry := mm[idx[0]]
for i := 1; i < len(idx); i++ {
if entry.m == nil {
entry.m = make(mymap)
entry.m[idx[i]] = &myentry{m: make(mymap), b: false}
} else if entry.m[idx[i]] == nil {
entry.m[idx[i]] = &myentry{m: make(mymap), b: false}
}
entry = entry.m[idx[i]]
}
entry.b = v
}
func (m mymap) getbool(idx ...int) bool {
if val := m.get(idx...); val != nil {
return val.b
}
return false
}
func (m mymap) getmap(idx ...int) mymap {
if val := m.get(idx...); val != nil {
return val.m
}
return nil
}
Playground link
Something like that ought to get you started
If you don't need the hierarchical map structure and just want to use keys with variable length one approach could be to simply use strings as keys and one single map.
m := make(map[string]bool)
k := fmt.Sprintf("%v_%v_%v", 1, 2, 3)
m[k] = true
fmt.Println(m[k])
You cannot do this as this sort of type is not representable in Go's type system.
You will have to redesign.
E.g. a type arbitrarilyKeyedMapwith a method lookup(vals ...int) bool.
Probably you'll need methods for setting and deletion too.

Resources