55 lines
1.3 KiB
Go
55 lines
1.3 KiB
Go
package q756
|
|
|
|
type Bottom [2]byte
|
|
|
|
func canBuild(buffer []byte, layer, offset int, allowed map[Bottom][]byte) bool {
|
|
layerOffset := len(buffer) - (layer+1)*layer/2
|
|
current := buffer[layerOffset : layerOffset+layer]
|
|
bottom := buffer[layerOffset-layer-1 : layerOffset]
|
|
|
|
nextLayer, nextOffset := layer, offset+1
|
|
if nextOffset == layer {
|
|
nextLayer, nextOffset = layer-1, 0
|
|
}
|
|
if current[offset] != 0 { // skip
|
|
return canBuild(buffer, nextLayer, nextOffset, allowed)
|
|
}
|
|
|
|
choices := allowed[Bottom{bottom[offset], bottom[offset+1]}]
|
|
if len(choices) == 0 {
|
|
return false
|
|
}
|
|
if layer == 1 {
|
|
return true
|
|
}
|
|
|
|
next := buffer[layerOffset+layer:]
|
|
for _, c := range choices {
|
|
current[offset] = c
|
|
if offset > 0 {
|
|
next[offset-1] = 0 // needs recalculate
|
|
}
|
|
if offset < layer-1 {
|
|
next[offset] = 0
|
|
}
|
|
|
|
if canBuild(buffer, nextLayer, nextOffset, allowed) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func pyramidTransition(bottom string, allowed []string) bool {
|
|
allowedIdx := map[Bottom][]byte{}
|
|
for i := range allowed {
|
|
k := [2]byte{allowed[i][0], allowed[i][1]}
|
|
allowedIdx[k] = append(allowedIdx[k], allowed[i][2])
|
|
}
|
|
buffer := make([]byte, (len(bottom)+1)*len(bottom)/2)
|
|
copy(buffer, []byte(bottom))
|
|
|
|
return canBuild(buffer, len(bottom)-1, 0, allowedIdx)
|
|
}
|
|
|
|
var _ = pyramidTransition
|