-
Notifications
You must be signed in to change notification settings - Fork 0
/
crt_two.go
114 lines (95 loc) · 2.57 KB
/
crt_two.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// ___ _ __ ___ _ ___
// | \ __ _ _ _ / |/ \ | _ \__ _ _ _| |_ |_ )
// | |) / _` | || | | | () | | _/ _` | '_| _| / /
// |___/\__,_|\_, | |_|\__/ |_| \__,_|_| \__| /___|
// |__/
//
// "Cathode-Ray Tube"
//
// Instead of determining the signal strength (cycle number * register value)
// at specific cycle numbers, use the instructions and the same processing
// pattern to determine the image that is being drawn. The register value is the
// horizontal position of a three-pixel-wide sprite. If the cycle number is part
// of the [r-1, r, r+1] set, the pixel (cycle #) "illuminates." Each row is 40
// pixels wide, 6 rows --> 240 cycles.
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
const filename string = "input.txt"
func main() {
file, err := os.Open(filename)
if err != nil { panic(err) }
defer file.Close()
scanner := bufio.NewScanner(file)
register := 1 // Current "addx" value
i := 1 // Current cycle
window := []int{0} // List of what we're gonna have to add
screen := make([]bool, 240) // Cycle 1 draws Pixel 0!
for scanner.Scan() {
line := scanner.Text()
// Cycle starts with reading the line and queueing the instruction
if string(line[0:4]) == "noop" {
window = append(window, 0)
} else if string(line[0:4]) == "addx" {
n, err := strconv.Atoi(string(line[5:]))
if err != nil {
panic("Error parsing number")
}
window = append(window, n, 0)
}
// Then "DURING" the cycle (before anything is added), CRT draws the pixel.
screen[i - 1] = sprite((i - 1) % 40, register) // Cycle 1 draws Pixel 0!
// Cycle ends by applying the next addx (or noop skip) instruction
register += window[0]
window = window[1:]
i += 1
}
// Do the runout.
for j, _ := range window {
// Stop when we're out of pixels.
if i >= 240 {
break
}
screen[i - 1] = sprite((i - 1) % 40, register)
register += window[j]
i += 1
}
// Part Two:
// #### ## #### # # #### ## # ###
// # # # # # # # # # # # #
// ### # # # # # # # # # #
// # # # # # # #### # ###
// # # # # # # # # # # # #
// #### ## #### ## #### # # #### # #
television(screen)
}
func sprite(n int, r int) bool {
if r - 1 <= n && n <= r + 1 {
return true
}
return false
}
func pixel(n int, r int) string {
if sprite(n, r) {
return "#"
} else {
return " "
}
}
func television(s []bool) {
width := 40
for i, v := range s {
if v {
fmt.Printf("#")
} else {
fmt.Printf(" ")
}
if (i + 1) % width == 0 {
fmt.Printf("\n")
}
}
}