瀏覽代碼

Solved part2

Piotr Czajkowski 1 年之前
父節點
當前提交
bfc7e64d46
共有 1 個文件被更改,包括 103 次插入0 次删除
  1. 103 0
      03/code.go

+ 103 - 0
03/code.go

@@ -114,6 +114,108 @@ func part1(lines []string) int {
 	return result
 }
 
+type Point struct {
+	x, y int
+}
+
+func digitsFromLine(line string, start int, end int, y int) []Point {
+	var points []Point
+	reading := false
+	for i := start; i <= end; i++ {
+		if isDigit(line[i]) {
+			if !reading {
+				points = append(points, Point{x: i, y: y})
+				reading = true
+			}
+		} else {
+			reading = false
+		}
+	}
+
+	return points
+}
+
+func getDigits(lines []string, height int, width int, y int, x int) []Point {
+	var points []Point
+
+	start := x - 1
+	if start < 0 {
+		start = x
+	}
+
+	end := x + 1
+	if end >= width {
+		end = x
+	}
+
+	if y-1 >= 0 {
+		points = append(points, digitsFromLine(lines[y-1], start, end, y-1)...)
+	}
+
+	if y+1 < height {
+		points = append(points, digitsFromLine(lines[y+1], start, end, y+1)...)
+	}
+
+	points = append(points, digitsFromLine(lines[y], start, end, y)...)
+
+	return points
+}
+
+func numberFromPoint(lines []string, width int, point Point) int {
+	start := point.x
+	end := point.x
+	var haveStart, haveEnd bool
+	for {
+		if haveStart && haveEnd {
+			break
+		}
+
+		if !haveStart && start-1 >= 0 && isDigit(lines[point.y][start-1]) {
+			start--
+		} else {
+			haveStart = true
+		}
+
+		if !haveEnd && end+1 < width && isDigit(lines[point.y][end+1]) {
+			end++
+		} else {
+			haveEnd = true
+		}
+	}
+	end++
+
+	var d int
+	n, err := fmt.Sscanf(lines[point.y][start:end], "%d", &d)
+	if n != 1 || err != nil {
+		log.Fatalf("Wrong input: %s\n%s", lines[point.y][start:end], err)
+	}
+
+	return d
+}
+
+func part2(lines []string) int {
+	height := len(lines)
+	width := len(lines[0])
+	var result int
+	for i := range lines {
+		for j := range lines[i] {
+			if lines[i][j] == '*' {
+				digits := getDigits(lines, height, width, i, j)
+				if len(digits) == 2 {
+					prod := 1
+					for k := range digits {
+						prod *= numberFromPoint(lines, width, digits[k])
+					}
+
+					result += prod
+				}
+			}
+		}
+	}
+
+	return result
+}
+
 func main() {
 	if len(os.Args) < 2 {
 		log.Fatal("You need to specify a file!")
@@ -128,4 +230,5 @@ func main() {
 
 	lines := readInput(file)
 	fmt.Println("Part1:", part1(lines))
+	fmt.Println("Part2:", part2(lines))
 }