code.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. "sort"
  8. )
  9. type Object struct {
  10. xMin, yMin, zMin int
  11. xMax, yMax, zMax int
  12. zRealMin, zRealMax int
  13. supports []*Object
  14. standsOn []*Object
  15. }
  16. func readInput(file *os.File) []Object {
  17. scanner := bufio.NewScanner(file)
  18. var objects []Object
  19. for scanner.Scan() {
  20. line := scanner.Text()
  21. if line == "" {
  22. break
  23. }
  24. var object Object
  25. n, err := fmt.Sscanf(line, "%d,%d,%d~%d,%d,%d", &object.xMin, &object.yMin, &object.zMin, &object.xMax, &object.yMax, &object.zMax)
  26. if n != 6 || err != nil {
  27. log.Fatalf("Bad input: %s\n%s", line, err)
  28. }
  29. objects = append(objects, object)
  30. }
  31. return objects
  32. }
  33. func intersect(a, b Object) bool {
  34. return a.xMin <= b.xMax && a.xMax >= b.xMin && a.yMin <= b.yMax && a.yMax >= b.yMin
  35. }
  36. func process(objects []Object) {
  37. sort.Slice(objects, func(i, j int) bool { return objects[i].zMin < objects[j].zMin })
  38. endsAt := make(map[int][]*Object)
  39. for i := range objects {
  40. stable := false
  41. for z := objects[i].zMin - 1; z > 0; z-- {
  42. below := endsAt[z]
  43. for j := range below {
  44. if intersect(objects[i], *below[j]) {
  45. objects[i].zRealMin = z + 1
  46. objects[i].zRealMax = objects[i].zRealMin + (objects[i].zMax - objects[i].zMin)
  47. objects[i].standsOn = append(objects[i].standsOn, below[j])
  48. below[j].supports = append(below[j].supports, &objects[i])
  49. if !stable {
  50. endsAt[objects[i].zRealMax] = append(endsAt[objects[i].zRealMax], &objects[i])
  51. }
  52. stable = true
  53. }
  54. }
  55. if stable {
  56. break
  57. }
  58. }
  59. if !stable {
  60. objects[i].zRealMin = 1
  61. objects[i].zRealMax = objects[i].zRealMin + (objects[i].zMax - objects[i].zMin)
  62. endsAt[objects[i].zRealMax] = append(endsAt[objects[i].zRealMax], &objects[i])
  63. }
  64. }
  65. }
  66. func part1(objects []Object) int {
  67. var result int
  68. process(objects)
  69. fmt.Println(objects)
  70. return result
  71. }
  72. func main() {
  73. if len(os.Args) < 2 {
  74. log.Fatal("You need to specify a file!")
  75. }
  76. filePath := os.Args[1]
  77. file, err := os.Open(filePath)
  78. if err != nil {
  79. log.Fatalf("Failed to open %s!\n", filePath)
  80. }
  81. objects := readInput(file)
  82. fmt.Println("Part1:", part1(objects))
  83. }