Last active
August 29, 2015 14:25
-
-
Save itarato/41432e42e8c7126f1c55 to your computer and use it in GitHub Desktop.
Challenge 224 intermediate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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