使用golang和并发验证9x9数独板

问题描述 投票:0回答:1

我正在通过在LeetCode上进行编码问题来练习golang。我正在尝试解决一个简单的数独难题(它只是验证了棋盘)。没有具有相同数字的行,没有具有相同数字的列,没有具有相同数字的3x3块。我正在尝试使用并发性来学习Go Routines / Channels / Etc ...

我无法让等待组完成

import (
    "sync"
    "fmt"
)
func isValidSlice(slice []byte, results chan<- bool, wg *sync.WaitGroup) {
    fmt.Println(slice)
    seen := make(map[byte]bool)
    for _,val := range(slice) {
        if seen[val] {
            if val != '.'{
                results <- false
                defer wg.Done()
                return    
            }
        } else {
            seen[val] = true
        }
    }

    results <- true
    defer wg.Done()
}

func isValidSudoku(board [][]byte) bool {
    // Channel to receive solution
    c := make(chan bool)

    // Number of routines that will run (9 for rows, 9 for cols, 9 for 3x3 blocks)
    var wg sync.WaitGroup

    // Check every row
    for x:= 0; x < 9; x++{
        wg.Add(1)
        go isValidSlice(append([]byte{}, board[x]...), c, &wg)
    }
    for y:= 0; y < 9; y++{
        wg.Add(1)
        go isValidSlice(append([]byte{}, board[0:9][y]...), c, &wg)   
    }
    // Check every 3x3 block
    for x:= 0; x <= 6; x += 3{
        for y := 0; y <= 6; y += 3{
            block_digits := append([]byte{}, board[x][y:y+3]...)
            block_digits = append(block_digits, board[x+1][y:y+3]...)
            block_digits = append(block_digits, board[x+2][y:y+3]...)
            wg.Add(1)
            go isValidSlice(block_digits, c, &wg)
        }
    }

    fmt.Println("got here")
    wg.Wait()
    fmt.Println("never got here")

    for result := range c{
        if !result{
            return false
        }
    }

    return true
}

我期望wg.Wait()锁能够释放,并且代码可以向前移动。然后,我期望通道中的结果之一为false,如果为false,则返回false。否则,在遍历通道中的所有元素且未找到任何错误之后,我期望为真。

go sudoku
1个回答
0
投票

您的goroutine无法调用wg.Done(),因为它们都等待在通道中添加其值。但是由于您只消耗wg.Wait()之后的通道中的值,因此除一个之外的所有goroutine都永远无法调用wg.Done()。]

只需在最后循环后移动wg.Wait()

其他评论:

  1. 您应将defer wg.Done()移至isValidSlice的第一行。毫无意义地推迟现在的样子。
  2. 您实际上可以删除wg.Wait()。仅当您要正确关闭通道时才需要它,并且可以在其他goroutine中执行此操作。
© www.soinside.com 2019 - 2024. All rights reserved.