Change 2D slice in-place - go

I am implementing a matrix-matrix multiplication algorithm in Go and I cannot reason how to change the output matrix in-place. I have tried changing the input to a pointer but 2D slices cannot be pointers?
package main
import (
"fmt"
"strconv"
"math/rand"
"os"
"time"
)
func main() {
L := len(os.Args)
m, n, p, q, err := mapVars(L, os.Args)
if err != 0 {
fmt.Fprintf(os.Stderr, "error: Incorrect command line arguments.\n")
os.Exit(1)
}
fmt.Println("The product array has dimensions.")
fmt.Printf("\tC is %dx%d\n", m, q)
fmt.Println("\nPopulating matrix A.")
A, _ := createMat(m, n)
fmt.Println("Matrix A.")
printMat(m, A)
fmt.Println("\nPopulating matrix B.")
B, _ := createMat(p, q)
fmt.Println("Matrix B.")
printMat(p, B)
fmt.Println("\nPerforming row-wise matrix-matrix multiplication AB.")
startRow := time.Now()
C := rowMultMat(m, n, q, A, B)
dtRow := time.Since(startRow)
fmt.Printf("Time elapsed: %v\n", dtRow)
fmt.Println("Matrix C.")
printMat(q, C)
}
func mapVars(l int, args []string) (m int, n int, p int, q int, err int) {
if l == 2 {
m, _ := strconv.Atoi(args[1])
n, _ := strconv.Atoi(args[1])
p, _ := strconv.Atoi(args[1])
q, _ := strconv.Atoi(args[1])
fmt.Printf("Creating two arrays, A, B, with square dimensions.\n")
fmt.Printf("\tA is %dx%d\n\tB is %dx%d\n", m, n, p, q)
return m, n, p, q, 0
} else if (l == 5 || n != p) {
m, _ := strconv.Atoi(args[1])
n, _ := strconv.Atoi(args[2])
p, _ := strconv.Atoi(args[3])
q, _ := strconv.Atoi(args[4])
fmt.Println("Creating two arrays, A, B, with dimensions.")
fmt.Printf("\tA is %dx%d\n\tB is %dx%d\n", m, n, p, q)
return m, n, p, q, 0
} else {
fmt.Println("Incorrect command line arguments.\n")
return 0, 0, 0, 0, 1
}
}
func initMat(m int, n int) (M [][]float64, rows []float64) {
M = make([][]float64, m)
rows = make([]float64, n*m)
for i := 0; i < m; i++ {
M[i] = rows[i*n : (i+1)*n]
}
return M, rows
}
func createMat(m int, n int) (M [][]float64, rows []float64) {
M = make([][]float64, m)
rows = make([]float64, n*m)
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
rows[i*n + j] = float64(rand.Int63()%10)
}
M[i] = rows[i*n : (i+1)*n]
}
return M, rows
}
func printMat(row int, M [][]float64) {
for i := 0; i < row; i++ {
fmt.Printf("%v\n", M[i])
}
}
func rowMultMat(m int, n int, q int, A [][]float64, B [][]float64) (C [][]float64) {
C, _ = initMat(m, q)
var total float64 = 0.0
for i := 0; i < m; i++ {
for j := 0; j < q; j++ {
for k := 0; k < n; k++ {
total += A[i][k] * (B[k][j])
}
C[i][j] = total
total = 0
}
}
return C
}
Currently I am initializing the matrix inside rowMultMat because I am unable to pass C as a pointer to a 2D slice. For example, run main.go 2 3 3 2 will multiply a 2x3 with 3x2 to yield 2x2.

A slice is already a reference value. If you pass a slice into a function, the function can modify its contents (*) and the modifications will be visible to the caller once it returns.
Alternatively, returning a new slice is also efficient - because again, slices are just references and don't take up much memory.
(*) By contents here I mean the contents of the underlying array the slice points to. Some attributes like the slice's length cannot be changed in this way; if your function needs to make the slice longer, for example, you'll have to pass in a pointer to a slice.

Related

Heapsort implementation in Go

I'm trying to implement code from Sedgewick's Algorithms textbook. The idea is to implement heapsort with the root of the heap stored in position 1 in the array.
Given the input S O R T E X A M P L E I expect a sorted output of A E E L M O P R S T X.
I'm having a bit of trouble implementing this, even when directly trying to translate the referenced Java code. This is what I have so far, which returns the following output:
package main
import (
"bufio"
"fmt"
"os"
"reflect"
"strings"
)
type Heap struct {
PQ []interface{}
}
func (h *Heap) Sort(pq []interface{}) {
n := len(pq)
for k := n / 2; k >= 1; k-- {
Sink(pq, k, n)
}
for n > 1 {
Exchange(pq, 1, n)
n = n - 1
Sink(pq, 1, n)
}
}
func Sink(pq []interface{}, k, n int) {
fmt.Println(k, n, pq)
for 2*k <= n {
j := 2 * k
if j < n && Less(pq, j, j+1) {
j = j + 1
}
Exchange(pq, k, j)
k = j
}
}
func Exchange(pq []interface{}, j, k int) {
curr := pq[j-1]
pq[j-1] = pq[k-1]
pq[k-1] = curr
}
func Less(pq []interface{}, j, k int) bool {
x, y := pq[j-1], pq[k-1]
if reflect.TypeOf(x) != reflect.TypeOf(y) {
fmt.Println("mismatched inputs", x, y)
panic("mismatched inputs")
}
switch x.(type) {
case int:
a, b := x.(int), y.(int)
if a > b {
return false
}
case float32:
a, b := x.(int), y.(int)
if a > b {
return false
}
case float64:
a, b := x.(int), y.(int)
if a > b {
return false
}
case string:
a, b := x.(string), y.(string)
if a > b {
return false
}
default:
panic("unhandled types, please add case.")
}
return true
}
func main() {
a := readStdin()
var h *Heap = new(Heap)
h.PQ = a
h.Sort(h.PQ)
fmt.Println(h.PQ)
}
func readStdin() []interface{} {
scanner := bufio.NewScanner(os.Stdin)
var items []interface{}
for scanner.Scan() {
item := scanner.Text()
tmp := strings.SplitAfter(item, " ")
items = make([]interface{}, len(tmp)+1)
for i, item := range tmp {
items[i+1] = item
}
}
if err := scanner.Err(); err != nil {
panic(err)
}
return items
}
mismatched inputs E <nil>
panic: mismatched inputs
which panics as expected because of the comparison between nil value at index 0 and the currents slice value from 1..n. Perhaps I'm looking at this problem a bit too closely, or more than likely, I am missing a key point in the heapsort implementation altogether. Thoughts?
The standard library contains a heap package that you can use to directly implement this.
Even if you want to re-implement it yourself, the idea of using an interface to access the underlying slice is a good one -- allowing you to focus on the abstract heap operations without the mess of dealing with various types.
Here's a complete working example of heapsort, running on a slice of runes. Note that *runeSlice type implements heap.Interface by defining the three methods of sort.Interface: Len, Less, Swap, and the additional two methods from heap.Interface: Push and Pop.
package main
import (
"container/heap"
"fmt"
)
type runeSlice []rune
func (r runeSlice) Len() int { return len(r) }
func (r runeSlice) Less(i, j int) bool { return r[i] > r[j] }
func (r runeSlice) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
func (r *runeSlice) Push(x interface{}) {
*r = append(*r, x.(rune))
}
func (r *runeSlice) Pop() interface{} {
x := (*r)[len(*r)-1]
*r = (*r)[:len(*r)-1]
return x
}
func main() {
a := []rune("SORTEXAMPLE")
h := runeSlice(a)
heap.Init(&h)
for i := len(a) - 1; i >= 0; i-- {
a[0], a[i] = a[i], a[0]
h = h[:i]
heap.Fix(&h, 0)
}
fmt.Println(string(a))
}

Julia set image rendering ruined by concurrency

I have the following code that I am to change into a concurrent program.
// Stefan Nilsson 2013-02-27
// This program creates pictures of Julia sets (en.wikipedia.org/wiki/Julia_set).
package main
import (
"image"
"image/color"
"image/png"
"log"
"math/cmplx"
"os"
"strconv"
)
type ComplexFunc func(complex128) complex128
var Funcs []ComplexFunc = []ComplexFunc{
func(z complex128) complex128 { return z*z - 0.61803398875 },
func(z complex128) complex128 { return z*z + complex(0, 1) },
}
func main() {
for n, fn := range Funcs {
err := CreatePng("picture-"+strconv.Itoa(n)+".png", fn, 1024)
if err != nil {
log.Fatal(err)
}
}
}
// CreatePng creates a PNG picture file with a Julia image of size n x n.
func CreatePng(filename string, f ComplexFunc, n int) (err error) {
file, err := os.Create(filename)
if err != nil {
return
}
defer file.Close()
err = png.Encode(file, Julia(f, n))
return
}
// Julia returns an image of size n x n of the Julia set for f.
func Julia(f ComplexFunc, n int) image.Image {
bounds := image.Rect(-n/2, -n/2, n/2, n/2)
img := image.NewRGBA(bounds)
s := float64(n / 4)
for i := bounds.Min.X; i < bounds.Max.X; i++ {
for j := bounds.Min.Y; j < bounds.Max.Y; j++ {
n := Iterate(f, complex(float64(i)/s, float64(j)/s), 256)
r := uint8(0)
g := uint8(0)
b := uint8(n % 32 * 8)
img.Set(i, j, color.RGBA{r, g, b, 255})
}
}
return img
}
// Iterate sets z_0 = z, and repeatedly computes z_n = f(z_{n-1}), n ≥ 1,
// until |z_n| > 2 or n = max and returns this n.
func Iterate(f ComplexFunc, z complex128, max int) (n int) {
for ; n < max; n++ {
if real(z)*real(z)+imag(z)*imag(z) > 4 {
break
}
z = f(z)
}
return
}
I have decided to try and make the Julia() function concurrent. So I changed it to:
func Julia(f ComplexFunc, n int) image.Image {
bounds := image.Rect(-n/2, -n/2, n/2, n/2)
img := image.NewRGBA(bounds)
s := float64(n / 4)
for i := bounds.Min.X; i < bounds.Max.X; i++ {
for j := bounds.Min.Y; j < bounds.Max.Y; j++ {
go func(){
n := Iterate(f, complex(float64(i)/s, float64(j)/s), 256)
r := uint8(0)
g := uint8(0)
b := uint8(n % 32 * 8)
img.Set(i, j, color.RGBA{r, g, b, 255})
}()
}
}
return img
This change causes the images to look very different. The patterns are essentially the same, but there are a lot of white pixels that were not there before.
What is happening here?
There are 2 problems:
You don't actually wait for your goroutines to finish.
You don't pass i and j to the goroutine, so they will almost always be the last i and j.
Your function should look something like:
func Julia(f ComplexFunc, n int) image.Image {
var wg sync.WaitGroup
bounds := image.Rect(-n/2, -n/2, n/2, n/2)
img := image.NewRGBA(bounds)
s := float64(n / 4)
for i := bounds.Min.X; i < bounds.Max.X; i++ {
for j := bounds.Min.Y; j < bounds.Max.Y; j++ {
wg.Add(1)
go func(i, j int) {
n := Iterate(f, complex(float64(i)/s, float64(j)/s), 256)
r := uint8(0)
g := uint8(0)
b := uint8(n % 32 * 8)
img.Set(i, j, color.RGBA{r, g, b, 255})
wg.Done()
}(i, j)
}
}
wg.Wait()
return img
}
A bonus tip, when diving into concurrency, it's usually a good idea to try your code with the race detector.
You might have to use a mutex to call img.Set but I'm not very sure and I can't test atm.

Is this a reasonable and idiomatic GoLang circular shift implementation?

Can anyone comment on whether this is a reasonable and idiomatic way of implementing circular shift of integer arrays in Go? (I deliberately chose not to use bitwise operations.)
How could it be improved?
package main
import "fmt"
func main() {
a := []int{1,2,3,4,5,6,7,8,9,10}
fmt.Println(a)
rotateR(a, 5)
fmt.Println(a)
rotateL(a, 5)
fmt.Println(a)
}
func rotateL(a []int, i int) {
for count := 1; count <= i; count++ {
tmp := a[0]
for n := 1;n < len(a);n++ {
a[n-1] = a[n]
}
a[len(a)-1] = tmp
}
}
func rotateR(a []int, i int) {
for count := 1; count <= i; count++ {
tmp := a[len(a)-1]
for n := len(a)-2;n >=0 ;n-- {
a[n+1] = a[n]
}
a[0] = tmp
}
}
Rotating the slice one position at a time, and repeating to get the total desired rotation means it will take time proportional to rotation distance × length of slice. By moving each element directly into its final position you can do this in time proportional to just the length of the slice.
The code for this is a little more tricky than you have, and you’ll need a GCD function to determine how many times to go through the slice:
func gcd(a, b int) int {
for b != 0 {
a, b = b, a % b
}
return a
}
func rotateL(a []int, i int) {
// Ensure the shift amount is less than the length of the array,
// and that it is positive.
i = i % len(a)
if i < 0 {
i += len(a)
}
for c := 0; c < gcd(i, len(a)); c++ {
t := a[c]
j := c
for {
k := j + i
// loop around if we go past the end of the slice
if k >= len(a) {
k -= len(a)
}
// end when we get to where we started
if k == c {
break
}
// move the element directly into its final position
a[j] = a[k]
j = k
}
a[j] = t
}
}
Rotating a slice of size l right by p positions is equivalent to rotating it left by l − p positions, so you can simplify your rotateR function by using rotateL:
func rotateR(a []int, i int) {
rotateL(a, len(a) - i)
}
Your code is fine for in-place modification.
Don't clearly understand what you mean by bitwise operations. Maybe this
package main
import "fmt"
func main() {
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
fmt.Println(a)
rotateR(&a, 4)
fmt.Println(a)
rotateL(&a, 4)
fmt.Println(a)
}
func rotateL(a *[]int, i int) {
x, b := (*a)[:i], (*a)[i:]
*a = append(b, x...)
}
func rotateR(a *[]int, i int) {
x, b := (*a)[:(len(*a)-i)], (*a)[(len(*a)-i):]
*a = append(b, x...)
}
Code works https://play.golang.org/p/0VtiRFQVl7
It's called reslicing in Go vocabulary. Tradeoff is coping and looping in your snippet vs dynamic allocation in this. It's your choice, but in case of shifting 10000 elements array by one position reslicing looks much cheaper.
I like Uvelichitel solution but if you would like modular arithmetic which would be O(n) complexity
package main
func main(){
s := []string{"1", "2", "3"}
rot := 5
fmt.Println("Before RotL", s)
fmt.Println("After RotL", rotL(rot, s))
fmt.Println("Before RotR", s)
fmt.Println("After RotR", rotR(rot,s))
}
func rotL(m int, arr []string) []string{
newArr := make([]string, len(arr))
for i, k := range arr{
newPos := (((i - m) % len(arr)) + len(arr)) % len(arr)
newArr[newPos] = k
}
return newArr
}
func rotR(m int, arr []string) []string{
newArr := make([]string, len(arr))
for i, k := range arr{
newPos := (i + m) % len(arr)
newArr[newPos] = k
}
return newArr
}
If you need to enter multiple values, whatever you want (upd code Uvelichitel)
package main
import "fmt"
func main() {
var N, n int
fmt.Scan(&N)
a := make([]int, N)
for i := 0; i < N; i++ {
fmt.Scan(&a[i])
}
fmt.Scan(&n)
if n > 0 {
rotateR(&a, n%len(a))
} else {
rotateL(&a, (n*-1)%len(a))
}
for _, elem := range a {
fmt.Print(elem, " ")
}
}
func rotateL(a *[]int, i int) {
x, b := (*a)[:i], (*a)[i:]
*a = append(b, x...)
}
func rotateR(a *[]int, i int) {
x, b := (*a)[:(len(*a)-i)], (*a)[(len(*a)-i):]
*a = append(b, x...)
}

Challenge of finding 3 pairs in array

The length L at the time of joining, when the length of the bar of the N (1 ≦ N ≦ 5000) is supplied from standard input, is the L by connecting three lengths among the N number of bars please write a program to find the total number of combinations of. However, and the length of the individual bars, length was pieced together (L) is a positive integer, is sufficient handle range in 32bit integer. In addition, it has all the length of the bar different things.
for example)
input:
15
5
8
4
10
3
2
output:
2 //{{2, 3, 10}, {3, 4, 8}}
example 2)
input :
35
10
13
12
17
10
4
18
3
11
5
7
output:
6 //{{4, 13, 18}, {5, 12, 18}, {5, 13, 17}, {7, 10, 18}, {7, 11, 17}, {10, 12, 13}}
and my answer is here
package main
import (
"fmt"
"sort"
)
func main() {
input_count := 0
var target int
var count int
var v int
var array []int
for read_count, _ := fmt.Scan(&v); read_count != 0; read_count, _ = fmt.Scan(&v) {
if 0 == input_count {
target = v
} else if 1 == input_count {
count = v
array = make([]int, count)
} else {
array[input_count-2] = v
}
input_count++
}
sort.Ints(array)
fmt.Println(Calculate(target, count, array))
}
func Except(pair []int, count int, array []int) []int {
except := make([]int, count-pair[2])
except_index := 0
on := false
for _, v := range array {
if on {
except[except_index] = v
except_index++
}
if v == pair[1] {
on = true
}
}
return except
}
func ListUp(target int, count int, array []int) [][]int {
max := array[count-1]
list := make([][]int, Fact(count-1))
list_index := 0
for i, h := range array {
if count > i+1 && target > h+array[i+1] {
for j, v := range array[i+1:] {
if count > i+j+1 && target <= max+h+v && target > h+v {
list[list_index] = []int{h, v, i + j + 1}
list_index++
}
}
}
}
return list
}
//func Calculate(target int, count int, array []int) [][]int {
func Calculate(target int, count int, array []int) int {
// var answers [][]int
answer_count := 0
for _, pair := range ListUp(target, count, array) {
if 3 == len(pair) {
pair_sum := pair[0] + pair[1]
if target-pair_sum >= array[0] {
for _, v := range Except(pair, count, array) {
if target == pair[0]+pair[1]+v {
// answers = append(answers, []int{pair[0], pair[1], v})
answer_count++
}
}
}
}
}
return answer_count
}
func Fact(n int) int {
if n == 0 {
return 0
}
return n + Fact(n-1)
}
Does anyone who can refactor the code?
and you should refactor it
if input
https://github.com/freddiefujiwara/horiemon-challenge-codeiq/blob/master/sample4.txt
then output
1571200
in 10 seconds
current status is here
time ./horiemon-challenge-codeiq < sample4.txt
1571200
real 6m56.584s
user 6m56.132s
sys 0m1.578s
very very slow.
Your time of almost seven minutes is very, very slow. Ten seconds is slow. One second is more reasonable, a tenth of a second is good. For example, using an O(N*N) algorithm,
package main
import (
"bufio"
"errors"
"fmt"
"io"
"os"
"sort"
"strconv"
"strings"
)
func triples(l int, b []int) int {
t := 0
sort.Ints(b)
// for i < j < k, b[i] <= b[j] <= b[k]
for i := 0; i < len(b)-2; i++ {
x := b[i]
if x > l {
break
}
lx := l - x
j, k := i+1, len(b)-1
y := b[j]
z := b[k]
for j < k {
yz := y + z
switch {
case lx > yz:
j++
y = b[j]
case lx < yz:
k--
z = b[k]
default:
// l == b[i]+b[j]+b[k]
t++
j++
k--
y = b[j]
z = b[k]
}
}
}
return t
}
func readInput() (l int, b []int, err error) {
r := bufio.NewReader(os.Stdin)
for {
line, err := r.ReadString('\n')
line = strings.TrimSpace(line)
if err == nil && len(line) == 0 {
err = io.EOF
}
if err != nil {
if err == io.EOF {
break
}
return 0, nil, err
}
i, err := strconv.Atoi(string(line))
if err == nil && i < 0 {
err = errors.New("Nonpositive number: " + line)
}
if err != nil {
return 0, nil, err
}
b = append(b, i)
}
if len(b) > 0 {
l = b[0]
b = b[1:]
if len(b) > 1 {
n := b[0]
b = b[1:]
if n != len(b) {
err := errors.New("Invalid number of bars: " + strconv.Itoa(len(b)))
return 0, nil, err
}
}
}
return l, b, nil
}
func main() {
l, b, err := readInput()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
t := triples(l, b)
fmt.Println(t)
}
Output:
1571200
real 0m0.164s
user 0m0.161s
sys 0m0.004s
For comparison, your program,
Output:
1571200
real 9m24.384s
user 16m14.592s
sys 0m19.129s
ive tuned
package main
import (
"bufio"
"errors"
"fmt"
"io"
"os"
"sort"
"strconv"
"strings"
)
type triple struct {
x, y, z int
}
func triples(l int, n []int, list bool) (nt int, t []triple) {
num_of_list := len(n)
for i := 0; i < num_of_list-2; i++ {
x := n[i]
if x > l {
break
}
for j := i + 1; j < num_of_list-1; j++ {
y := x + n[j]
if y > l {
break
}
pos := sort.SearchInts(n[j:], l-y)
if j < pos+j && pos+j < num_of_list && n[pos+j] == l-y {
nt++
}
}
}
return nt, t
}
func readInput() (l int, n []int, err error) {
r := bufio.NewReader(os.Stdin)
for {
line, err := r.ReadString('\n')
line = strings.TrimSpace(line)
if err == nil && len(line) == 0 {
err = io.EOF
}
if err != nil {
if err == io.EOF {
break
}
return 0, nil, err
}
i, err := strconv.Atoi(string(line))
if err == nil && i < 0 {
err = errors.New("Nonpositive number: " + line)
}
if err != nil {
return 0, nil, err
}
n = append(n, i)
}
if len(n) > 0 {
l = n[0]
n = n[1:]
}
sort.Ints(n)
for i := 1; i < len(n); i++ {
if n[i] == n[i-1] {
copy(n[i:], n[i+1:])
n = n[:len(n)-1]
}
}
return l, n, nil
}
func main() {
l, n, err := readInput()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
list := false
nt, t := triples(l, n, list)
fmt.Println(nt)
if list {
fmt.Println(t)
}
}

What's wrong with my Priority Queue's Pop method?

Based on Rob Pike's load balancer demo, I implemented my own priority queue, but my Pop method is not right, can anyone tell me what's wrong?
package main
import (
"fmt"
"container/heap"
)
type ClassRecord struct {
name string
grade int
}
type RecordHeap []*ClassRecord
func (p RecordHeap) Len() int { return len(p) }
func (p RecordHeap) Less(i, j int) bool {
return p[i].grade < p[j].grade
}
func (p *RecordHeap) Swap(i, j int) {
a := *p
a[i], a[j] = a[j], a[i]
}
func (p *RecordHeap) Push(x interface{}) {
a := *p
n := len(a)
a = a[0 : n+1]
r := x.(*ClassRecord)
a[n] = r
*p = a
}
func (p *RecordHeap) Pop() interface{} {
a := *p
*p = a[0 : len(a)-1]
r := a[len(a)-1]
return r
}
func main() {
a := make([]ClassRecord, 6)
a[0] = ClassRecord{"John", 80}
a[1] = ClassRecord{"Dan", 85}
a[2] = ClassRecord{"Aron", 90}
a[3] = ClassRecord{"Mark", 65}
a[4] = ClassRecord{"Rob", 99}
a[5] = ClassRecord{"Brian", 78}
h := make(RecordHeap, 0, 100)
for _, c := range a {
fmt.Println(c)
heap.Push(&h, &c)
fmt.Println("Push: heap has", h.Len(), "items")
}
for i, x := 0, heap.Pop(&h).(*ClassRecord); i < 10 && x != nil; i++ {
fmt.Println("Pop: heap has", h.Len(), "items")
fmt.Println(*x)
}
}
EDIT: besides the way cthom06 pointed out, another way to fix this is to create a pointer array as follows,
a := make([]*ClassRecord, 6)
a[0] = &ClassRecord{"John", 80}
a[1] = &ClassRecord{"Dan", 85}
......
EDIT:
Oh I should've seen this right away.
heap.Push(&h, &c)
You push the address of c, which gets reused on each iteration of range. Every record in the heap is a pointer to the same area in memory, which ends up being Brian. I'm not sure if this is intended behavior or a compiler bug, but
t := c
heap.Push(&h, &t)
works around it.
Also: Your for loop is wrong.
for h.Len() > 0 {
x := heap.Pop(&h...
should fix it.

Resources