How to make a go program recursive - arrays

How could I make this go program recursive. I'm learning golang by writing a game number analyzer. I've been thinking and thinking on how to do this and can't come up with a working solution. Here is the link in the Google Playground. Any help would be greatly appreciated.
/*
File record.go
Author: Dan Huckson
Date: 20160120
Purpose: Number analyzer
*/
package main
import (
"fmt"
)
type Stats struct {
category map[string]Events
}
type Events struct {
event map[string]*Event
}
type Event struct {
value int64
}
func main() {
winners := [][]int{
{1, 2, 3, 4, 5, 6},
{2, 4, 6, 28, 26, 39},
{1, 4, 9, 10, 26, 39},
{1, 9, 19, 29, 26, 49},
{4, 5, 6, 28, 26, 49}}
keys := []string{"digits1", "digits2", "digits3", "digits4", "digits5", "digits6"}
stats := new(Stats)
stats.category = make(map[string]Events)
for _, key := range keys {
events, ok := stats.category[key]
if !ok {
events = *new(Events)
}
events.event = make(map[string]*Event)
stats.category[key] = events
}
fmt.Println()
for _, winner := range winners {
fmt.Println(winner)
stats.digits1("digits1", winner)
stats.digits2("digits2", winner)
stats.digits3("digits3", winner)
stats.digits4("digits4", winner)
stats.digits5("digits5", winner)
stats.digits6("digits6", winner)
}
}
func (stats *Stats) record(key string, balls string) {
event, ok := stats.category[key].event[balls]
if !ok {
event = new(Event)
stats.category[key].event[balls] = event
}
stats.category[key].event[balls].value += 1
word := ""
if len(balls) > 1 {
word = "Balls"
} else {
word = "Ball"
}
fmt.Printf("%s:%s\tCount:%d\n", word, balls_to_csv(balls), stats.category[key].event[balls].value)
}
func (stats *Stats) digits1(key string, winner []int) {
for i := 0; i < len(winner); i++ {
stats.record(key, string(winner[i]))
}
}
func (stats *Stats) digits2(key string, winner []int) {
for i := 0; i < len(winner)-1; i++ {
for j := i + 1; j < len(winner); j++ {
stats.record(key, string(winner[i])+string(winner[j]))
}
}
}
func (stats *Stats) digits3(key string, winner []int) {
for i := 0; i < len(winner)-2; i++ {
for j := i + 1; j < len(winner)-1; j++ {
for k := j + 1; k < len(winner); k++ {
stats.record(key, string(winner[i])+string(winner[j])+string(winner[k]))
}
}
}
}
func (stats *Stats) digits4(key string, winner []int) {
for i := 0; i < len(winner)-3; i++ {
for j := i + 1; j < len(winner)-2; j++ {
for k := j + 1; k < len(winner)-1; k++ {
for l := k + 1; l < len(winner); l++ {
stats.record(key, string(winner[i])+string(winner[j])+string(winner[k])+string(winner[l]))
}
}
}
}
}
func (stats *Stats) digits5(key string, winner []int) {
for i := 0; i < len(winner)-4; i++ {
for j := i + 1; j < len(winner)-3; j++ {
for k := j + 1; k < len(winner)-2; k++ {
for l := k + 1; l < len(winner)-1; l++ {
for m := l + 1; m < len(winner); m++ {
stats.record(key, string(winner[i])+string(winner[j])+string(winner[k])+string(winner[l])+string(winner[m]))
}
}
}
}
}
}
func (stats *Stats) digits6(key string, winner []int) {
for i := 0; i < len(winner)-5; i++ {
for j := i + 1; j < len(winner)-4; j++ {
for k := j + 1; k < len(winner)-3; k++ {
for l := k + 1; l < len(winner)-2; l++ {
for m := l + 1; m < len(winner)-1; m++ {
for n := m + 1; n < len(winner); n++ {
stats.record(key, string(winner[i])+string(winner[j])+string(winner[k])+string(winner[l])+string(winner[m])+string(winner[n]))
}
}
}
}
}
}
}
func balls_to_csv(key string) string {
s := ""
length := len(key)
for i := 0; i < length; i++ {
s += fmt.Sprintf("%d,", key[i])
}
return s[:len(s)-1]
}

As far as I can tell, you want to recursively find all the combinations of winning numbers. For example,
package main
import "fmt"
func combinations(n []int, c []int, ccc [][][]int) [][][]int {
if len(n) == 0 {
return ccc
}
if len(ccc) == 0 {
ccc = make([][][]int, len(n))
}
for i := range n {
cc := make([]int, len(c)+1)
copy(cc, c)
cc[len(cc)-1] = n[i]
ccc[len(cc)-1] = append(ccc[len(cc)-1], cc)
ccc = combinations(n[i+1:], cc, ccc)
}
return ccc
}
func main() {
n := []int{1, 2, 3, 4}
fmt.Println("winning numbers", n)
fmt.Println()
nw := 0
w := combinations(n, nil, nil)
fmt.Println("winning tickets:")
d := " digit : "
for i := range w {
fmt.Print(i+1, d)
d = " digits: "
for j := range w[i] {
nw++
fmt.Print(w[i][j], " ")
}
fmt.Println()
}
fmt.Println()
fmt.Println(nw, "winners")
}
Output:
winning numbers [1 2 3 4]
winning tickets:
1 digit : [1] [2] [3] [4]
2 digits: [1 2] [1 3] [1 4] [2 3] [2 4] [3 4]
3 digits: [1 2 3] [1 2 4] [1 3 4] [2 3 4]
4 digits: [1 2 3 4]
15 winners
Simplifying, you can see the recursion.
func combinations(n []int) {
if len(n) == 0 {
return
}
for i := range n {
combinations(n[i+1:])
}
return
}
The recursion terminates when len(n) == 0. In the for loop, i increases to len(n)-1, combinations(n[i+1:]) becomes combinations(n[len(n):]), and len(n[len(n):]) == 0, which will terminate the recursion.

Recursion is not a language specific concept. If you know what is recursion and if you know how to write a function in Go, then you can write a recursive function in Go.
This is a dummy recursive function in Go.
func f(n int) int {
if n < 0 {
return 0 // or something else
}
if n == 0 {
return 1
}
return n * f(n - 1)
}
This is a recursive function in Go, because,
It has a termination (base) condition(n <= 0)
f(n) depends on f(x) for all x < n.
It's written in Go.

Related

Add 2 condition for for loop

I am using to arrays which might be differnet length.
I want to compare elements.
So I need check smallest length of array store it in var & then have to use that var in for loop.
To avoid this I want to check this lenth in for loop
like
for i:=0; (i<len(arr1)&&(i<len(arr2)) ; i++{
if arr1[i] < arr2[i] {}
}
OR
for i:=0; true == (i<len(arr1)&&(i<len(arr2)) ; i++{
if arr1[i] < arr2[i] {}
}
you could precompute which slice is longer
package main
import (
"fmt"
)
func longest(l1 []int, l2 []int) int {
if len(l1) > len(l2) {
return len(l2)
}
return len(l1)
}
func main() {
a := []int{1, 2, 3, 46, 7, 8, 9, 12, 13, 99, 87, 34}
b := []int{3, 4, 5, 6, 7, 8}
maxlen := longest(a, b)
for i := 0; i < maxlen; i++ {
if a[i] > b[i] {
fmt.Printf("%d yes", i)
}
}
}
https://play.golang.org/p/SXUwKrQrEo2

How can I compare values in 2D array with values in 1D array in GoLang?

I need to compare 1D array's and 2D array's values and to return the result array which has similar values using Go:
func absolutePermutation(n int32, k int32) []int32 {
var position []int32
var i, j int32
var result []int32
for i = 1; i <= n; i++ {
position[i-1] = i
}
x := getPermutations(position)
resVal := permNum(n)
fmt.Println(x)
for i = 0; i < resVal; i++ {
for j = 0; j < 4; j++ {
fmt.Println(x[i][j])
**if int32(math.Abs(float64(position[(j*resVal)+i])-float64(x[i][j]))) == k** {
result[i] = x[i][j]
} else {
continue
}
}
}
return result
}
func getPermutations(elements []int32) [][]int32 {
permutations := [][]int32{}
if len(elements) == 1 {
permutations = [][]int32{elements}
return permutations
}
for i := range elements {
el := make([]int32, len(elements))
copy(el, elements)
for _, perm := range getPermutations(append(el[0:i], el[i+1:]...)) {
permutations = append(permutations, append([]int32{elements[i]}, perm...))
}
}
return permutations
}
func permNum (n int32) int32 {
if n == 0 {
return 1
}
return n * permNum(n-1)
}
I tried to create position (1D array into 2D array here.) but it didn't make sense.
As a newbie to GoLang, I get this error in this code which is written to get the permutation of a given number:
runtime error: index out of range [0] with length 0
I solved to some extent. you can refer to this.
func absolutePermutation(n int32, k int32) []int32 {
var buffer [1024 * 1024]int32
position := buffer[0:n]
result := make([]int32, n)
var i, j int32
for i = 1; i <= n; i++ {
position[i-1] = i
}
x := getPermutations(position)
for i = 0; i < permNum(n); i++ {
for j = 0; j < n; j++ {
if int32(math.Abs(float64(position[j])-float64(x[i][j]))) == k {
result[j] = x[i][j]
if j==n-1{
return result
}
}else{
break
}
}
}
result = nil
return result
}

How to compare each element of array to other elements?

I need to find pairs in array, i wanted to do it with comparing arr[i] with others starting from arr[i+1] so i won't check for same value twice, but i can't get that going.
Here's what i've tried
func findPairs(_ ar: [Int]) -> Int {
var pairs = 0
for i in 0..<ar.count {
var k = i + 1
for k in 0..<ar.count {
if ar[i] == ar[k] {
pairs += 1
}
}
}
return pairs/2
}
Upd
to clarify, in the example i have, it was given as in array [1,2,3,1,2,3,4,5,1] we have 3 pairs [1,1] [2,2] [3,3]
You probably need to use i + 1 as the starting index in your inner loop, like that:
func findPairs(_ ar: [Int]) -> Int {
var pairs = 0
for i in 0..<ar.count {
let m = i + 1
for k in m..<ar.count {
if ar[i] == ar[k] {
pairs += 1
}
}
}
return pairs
}
Also, you can use another array to store the indexes of the pairs so that you do not use the same element for another pair:
func findPairs(_ ar: [Int]) -> Int {
var pairs = 0
var pairIndexes = [Int]()
for i in 0..<ar.count where !pairIndexes.contains(i) {
let m = i + 1
for k in m..<ar.count where !pairIndexes.contains(k) {
if ar[i] == ar[k] {
pairs += 1
pairIndexes.append(contentsOf: [i, k])
break
}
}
}
return pairs
}
The functional approach would be to get the total number of occurrences of the elements and sum half of it:
func findPairs(_ ar: [Int]) -> Int {
ar.reduce(into: [Int:Int]()) { $0[$1, default: 0] += 1 }.values.reduce(0) { $0 + $1/2 }
}
findPairs([1,2,3,1,2,3,4,5,1]) // 3
findPairs([4, 4, 4, 4, 4]) // 2
Or extending collection constraining the elements to hashable:
extension Collection where Element: Hashable {
var numberOfPairs: Int {
reduce(into: [Element:Int]()) { $0[$1, default: 0] += 1 }.values.reduce(0) { $0 + $1/2 }
}
}
[1,2,3,1,2,3,4,5,1].numberOfPairs // 3
[4, 4, 4, 4, 4].numberOfPairs // 2
I think you only need to find the number of pairs in the array.
So the following can work for you:
func findPairs(_ ar: [Int]) -> Int {
var pairs = 0
for i in 0..<ar.count {
for k in (i+1)..<ar.count {
if ar[i] == ar[k] {
pairs += 1
break
}
}
}
return pairs
}

i get alway an exception INDEX OUT OF RANGE at mat[i][j] = matrix[i+1][j+1]

Why am I getting index out of range in mat[i][j] = matrix[i+1][j+1]?
On the functions below I'm trying to count the determiner of a matrix.
Function eraze is to erase one line and one column so when I am filling the new matrix (array). Exception shows 'index out of range'.
func det2(matrix :[[Int]] ) -> Int {
var p : Int
p = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
return p
}
func det(matrix :[[Int]] , fo : Int ) -> Int {
var p2 : Int = 0
if (fo == 2) {
p2 = det2(matrix: matrix)
} else {
for j in 0..<fo {
p2 = matrix[j][0] * det(matrix: eraze(matrix: matrix, nb: j, dim: fo), fo: fo-1)
}
}
return p2
}
func eraze(matrix : [[Int]] , nb: Int , dim : Int) -> [[Int]] {
var mat = [[Int]]()
for i in 0..<dim-1 {
for j in 0..<dim-1 {
if (i == nb ) || (i>nb) {
mat[i][j] = matrix[i+1][j+1]
} else if (i<nb) {
mat[i][j] = matrix[i][j+1]
}
}
}
return mat
}
Your first issue is that in eraze(), you aren't initializing mat. In Swift you can't index into an empty array.
Replace:
var mat = [[Int]]()
with:
var mat = [[Int]](repeating: Array(repeating: 0, count: dim - 1), count: dim - 1)
With that change, your code no longer crashes, but it produces incorrect results.
You forgot to sum up the values of the expansion and when you do that you need to alternate the sign of the values:
func det(matrix :[[Int]] , fo : Int ) -> Int {
func sign(_ n: Int) -> Int {
return n % 2 == 0 ? 1 : -1
}
var p2 : Int = 0
if (fo == 2) {
p2 = det2(matrix: matrix)
} else {
for j in 0..<fo {
p2 += (sign(j) * matrix[j][0] * det(matrix: eraze(matrix: matrix, nb: j, dim: fo), fo: fo-1))
}
}
return p2
}
Test
det(matrix: [[1, 4, 7, 3, -6], [2, 5, 8, 4, -3], [3, 6, 10, -5, 14], [1, -2, 3, 4, 5], [6, -5, 4, -3, 2]], fo: 5)
13090
which agrees with Wolfram Alpha

Insertion sort using Go

I'm having difficulty creating a random value insert in Go, I need to do 10 tests with 1000 numbers, then 10 tests with 5000 numbers, then 10 tests with 10000 numbers, then 10 tests with 15000 ... up to 50000
I made a code with function and another code without function and the 2 are wrong
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
var vetor [50000]int
for k := 1; k <= 10; {
k := (5 ^ k) * 1000
for i := 1000; i < 50000; {
vetor[i] = rand.Intn(1000)
fmt.Print(vetor[i], ",")
}
start := time.Now()
n := len(vetor)
if n < 2 {
return
}
for i := 1; i < n; i++ {
for j := i - 1; j >= 0; j-- {
if (vetor)[j] > (vetor)[j+1] {
(vetor)[j], (vetor)[j+1] = (vetor)[j+1], (vetor)[j]
} else {
break
}
}
}
t := time.Now()
decorrido := t.Sub(start)
}
}
package main
import (
"fmt"
"math/rand"
"time"
)
func insertion(array *[]int) {
n := len(*array)
if n < 2 {
return
}
for i := 1; i < n; i++ {
for j := i - 1; j >= 0; j-- {
if (*array)[j] > (*array)[j+1] {
(*array)[j], (*array)[j+1] = (*array)[j+1], (*array)[j]
} else {
break
}
}
}
}
func main() {
var vetor [50000]int
for k := 1; k <= 10; {
k := (5 ^ k) * 1000
for i := 1000; i < 50000; {
vetor[i] = rand.Intn(1000)
fmt.Print(vetor[i], ",")
}
start := time.Now()
insertion(&vetor)
t := time.Now()
decorrido := t.Sub(start)
}
}
I also need to calculate the run time for all the tests and take the averages out of all 10 results

Resources