import "aoc" for AoC class Pos { construct new() { _x = 0 _y = 0 } x { _x } y { _y } touches(other) { var dx = (_x - other.x).abs var dy = (_y - other.y).abs return dx <= 1 && dy <= 1 } static movement(h, t) { if(h.touches(t)) { return "" } var dx = h.x - t.x var dy = h.y - t.y if(dx < 0 && dy < 0) { return "LD" } if(dx < 0 && dy > 0) { return "LU" } if(dx > 0 && dy < 0) { return "RD" } if(dx > 0 && dy > 0) { return "RU" } if(dx < 0 ) { return "L" } if(dx > 0 ) { return "R" } if(dy < 0 ) { return "D" } if(dy > 0 ) { return "U" } } u() { _y = _y + 1 } d() { _y = _y - 1 } l() { _x = _x - 1 } r() { _x = _x + 1 } move(direction) { for(c in direction) { if(c == "U") this.u() if(c == "D") this.d() if(c == "L") this.l() if(c == "R") this.r() } } xy { _x.toString + "," + _y.toString } } var h = Pos.new() var t = Pos.new() var rope = [] for(i in 0...10) { rope.add(Pos.new()) } var seen_p1 = {} var seen_p2 = {} for(line in AoC.input.split("\n").where {|l| l != ""}) { var split = line.split(" ") var direction = split[0] var count = Num.fromString(split[1]) for(i in 0...count) { h.move(direction) t.move(Pos.movement(h, t)) seen_p1[t.xy] = true rope[0].move(direction) for(i in 1...10) { rope[i].move(Pos.movement(rope[i-1], rope[i])) } seen_p2[rope[9].xy] = true } } System.print(seen_p1.count) System.print(seen_p2.count)