Created
December 5, 2019 17:14
-
-
Save waltflanagan/14c8b4782a1df05f7ca7d35e019a0b03 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var str = "Hello, playground" | |
let wire1 = "R1004,U520,R137,D262,L403,U857,R50,U679,R788,D98,L717,D1,R367,U608,L125,U703,L562,D701,L718,U357,R742,D860,R557,D117,R950,U546,L506,U836,R951,D460,L38,U893,L1,D217,R262,D950,R239,U384,R971,D289,R323,U878,L525,U687,L831,U523,R94,D33,L879,D318,R633,D775,R879,D351,L120,D8,R31,U49,R328,D598,L380,D160,R261,D716,R459,U533,L444,U412,L326,U93,L193,D621,R236,U769,L319,D885,L559,U509,L62,U321,L667,D505,R556,U159,L5,U126,L262,D946,L168,U491,L56,D831,R926,U926,R562,D270,R785,U436,R852,D629,R872,U716,R549,U435,R462,U191,R318,U91,L637,D682,R647,D53,L789,D725,R312,D366,L287,U29,R85,D657,R88,U300,R795,U378,R800,D391,L594,U791,R205,U352,L510,D975,R47,D311,R319,U579,R214,D112,R996,U874,R328,D578,R37,U689,L543,U16,L580,D230,L714,D58,L580,D658,R218,U535,R149,U996,L173,D316,L90,D372,L364,U700,L60,D70,L250,U276,R580,U505,L682,U943,R336,U847,R810,U963,R874,D740,R732,D328,R926,D447,R638,D102,R696,U211,L594,D354,R384,U81,L884,U916,L168,U759,R631,D702,L598,D382,L647,U642,R537,U53,R897,U954,R263,U445,L41,D91,L51,D338,R219,U269,L689,D172,R627,D287,L440,D504,L253,D252,R815,D108,L282,U835,L243,U638,R910,D306,R755,D202,R69,D862,L537,D947,L180,D835,L111,U832,R939,D449,R180,U105,R892,D837,L153,U215,L695,U957,R923,U496,R608,U739,L711,U700,L838,D117,R479,U852,R795,D955,L386,D70,R728,D40,R580,U777,L877,U284,R414,D300,R105,D372,L317,D91,R653,U920,R956,D496,L543,D363,R374,D283,L696,U466,R467,D878,R660,U590,L962,U619,R991,U848,L648,D191,R459,U125,L998,U19,L214,U947,R188,U103,R916" | |
let wire2 = "L1008,U717,R288,D770,R270,U514,R109,D538,L719,U179,R466,D792,R421,U723,L22,U705,L284,U14,L478,U367,R727,U880,R620,D46,R377,U897,L731,U840,L910,D385,L257,U311,L596,D991,L668,D730,L707,D816,R47,U948,R84,D700,R299,U707,R261,D928,R358,D504,R309,U369,R931,U20,L940,U326,L362,D52,R98,D475,L907,D918,R931,D468,R279,D586,R592,U973,R753,D365,R694,U278,R934,U712,R441,U996,L989,D693,L211,D561,R105,D425,R53,U168,L451,U865,L585,D412,L857,U988,R724,U774,R295,U588,R329,D810,L698,D118,R277,U193,R309,U933,R186,D535,R409,U322,L849,U606,R590,U892,L542,D237,R475,D920,R679,U602,L477,D634,L988,D540,L323,U791,L375,U625,L621,U567,L943,U512,L239,D90,L66,U151,R83,U435,R612,D865,L177,U368,R326,U574,L241,U197,R499,U419,R297,U207,L311,D243,L559,D281,R513,U748,L884,U207,R71,D441,R133,D993,L4,D977,L669,U523,L564,U186,R477,U737,L685,U338,L456,U939,R774,U674,L97,D827,R237,D451,R618,D143,R750,U196,L559,D178,L693,D916,R334,U231,L651,U249,R620,U283,L387,U352,L915,U959,L693,U909,R320,U119,L617,U177,L993,D265,R667,U204,R59,D601,L579,U483,R155,D484,L44,D751,R915,U510,L552,U308,R505,U394,R585,U872,L617,U202,R928,U941,R235,U768,R666,D547,L244,D270,R353,D612,R384,U430,L685,D536,R103,U147,R794,D621,L52,U96,L557,D455,L635,D58,R265,U545,R938,D266,L173,U746,L672,D237,R286,U131,R487,U837,R394,D702,R49,U579,L699,U819,L448,D223,L982,D906,L397,U807,L737,D223,L791,D965,R436,U29,R908,D273,R194,U91,R232,U591,L336,D70,R467,U505,L341,U989,R278,U387,L442,U950,R487,D384,L534,D514,L433,U627,R381,U54,L847,U231,L590" | |
let test1 = "R8,U5,L5,D3" | |
let test2 = "U7,R6,D4,L4" | |
struct Point: Hashable { | |
let x: Int | |
let y: Int | |
func distanceFrom(_ other: Point) -> Int { | |
return abs(x - other.x) + abs(y - other.y) | |
} | |
func moveBy(_ direction: Direction) -> Point { | |
print("moved") | |
switch direction { | |
case .up(let amount): | |
return Point(x: x, y: y + amount) | |
case .down(let amount): | |
return Point(x: x, y: y - amount) | |
case .left(let amount): | |
return Point(x: x - amount, y: y ) | |
case .right(let amount): | |
return Point(x: x + amount, y: y ) | |
} | |
} | |
} | |
extension Point: CustomDebugStringConvertible { | |
var debugDescription: String { | |
return "(\(x), \(y))" | |
} | |
} | |
enum Direction { | |
case up(Int) | |
case down(Int) | |
case left(Int) | |
case right(Int) | |
init(_ string: String) { | |
let amount = Int(string.dropFirst())! | |
switch String(string.first!).lowercased() { | |
case "u": | |
self = .up(amount) | |
case "d": | |
self = .down(amount) | |
case "l": | |
self = .left(amount) | |
case "r": | |
self = .right(amount) | |
default: | |
print("oops \(string)") | |
exit(-1) | |
} | |
} | |
var delay: Int { | |
switch self { | |
case .up(let amount): return amount | |
case .down(let amount): return amount | |
case .left(let amount): return amount | |
case .right(let amount): return amount | |
} | |
} | |
} | |
class Wire { | |
struct Segment { | |
let start: Point | |
let end: Point | |
let xRange: ClosedRange<Int> | |
let yRange: ClosedRange<Int> | |
let delay: Int | |
init(start: Point, end: Point, delay: Int) { | |
self.start = start | |
self.end = end | |
let xcomponents = [start.x, end.x] | |
let ycomponents = [start.y, end.y] | |
let xRange = xcomponents.min()!...xcomponents.max()! | |
let yRange = ycomponents.min()!...ycomponents.max()! | |
self.xRange = xRange | |
self.yRange = yRange | |
self.delay = delay | |
} | |
func pointInSegment(_ point: Point) -> Bool { | |
return xRange.contains(point.x) && yRange.contains(point.y) | |
} | |
func intersects(_ other: Segment) -> Bool { | |
return xRange.overlaps(other.xRange) && yRange.overlaps(other.yRange) | |
} | |
func delayForPoint(_ point: Point) -> Int { | |
if xRange.count == 1 { | |
return delay + abs(point.y - start.y) | |
} else { | |
return delay + abs(point.x - start.x) | |
} | |
} | |
func intersection(_ other: Segment) -> Point? { | |
guard intersects(other) else { return nil } | |
var x = 0 | |
var y = 0 | |
if xRange.count == 1 { | |
x = other.xRange.clamped(to: xRange).lowerBound | |
} else { | |
x = xRange.clamped(to: other.xRange).lowerBound | |
} | |
if yRange.count == 1 { | |
y = other.yRange.clamped(to: yRange).lowerBound | |
} else { | |
y = yRange.clamped(to: other.yRange).lowerBound | |
} | |
return Point(x: x, y: y) | |
} | |
} | |
let path: [Segment] | |
init(_ string: String) { | |
var last = Point(x: 0, y: 0) | |
var currentDelay = 0 | |
var path = [Segment]() | |
let directions = string.components(separatedBy: ",") | |
.map { Direction($0) } | |
directions.forEach { (direction) in | |
let newPoint = last.moveBy(direction) | |
let segment = Segment(start: last, end: newPoint, delay: currentDelay) | |
path.append(segment) | |
currentDelay += direction.delay | |
last = newPoint | |
} | |
self.path = path | |
} | |
func intersections(_ other: Wire) -> [Point] { | |
var intersections = [Point]() | |
for segment in path { | |
for otherSegment in other.path { | |
guard let intersection = segment.intersection(otherSegment) else { continue } | |
intersections.append(intersection) | |
} | |
} | |
return intersections | |
} | |
} | |
let one = Wire(wire1) | |
let two = Wire(wire2) | |
//let one = Wire(test1) | |
//let two = Wire(test2) | |
one.path.count | |
two.path.count | |
one.path | |
two.path | |
// | |
//let intersections: [Point] = [Point(x: 563, y: 1953), Point(x: 113, y: 2662), Point(x: 207, y: 0), Point(x: 0, y: 0), Point(x: 1, y: 2662), Point(x: 187, y: 2662), Point(x: 605, y: 0), Point(x: 539, y: 2850), Point(x: 1, y: 2305), Point(x: 539, y: 2689), Point(x: 788, y: 1412), Point(x: 539, y: 2367), Point(x: 563, y: 2367), Point(x: 113, y: 2305)] | |
var steps = [Int]() | |
for intersection in intersections { | |
let oneSegment = one.path.first(where: { $0.pointInSegment(intersection) })?.delayForPoint(intersection) ?? Int.max | |
let twoSegment = two.path.first(where: { $0.pointInSegment(intersection) })?.delayForPoint(intersection) ?? Int.max | |
steps.append(oneSegment + twoSegment) | |
} | |
steps.min() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment