Created
March 30, 2020 03:05
-
-
Save samisuteria/e229ae7c4cf3396162295f35cc85da91 to your computer and use it in GitHub Desktop.
This file contains 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
import Foundation | |
struct Point: Equatable, CustomStringConvertible { | |
let x: Int | |
let y: Int | |
init(_ x: Int, _ y: Int) { | |
self.x = x | |
self.y = y | |
} | |
var description: String { "(\(x), \(y))" } | |
static func + (_ lhs: Point, _ rhs: Point) -> Point { | |
Point(lhs.x + rhs.x, lhs.y + rhs.y) | |
} | |
static func - (_ lhs: Point, _ rhs: Point) -> Point { | |
Point(lhs.x - rhs.x, lhs.y - rhs.y) | |
} | |
static var zero: Point { Point(0,0) } | |
} | |
enum Direction: String { | |
case N, S, E, W, NE, NW, SE, SW | |
var delta: Point { | |
switch self { | |
case .N: return Point(0, 1) | |
case .S: return Point(0, -1) | |
case .E: return Point(1, 0) | |
case .W: return Point(-1, 0) | |
case .NE: return Direction.N.delta + Direction.E.delta | |
case .NW: return Direction.N.delta + Direction.W.delta | |
case .SE: return Direction.S.delta + Direction.E.delta | |
case .SW: return Direction.S.delta + Direction.W.delta | |
} | |
} | |
} | |
struct Rule: CustomStringConvertible { | |
let destination: String | |
let direction: Direction | |
let source: String | |
init?(string: String) { | |
let values = string | |
.split(separator: " ") | |
.map { String($0) } | |
guard | |
values.count == 3, | |
let parsedDirection = Direction(rawValue: values[1]) | |
else { return nil } | |
self.destination = values[0] | |
self.direction = parsedDirection | |
self.source = values[2] | |
} | |
var description: String { "\(destination) \(direction) \(source)" } | |
} | |
//let input = """ | |
//A NW B | |
//A N B | |
//""" | |
let input = """ | |
A N B | |
B NE C | |
C N A | |
""" | |
func isValidRules(input: String) -> Bool { | |
let parsedRules: [Rule] = input | |
.split(separator: "\n") | |
.map { String($0) } | |
.compactMap { Rule(string: $0) } | |
var pointsOnMap = Set<String>() | |
var locationsOfPoints = Dictionary<String, Point>() | |
var isValid = true | |
for rule in parsedRules { | |
print(rule) | |
switch (pointsOnMap.contains(rule.source), pointsOnMap.contains(rule.destination)) { | |
case (false, false): | |
print("neither point is on map, adding them") | |
pointsOnMap.insert(rule.source) | |
locationsOfPoints[rule.source] = .zero | |
pointsOnMap.insert(rule.destination) | |
locationsOfPoints[rule.destination] = .zero + rule.direction.delta | |
case (true, false): | |
if let sourcePoint = locationsOfPoints[rule.source] { | |
print("source on map, adding destination") | |
pointsOnMap.insert(rule.destination) | |
locationsOfPoints[rule.destination] = sourcePoint + rule.direction.delta | |
} | |
case (false, true): | |
if let destinationPoint = locationsOfPoints[rule.destination] { | |
print("destination on map, adding source by inverting direction") | |
pointsOnMap.insert(rule.source) | |
locationsOfPoints[rule.source] = destinationPoint - rule.direction.delta | |
} | |
case (true, true): | |
print("both points already on map, going to rules check") | |
} | |
print(pointsOnMap) | |
print(locationsOfPoints) | |
guard | |
let sourcePoint = locationsOfPoints[rule.source], | |
let destinationPoint = locationsOfPoints[rule.destination] | |
else { continue } | |
switch rule.direction { | |
case .N, .S: | |
if sourcePoint.y + rule.direction.delta.y != destinationPoint.y { | |
isValid = false | |
} | |
case .E, .W: | |
if sourcePoint.x + rule.direction.delta.x != destinationPoint.x { | |
isValid = false | |
} | |
default: | |
if sourcePoint + rule.direction.delta != destinationPoint { | |
isValid = false | |
} | |
} | |
print("valid: \(isValid)") | |
} | |
return isValid | |
} | |
isValidRules(input: input) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment