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