Advertisement
Guest User

Untitled

a guest
Dec 5th, 2021
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 2.00 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4.     "fmt"
  5.     "math"
  6. )
  7.  
  8. type Point struct {
  9.     X int
  10.     Y int
  11. }
  12.  
  13. func (p Point) String() string {
  14.     return fmt.Sprintf("[%d,%d]", p.X, p.Y)
  15. }
  16.  
  17. type Route struct {
  18.     From Point
  19.     To   Point
  20. }
  21.  
  22. func (r Route) Diagonal() bool {
  23.     return math.Abs(float64(r.From.X)-float64(r.To.X)) == math.Abs(float64(r.From.Y)-float64(r.To.Y))
  24. }
  25.  
  26. func (r Route) Draw() []Point {
  27.     f := func(i int, j int) (min int, max int) {
  28.         if i > j {
  29.             return j, i
  30.         }
  31.         return i, j
  32.     }
  33.     p := make([]Point, 0)
  34.     // horizontal
  35.     if r.From.Y == r.To.Y {
  36.         min, max := f(r.From.X, r.To.X) //direction doesn't matter
  37.         for i := min; i <= max; i++ {
  38.             p = append(p, Point{i, r.From.Y})
  39.         }
  40.     }
  41.     // vertical
  42.     if r.From.X == r.To.X {
  43.         min, max := f(r.From.Y, r.To.Y) //direction doesn't matter
  44.         for i := min; i <= max; i++ {
  45.             p = append(p, Point{r.From.X, i})
  46.         }
  47.     }
  48.     // diagonal
  49.     if r.Diagonal() {
  50.         // there are 4 cases, 4 diagonal.
  51.         // always start from the lower x, direction doesn't matter
  52.         // and simplify the cases to 2
  53.         if r.From.X > r.To.X {
  54.             r.From, r.To = r.To, r.From
  55.         }
  56.         for i := 0; i <= r.To.X-r.From.X; i++ {
  57.             if r.From.Y > r.To.Y {
  58.                 p = append(p, Point{r.From.X + i, r.From.Y - i})
  59.             } else {
  60.                 p = append(p, Point{r.From.X + i, r.From.Y + i})
  61.             }
  62.         }
  63.     }
  64.     return p
  65. }
  66.  
  67. func PartOne(values []Route) int {
  68.     m := make(map[string]int)
  69.     for _, v := range values {
  70.         if v.Diagonal() {
  71.             continue
  72.         }
  73.         points := v.Draw()
  74.         for _, p := range points {
  75.             if _, ok := m[p.String()]; ok {
  76.                 m[p.String()]++
  77.                 continue
  78.             }
  79.             m[p.String()] = 1
  80.         }
  81.     }
  82.     for k, v := range m {
  83.         if v == 1 {
  84.             delete(m, k)
  85.         }
  86.     }
  87.     return len(m)
  88. }
  89.  
  90. func PartTwo(values []Route) int {
  91.     m := make(map[string]int)
  92.     for _, v := range values {
  93.         points := v.Draw()
  94.         for _, p := range points {
  95.             if _, ok := m[p.String()]; ok {
  96.                 m[p.String()]++
  97.                 continue
  98.             }
  99.             m[p.String()] = 1
  100.         }
  101.     }
  102.     for k, v := range m {
  103.         if v == 1 {
  104.             delete(m, k)
  105.         }
  106.     }
  107.     return len(m)
  108. }
  109.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement