优化大型数组中值的比较 - 转到

时间:2017-02-07 03:55:17

标签: arrays loops recursion go

我正在努力学习Go,并尝试解决此处所解释的问题https://projecteuler.net/problem=215

我提出了一个有效的解决方案,但是一旦问题变得复杂就需要很长时间才能计算出来,在没有解决问题的情况下运行数小时,所以我认为我需要以某种方式优化我的解决方案。以下是我的代码

package main

import "fmt"

func main() {
    fmt.Println(wall(18, 10))
}

func wall(width, height int) int64 {

    var total int64

    combinations := findCombinations(width)

    combiPointer := &combinations

    for i := 0; i < 4; i++ {
        for _, a := range combinations[i] {
            if i%2 == 0 {
                buildWall(a, combiPointer[i+1], 0, height, i+1, &total, combiPointer)
            } else {
                buildWall(a, combiPointer[i-1], 0, height, i-1, &total, combiPointer)
            }
        }
    }
return total
}

func buildWall(a []int, combi [][]int, level, height, index int, total *int64, pointer *[4][][]int) {
level++
var canCombine bool
for _, a1 := range combi {
    canCombine = true
    for _, value := range a {
            if canCombine == false {
                break
            }
            for _, value1 := range a1 {
                if value == value1 {
                    canCombine = false
                    break
                }
            }
        }
        if canCombine == true && level < height {

            if index%2 == 0 {
                buildWall(a1, pointer[index+1], level, height, index+1, total, pointer)
            } else {
                buildWall(a1, pointer[index-1], level, height, index-1, total, pointer)
            }
        } else if level == height {
            *total++
            break
        }
    }
}

findCombinations正常工作并返回包含所有可能解决方案的三维数组。 [0]和[1]中的数组可以(可能)相互叠加而不会发生裂缝。 [2]和[3]相同。我选择通过查看用于构建墙的第一个和最后一个块的位置来切割4个阵列中的所有解决方案的数组,因为我认为它会提高性能以循环遍历较小的阵列。

func findCombinations(width int) [4][][]int {
    var i int
    var tmp int
    var tmpInt1 int
    var tmpInt2 int
    open := make([][]int, 0, 100)
    var solutionsHolder [4][][]int
    open = append(open, []int{3, 2})
    tmpArray := make([]int, 0, 100)

    for {
        if len(open[i]) > 0 {
            tmpArray = append(tmpArray[:i], open[i][0])
            open[i] = append(open[i][:0], open[i][1:]...)
            counter := 0
            for _, x := range tmpArray {
                counter += x
            }
            if counter == width {
                solutionArray := make([]int, len(tmpArray)-1)
                counter2 := 0
                for n := 0; n < len(tmpArray)-1; n++ {
                    if n == 0 {
                        tmpInt1 = tmpArray[n] % 2
                    }
                    counter2 += tmpArray[n]
                    solutionArray[n] = counter2
                }
                tmpInt2 = counter2 % 2
                if tmpInt1 == 0 && tmpInt2 == 0 {
                    solutionsHolder[0] = append(solutionsHolder[0], solutionArray)
                } else if tmpInt1 == 1 && tmpInt2 == 1 {
                    solutionsHolder[1] = append(solutionsHolder[1], solutionArray)
                } else if tmpInt1 == 1 && tmpInt2 == 0 {
                    solutionsHolder[2] = append(solutionsHolder[2], solutionArray)
                } else {
                    solutionsHolder[3] = append(solutionsHolder[3], solutionArray)
                }

                for _, v := range open {
                    tmp += len(v)
                }
                if tmp == 0 {
                    return solutionsHolder
                }
                tmp = 0
            } else if counter > width {
                for _, v := range open {
                    tmp += len(v)
                }
                if tmp == 0 {
                   return solutionsHolder
                }
                tmp = 0
            } else if counter < width {
                i++
                if len(open) <= i {
                    open = append(open, []int{3, 2})
                } else {
                    open[i] = append(open[i], []int{3, 2}...)
                }
            }
        } else {
            i--
        }
    }
}

它的wall函数调用一个递归函数,如果你插入一个宽度和高度的墙(32,10),它会运行很长一段时间(我已经运行了一个小时没有结果)希望你在网站上计算。

通过墙壁调用的

buildWall()检查两个解决方案的相同位置是否没有裂缝,如果是这种情况,它会再次为墙壁的下一层运行buildWall,直到达到墙壁高度。它将每个解决方案与其他所有可能的解决方案进行比较,但仅限于3d阵列的一个子集。

我想也许有另一种方法可以找到所有可以组合的墙,但我似乎无法绕过它。

0 个答案:

没有答案