Related
I'm trying to get the max value from a diff, n[i] - n[i-1], timeseries. The first value is always zero from the slice, here is the code:
func MaxBelowZero(n ...float64) float64 {
var maxValue float64
if len(n) == 1 {
return n[0]
} else if len(n) == 0 {
return 0.
}
for i := range n {
if i == 0 {
maxValue = math.SmallestNonzeroFloat64
continue
}
if maxValue < n[i] && n[i] < 0 {
maxValue = n[i]
}
}
return maxValue
}
var sliceTest = []float64{0, 1, 2, -1, -2, -10, 10, 20}
MaxBelowZero(sliceTest...)
Output: 5e-324
It supossed to be -1. What am I doing wrong? I would appreciate some help.
The code in playground: link
math.SmallestNonzeroFloat64 is the number closest to 0 that is not 0, not the number furthest from zero. Try this:
go playground
func MaxBelowZero(values ...float64) float64 {
if len(values) == 0 {
return 0
} else if len(values) == 1 {
return values[0]
}
max := -math.MaxFloat64
for _, n := range values {
if n >= 0 {
continue
}
if n > max {
max = n
}
}
return max
}
func MaxBelowZero(n ...float64) float64 {
maxValue := -math.MaxFloat64 // Initial value must be negative
if len(n) == 1 {
return n[0]
} else if len(n) == 0 {
return 0.
}
for i := 1; i < len(n); i++ {
diff := n[i] - n[i-1] // Correct logic here
if diff > maxValue && diff < 0 {
maxValue = diff
}
}
return maxValue
}
You could reverse sort the slice, then find first negative number:
package main
import "sort"
func main() {
a := []float64{0, 1, 2, -1, -2, -10, 10, 20}
sort.Slice(a, func(d, e int) bool {
return a[e] < a[d]
})
n := sort.Search(len(a), func(n int) bool {
return a[n] < 0
})
println(a[n] == -1)
}
Or sort by sign, then by absolute value:
package main
import "math"
type sFunc func(a, b float64) bool
var sFuncs = []sFunc{
func(a, b float64) bool {
return math.Copysign(1, a) < math.Copysign(1, b)
},
func(a, b float64) bool {
return math.Abs(a) < math.Abs(b)
},
}
Result:
package main
import (
"fmt"
"sort"
)
func main() {
floats := []float64{0, 1, 2, -1, -2, -10, 10, 20}
sort.Slice(floats, func(a, b int) bool {
fa, fb := floats[a], floats[b]
for _, sf := range sFuncs {
if sf(fa, fb) {
return true
}
if sf(fb, fa) {
break
}
}
return false
})
fmt.Println(floats) // [-1 -2 -10 0 1 2 10 20]
}
https://golang.org/pkg/sort#Search
https://golang.org/pkg/sort#Slice
enter image description here
This code snippet is for give two slice of binary number a1 and a2 to return sum slice r1, and I want to figure out how long spend with this code snippet figure out the result.
and I figure out the factorial result.
Is my analysis right?
my analysis for time complexity is:
cn + (n*n!) + c
the Code is:
func BinaryPlus(a1 []int, a2 []int) []int {
var r1 = make([]int, len(a1), 2*(len(a1)))
for i := 0; i < len(a1); i++ {
r1[i] = a1[i] + a2[i]
}
// 二分反转
ReverseSlice(r1)
r1 = append(r1, 0)
final := 0
for i := 0; final != 1; i++ {
isOver := 1
for j := 0; j < len(r1); j++ {
if r1[j] > 1 {
r1[j] = r1[j] % 2
r1[j+1] += 1
if r1[j+1] > 1 {
isOver = 0
}
}
}
if isOver == 1 {
final = 1
}
}
// 二分反转
ReverseSlice(r1)
return r1
}
func ReverseSlice(s interface{}) {
n := reflect.ValueOf(s).Len()
swap := reflect.Swapper(s)
for i, j := 0, n-1; i < j; i, j = i+1, j-1 {
swap(i, j)
}
}
It is not entirely clear that your code, as written, is correct. The size cap for your result array could be too small. Consider the case that len(a2) > 2*len(a1): the r1 := make(...) will not reserve enough in this case. Further, the initial for loop will miss adding in the more significant bits of a2.
Binary addition should have no more than O(n) complexity. You can do it with a single for loop. n = 1+max(len(a1),len(a2)):
package main
import (
"fmt"
"reflect"
)
func BinaryPlus(a1 []int, a2 []int) []int {
reserve := len(a1) + 1
if x := len(a2) + 1; x > reserve {
reserve = x
}
hold := 0
maxBit := 1
ans := make([]int, reserve)
for i := 1; i <= reserve; i++ {
hold = hold / 2
if i <= len(a1) {
hold += a1[len(a1)-i]
}
if i <= len(a2) {
hold += a2[len(a2)-i]
}
ans[reserve-i] = hold & 1
if hold != 0 && i > maxBit {
maxBit = i
}
}
return ans[reserve-maxBit:]
}
func main() {
tests := []struct {
a, b, want []int
}{
{
a: []int{1},
b: []int{0},
want: []int{1},
},
{
a: []int{1, 0},
b: []int{0, 0, 1},
want: []int{1, 1},
},
{
a: []int{1, 0, 0, 1},
b: []int{1, 1, 1, 1, 0},
want: []int{1, 0, 0, 1, 1, 1},
},
{
a: []int{0, 0},
b: []int{0, 0, 0, 0, 0},
want: []int{0},
},
}
bad := false
for i := 0; i < len(tests); i++ {
t := tests[i]
c := BinaryPlus(t.a, t.b)
if !reflect.DeepEqual(c, t.want) {
fmt.Println(t.a, "+", t.b, "=", c, "; wanted:", t.want)
bad = true
}
}
if bad {
fmt.Println("FAILED")
} else {
fmt.Println("PASSED")
}
}
I have a slice of int containing only zeros and ones ([]int{1,1,1,1,0,0,0,0})
I want to convert the string representation to hex value. I'm converting the slice of ints to a slice of strings then doing a strconv.ParseUint to convert.
package main
import (
"fmt"
"log"
"strconv"
"strings"
)
func IntToString(values []int) string {
valuesText := []string{}
for i := range values {
valuesText = append(valuesText, strconv.Itoa(values[i]))
}
return strings.Join(valuesText, "")
}
func IntSliceToHex(in []int) (string, error) {
intString := IntToString(in)
ui, err := strconv.ParseUint(intString, 2, 64)
if err != nil {
return "", err
}
return fmt.Sprintf("%X", ui), nil
}
func HexToBin(hex string) (string, error) {
ui, err := strconv.ParseUint(hex, 16, 64)
if err != nil {
return "", err
}
return fmt.Sprintf("%b", ui), nil
}
func main() {
profile := []int{1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1}
hex, err := IntSliceToHex(profile)
if err != nil {
log.Fatalln(err)
}
bin, err := HexToBin(hex)
if err != nil {
log.Fatalln(err)
}
fmt.Println(hex, bin)
}
OUTPUT: F0F 111100001111
Is there a better way to do this?
You should use bitshift operations to build up the actual number from the slice rather than converting each bit to string and parsing it.
You should also keep the built-up integer rather than converting back and forth to a string.
package main
import (
"fmt"
)
func main() {
profile := []int{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
final := uint64(profile[0])
for i := 1; i < len(profile); i++ {
final <<= 1
final += uint64(profile[i])
}
fmt.Printf("%X %b\n", final, final)
// Output: FFFFFFFFFFFF0000 1111111111111111111111111111111111111111111111110000000000000000
}
Note: final is an unsigned 64 bit integer and can handle profile slices of length up to (and including) 64. For larger sizes, use big.Int.
I'm learning go concurrency and I wanted to implement a simple example that takes rows from a matrix and adds an array (slice) of values to each row.
Since I am using channels I try to wait for each row to get its corresponding result from the goroutine. However, this is not better than just doing this synchronously. How can I make each row wait for their respective result and allow the other rows to calculate their results concurrently?
https://play.golang.org/p/uCOGwOBeIQL
package main
import "fmt"
/*
Array:
0 1 2 3 4 5 6 7 8 9
+
Matrix:
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
->
Expected result:
1 1 2 3 4 5 6 7 8 9
0 2 2 3 4 5 6 7 8 9
0 1 3 3 4 5 6 7 8 9
0 1 2 4 4 5 6 7 8 9
0 1 2 3 5 5 6 7 8 9
0 1 2 3 4 6 6 7 8 9
0 1 2 3 4 5 7 7 8 9
0 1 2 3 4 5 6 8 8 9
0 1 2 3 4 5 6 7 9 9
0 1 2 3 4 5 6 7 8 10
*/
func main() {
numbers := []int {0,1,2,3,4,5,6,7,8,9}
matrix := [][]int{
{1,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,0},
{0,0,1,0,0,0,0,0,0,0},
{0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0},
{0,0,0,0,0,0,1,0,0,0},
{0,0,0,0,0,0,0,1,0,0},
{0,0,0,0,0,0,0,0,1,0},
{0,0,0,0,0,0,0,0,0,1},
}
rmatrix := make([][]int, 10)
for i, row := range matrix {
cResult := make(chan []int)
go func(row []int, numbers []int, c chan <- []int) {
c <- addRow(row,numbers)
}(row,numbers,cResult)
//this read from the channel will block until the goroutine sends its result over the channel
rmatrix[i] = <- cResult
}
fmt.Println(rmatrix)
}
func addRow(row []int, numbers []int) []int{
result := make([]int, len(row))
for i,e := range row {
result[i] = e + numbers[i];
}
return result
}
This example spawns a lesser number of goroutines and also guarantees the correct order irrespective of which goroutine completed it's processing first.
package main
import (
"fmt"
"sync"
)
type rowRes struct {
index int
result *[]int
}
func addRow(index int, row []int, numbers []int) rowRes {
result := make([]int, len(row))
for i, e := range row {
result[i] = e + numbers[i]
}
return rowRes{
index: index,
result: &result,
}
}
func main() {
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
matrix := [][]int{
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
}
rmatrix := make([][]int, 10)
// Buffered channel
rowChan := make(chan rowRes, 10)
wg := sync.WaitGroup{}
// Reciever goroutine
go recv(rowChan, rmatrix)
for i := range matrix {
wg.Add(1)
go func(index int, row []int, w *sync.WaitGroup) {
rowChan <- addRow(index, row, numbers)
w.Done()
}(i, matrix[i], &wg)
}
wg.Wait()
close(rowChan)
fmt.Println(rmatrix)
}
func recv(res chan rowRes, rmatrix [][]int) {
for {
select {
case k, ok := <-res:
if !ok {
return
}
rmatrix[k.index] = *k.result
}
}
}
I needed to use a sync.WaitGroup and assign directly the results of the call (to guarantee they go back to their indexed row). Thanks #Peter
package main
import (
"fmt"
"sync"
)
func main() {
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
matrix := [][]int{
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
}
rmatrix := make([][]int, 10)
var waitGroup sync.WaitGroup
for i, row := range matrix {
waitGroup.Add(1)
go func(i int, row []int) {
rmatrix[i] = addRow(row, numbers)
waitGroup.Done()
}(i, row)
}
waitGroup.Wait()
fmt.Println(rmatrix)
}
func addRow(row []int, numbers []int) []int {
result := make([]int, len(row))
for i, e := range row {
result[i] = e + numbers[i]
}
return result
}
pipeline method
taskChannel := make(chan string,1000); // Set up the task queue
wg := sync.WaitGroup
// Task release
wg.add(1)
go func(&wg,taskChannel) {
defer wg.Down()
for i in "task list" {
taskChannel <- "Stuff the characters you want to deal with here"
}
// After the task is sent and closed
close(taskChannel)
}(wg *sync.WaitGroup,taskChannel chan string)
// Task execution
go func(&wg,taskChannel,1000) {
defer wg.Down()
limit := make(chan bool,limitNumber); // Limit the number of concurrent
tg := sync.WaitGroup
loop:
for {
select {
case task,over := <-taskChannel:
if !over { // If there are no more tasks, quit
tg.Wait() // Wait for all tasks to end
break loop
}
tg.Add(1)
limit<-true
go func(&tg,limitm) {
defer func() {
<-limit
tg.Down()
}
// Business processing logic, processing tasks
}(tg *sync.WaitGroup,limit chan bool,task string)
}
}
}(wg *sync.WaitGroup,taskChannel chan string,limitNumber int)
wg.Wait()
Hope to help you
I am trying to solve a sudoku puzzle in Go using a recursive backtracking algorithm. I created helper functions that check if a certain row, column, or block are valid (i.e no repeated values), as well as a function to print out the current state. I have tested all of these many times so I don't think they are causing the issue. I created the following function to test if a potential game board would be possible.
func cellValid(gameBoard *[9][9]int, value int, y int, x int) bool {
oldVal := gameBoard[y-1][x-1]
gameBoard[y-1][x-1] = value
row := getRow(gameBoard, y)
col := getCol(gameBoard, x)
block := getBlock(gameBoard, x, y)
possible := unitValid(row) && unitValid(col) && unitValid(block)
gameBoard[y-1][x-1] = oldVal
return possible
}
It makes a change to the gameboard, checks if it is possible and stores that bool in the variable possible. It changes the board back to what it was then returns the bool. This function is being called from the following solveBoard function.
func solveBoard(gameBoard *[9][9]int) {
for row := 1; row <= 9; row++ {
for col := 1; col <= 9; col++ {
if gameBoard[row-1][col-1] == 0 {
for value := 1; value <= 9; value++ {
if cellValid(gameBoard, value, row, col) {
gameBoard[row-1][col-1] = value
solveBoard(gameBoard)
gameBoard[row-1][col-1] = 0
}
}
return
}
}
}
printBoard(gameBoard)
return
}
Upon running the file I get no output.
func main() {
var gameBoard = [9][9]int{
{5, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}}
solveBoard(&gameBoard)
}
Here is a link to a go playground containing all my code.
Go Playground
The following video demonstrates what I am trying to accomplish in python.
Computerphile Video
Solution to puzzle:
Puzzle solution
Your program works perfectly fine. Double check the second last line of your matrix:
You have:
{0, 0, 0, 4, 1, 7, 0, 0, 5},
But it should be
{0, 0, 0, 4, 1, 9, 0, 0, 5},
The final working code is.
package main
import (
"fmt"
)
func printBoard(gameBoard *[9][9]int) {
for y := 0; y < 9; y++ {
if y == 3 || y == 6 {
fmt.Println("\n---------")
} else {
fmt.Println("")
}
for x := 0; x < 9; x++ {
if x == 3 || x == 6 {
fmt.Print("|", gameBoard[y][x])
} else {
fmt.Print("", gameBoard[y][x])
}
}
}
fmt.Println("")
}
func unitValid(unit [9]int) bool {
for value := 1; value <= 9; value++ {
count := 0
for index := 0; index < 9; index++ {
if unit[index] == value {
count++
}
}
if count > 1 {
return false
}
}
return true
}
func getRow(gameBoard *[9][9]int, row int) [9]int {
return gameBoard[row-1]
}
func getCol(gameBoard *[9][9]int, col int) [9]int {
var column [9]int
for row := 0; row < 9; row++ {
column[row] = gameBoard[row][col-1]
}
return column
}
func getBlock(gameBoard *[9][9]int, row, col int) [9]int {
i := whatBlock(col)*3 - 2
j := whatBlock(row)*3 - 2
var block [9]int
block[0] = gameBoard[j-1][i-1]
block[1] = gameBoard[j-1][i]
block[2] = gameBoard[j-1][i+1]
block[3] = gameBoard[j][i-1]
block[4] = gameBoard[j][i]
block[5] = gameBoard[j][i+1]
block[6] = gameBoard[j+1][i-1]
block[7] = gameBoard[j+1][i]
block[8] = gameBoard[j+1][i+1]
return block
}
func whatBlock(val int) int {
if val >= 1 && val <= 3 {
return 1
} else if val >= 4 && val <= 6 {
return 2
} else if val >= 7 && val <= 9 {
return 3
}
return 0
}
func cellValid(gameBoard *[9][9]int, value int, y int, x int) bool {
oldVal := gameBoard[y-1][x-1]
gameBoard[y-1][x-1] = value
row := getRow(gameBoard, y)
col := getCol(gameBoard, x)
block := getBlock(gameBoard, y, x)
possible := unitValid(row) && unitValid(col) && unitValid(block)
gameBoard[y-1][x-1] = oldVal
return possible
}
func solveBoard(gameBoard *[9][9]int) {
for row := 1; row <= 9; row++ {
for col := 1; col <= 9; col++ {
if gameBoard[row-1][col-1] == 0 {
for value := 1; value <= 9; value++ {
if cellValid(gameBoard, value, row, col) {
gameBoard[row-1][col-1] = value
solveBoard(gameBoard)
gameBoard[row-1][col-1] = 0
}
}
return
}
}
}
printBoard(gameBoard)
return
}
func main() {
var gameBoard = [9][9]int{
{5, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}}
solveBoard(&gameBoard)
}