2018 day 10 done
This commit is contained in:
173
2018/day10/day10.go
Normal file
173
2018/day10/day10.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
MaxInt = int(^uint(0) >> 1)
|
||||
MinInt = -MaxInt - 1
|
||||
ClearScreen = "\033[H\033[2J"
|
||||
)
|
||||
|
||||
var sky *Sky
|
||||
|
||||
func main() {
|
||||
inp := StdinToStringSlice()
|
||||
buildSky(inp)
|
||||
part1()
|
||||
}
|
||||
|
||||
func buildSky(inp []string) {
|
||||
sky = &Sky{
|
||||
minPos: Pos{x: MaxInt, y: MaxInt},
|
||||
maxPos: Pos{x: MinInt, y: MinInt},
|
||||
}
|
||||
for _, v := range inp {
|
||||
sky.addStar(v)
|
||||
}
|
||||
}
|
||||
|
||||
func part1() {
|
||||
for i := 1; i < 100000; i++ {
|
||||
sky.tick()
|
||||
if sky.maxPos.y-sky.minPos.y <= 10 {
|
||||
sky.printSky()
|
||||
fmt.Println("Seconds:", i)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Sky struct {
|
||||
stars []*Star
|
||||
minPos, maxPos Pos
|
||||
}
|
||||
|
||||
func (s *Sky) tick() {
|
||||
s.setMinPosX(MaxInt)
|
||||
s.setMinPosY(MaxInt)
|
||||
s.setMaxPosX(MinInt)
|
||||
s.setMaxPosY(MinInt)
|
||||
for _, v := range s.stars {
|
||||
v.tick()
|
||||
s.considerStar(v)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Sky) considerStar(v *Star) {
|
||||
if v.position.x < s.minPos.x {
|
||||
s.setMinPosX(v.position.x)
|
||||
}
|
||||
if v.position.y < s.minPos.y {
|
||||
s.setMinPosY(v.position.y)
|
||||
}
|
||||
if v.position.x > s.maxPos.x {
|
||||
s.setMaxPosX(v.position.x)
|
||||
}
|
||||
if v.position.y > s.maxPos.y {
|
||||
s.setMaxPosY(v.position.y)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Sky) starAt(p *Pos) bool {
|
||||
for _, v := range s.stars {
|
||||
if p.equals(v.position) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Sky) printSky() {
|
||||
for i := s.minPos.y; i <= s.maxPos.y; i++ {
|
||||
for j := s.minPos.x; j <= s.maxPos.x; j++ {
|
||||
if s.starAt(&Pos{x: j, y: i}) {
|
||||
fmt.Print("*")
|
||||
} else {
|
||||
fmt.Print(" ")
|
||||
}
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Sky) addStar(inp string) {
|
||||
v := NewStar(inp)
|
||||
s.stars = append(s.stars, v)
|
||||
s.considerStar(v)
|
||||
}
|
||||
|
||||
func (s *Sky) setMinPosX(x int) {
|
||||
s.minPos.x = x
|
||||
}
|
||||
func (s *Sky) setMinPosY(y int) {
|
||||
s.minPos.y = y
|
||||
}
|
||||
func (s *Sky) setMaxPosX(x int) {
|
||||
s.maxPos.x = x
|
||||
}
|
||||
func (s *Sky) setMaxPosY(y int) {
|
||||
s.maxPos.y = y
|
||||
}
|
||||
|
||||
type Star struct {
|
||||
position *Pos
|
||||
velocity *Pos
|
||||
}
|
||||
|
||||
func NewStar(inp string) *Star {
|
||||
inp = inp[10:]
|
||||
pts := strings.Split(inp, ">")
|
||||
posStr := pts[0]
|
||||
velStr := pts[1][11:len(pts[1])]
|
||||
return &Star{
|
||||
position: NewPos(posStr),
|
||||
velocity: NewPos(velStr),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Star) tick() {
|
||||
s.position.x += s.velocity.x
|
||||
s.position.y += s.velocity.y
|
||||
}
|
||||
|
||||
type Pos struct {
|
||||
x, y int
|
||||
}
|
||||
|
||||
func NewPos(inp string) *Pos {
|
||||
pts := strings.Split(inp, ", ")
|
||||
return &Pos{
|
||||
x: Atoi(strings.TrimSpace(pts[0])),
|
||||
y: Atoi(strings.TrimSpace(pts[1])),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pos) equals(o *Pos) bool {
|
||||
return p.x == o.x && p.y == o.y
|
||||
}
|
||||
|
||||
func StdinToStringSlice() []string {
|
||||
var input []string
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for scanner.Scan() {
|
||||
input = append(input, scanner.Text())
|
||||
}
|
||||
return input
|
||||
}
|
||||
|
||||
func Atoi(i string) int {
|
||||
var ret int
|
||||
var err error
|
||||
if ret, err = strconv.Atoi(i); err != nil {
|
||||
fmt.Println(err.Error())
|
||||
log.Fatal("Invalid Atoi" + i)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
Reference in New Issue
Block a user