Skip to content

Instantly share code, notes, and snippets.

@itarato
Last active August 29, 2015 14:25
Show Gist options
  • Select an option

  • Save itarato/41432e42e8c7126f1c55 to your computer and use it in GitHub Desktop.

Select an option

Save itarato/41432e42e8c7126f1c55 to your computer and use it in GitHub Desktop.
Challenge 224 intermediate
package main
import (
"bytes"
"io/ioutil"
"log"
)
func temp(...interface{}) {}
const (
PLUS = 43
HORIZONTAL = 45
VERTICAL = 124
)
type Point []int
type Alg struct {
lines []string
height int
width int
}
func NewAlg(lines []string) *Alg {
alg := &Alg{lines: lines}
alg.height = len(lines)
alg.width = len(lines[0])
return alg
}
func (alg *Alg) findTopLeftCorners() {
total := 0
for lineIdx, line := range alg.lines {
for charIdx, char := range line {
if alg.isTopLeftCorner(lineIdx, charIdx, char) {
downs := alg.getDownNeighbours(lineIdx, charIdx)
rights := alg.getRightNeighbours(lineIdx, charIdx)
for _, down := range downs {
for _, right := range rights {
if alg.isClosed(down, right) {
total += 1
}
}
}
}
}
}
log.Printf("Total: %d\n", total)
}
func (alg *Alg) at(y, x int) rune {
return rune(alg.lines[y][x])
}
func (alg *Alg) isTopLeftCorner(lineIdx, charIdx int, char rune) bool {
if char != PLUS || lineIdx >= alg.height-1 || charIdx >= alg.width-1 {
return false
}
right := alg.at(lineIdx, charIdx+1)
down := alg.at(lineIdx+1, charIdx)
return (down == VERTICAL || down == PLUS) &&
(right == HORIZONTAL || right == PLUS)
}
func (alg *Alg) getDownNeighbours(lineIdx, charIdx int) []Point {
return alg.getNeighbours(lineIdx, charIdx, lineIdx, alg.height, VERTICAL)
}
func (alg *Alg) getRightNeighbours(lineIdx, charIdx int) []Point {
return alg.getNeighbours(lineIdx, charIdx, charIdx, alg.width, HORIZONTAL)
}
func (alg *Alg) getNeighbours(lineIdx, charIdx, from, to int, bridge rune) []Point {
var points []Point
var current rune
for i := from + 1; i < to; i++ {
if bridge == VERTICAL {
current = alg.at(i, charIdx)
} else {
current = alg.at(lineIdx, i)
}
if current == PLUS {
if bridge == VERTICAL {
points = append(points, []int{i, charIdx})
} else {
points = append(points, []int{lineIdx, i})
}
} else if current != bridge {
break
}
}
return points
}
func (alg *Alg) isClosed(down, right Point) bool {
if alg.at(down[0], right[1]) != PLUS {
return false
}
for i := down[1] + 1; i < right[1]; i++ {
current := alg.at(down[0], i)
if current != PLUS && current != HORIZONTAL {
return false
}
}
for i := right[0] + 1; i < down[0]; i++ {
current := alg.at(i, right[1])
if current != PLUS && current != VERTICAL {
return false
}
}
return true
}
func main() {
log.Println("CH224")
b, _ := ioutil.ReadFile("boxes")
buff := bytes.NewBuffer(b)
var lines []string
for {
b, err := buff.ReadBytes('\n')
lines = append(lines, string(b))
if err != nil {
break
}
}
alg := NewAlg(lines)
alg.findTopLeftCorners()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment