remove debugging and failed trials

This commit is contained in:
2024-12-20 12:29:29 -08:00
parent 321540d1c1
commit 20c02557bd

View File

@@ -3,72 +3,18 @@ import Foundation
struct Coord : Hashable, CustomStringConvertible {
let (x, y): (Int, Int)
var description: String { return "(\(x), \(y))" }
func dist(to: Coord) -> Int { return abs(x - to.x) + abs(y - to.y) }
}
struct Queue<T> {
var arr: [T?]
var front: Int = 0
var back: Int = 0
init(size: Int) {
arr = Array(repeating: nil, count: size)
}
mutating func push(_ element: T) {
arr[back] = element
back += 1
}
mutating func pop() -> T? {
if front < back {
front += 1
return arr[front-1]
}
return nil
}
}
struct Maze : CustomStringConvertible {
struct Maze {
let (w, h): (Int, Int)
let walls: Set<Coord>
let (start, end): (Coord, Coord)
let cheatMax: Int
var description: String {
var s = Array(repeating: Array(repeating: " ", count: w), count: h)
walls.forEach { wall in
s[wall.y][wall.x] = "██"
}
path.forEach { cell, cost in
s[cell.y][cell.x] = String(format: "%2d", cost%100)
}
let hdr = " " + (0..<w).map { " \($0 % 10)" }.joined() + "\n"
return hdr +
s.enumerated().map { i, c in
String(format: "%2d ", i) + c.joined() + "\n"
}.joined() + "\(start), \(end)"
}
var path: [Coord: Int] {
var cost: [Coord: Int] = [start: 0]
var cell = start
var prev = start
var currentCost = 0
while cell != end {
let next = neighbors(of: cell)
.filter(isPath)
.filter { $0 != prev }[0]
currentCost += 1
cost[next] = currentCost
prev = cell
cell = next
}
return cost
}
func valid(_ cell: Coord) -> Bool {
return cell.x >= 0 && cell.x < w && cell.y >= 0 && cell.y < h
}
func isPath(_ cell: Coord) -> Bool {
return !walls.contains(cell)
}
func isWall(_ cell: Coord) -> Bool {
return walls.contains(cell)
return cell.x >= 0 && cell.x < w && cell.y >= 0 && cell.y < h &&
!walls.contains(cell)
}
func neighbors(of cell: Coord) -> [Coord] {
@@ -76,49 +22,20 @@ struct Maze : CustomStringConvertible {
.map { Coord(x: cell.x + $0, y: cell.y + $1) }.filter(valid)
}
/*
func cheats(from entryCell: Coord) -> [Coord: Int] {
var q = Queue<(Coord, Int)>(size: cheatMax*cheatMax*2*2)
q.push((entryCell, 0))
var seen: Set<Coord> = [entryCell]
var jumps: [Coord: Int] = [:]
while let (cell, dist) = q.pop() {
neighbors(of: cell).filter { !seen.contains($0) }.forEach { nb in
seen.insert(nb)
if isPath(nb) {
if dist + 1 <= cheatMax {
//print("\(cell) -> \(nb) . \(dist + 1)")
jumps[nb] = min(jumps[nb] ?? Int.max, dist + 1)
}
} else if dist < cheatMax {
//print("\(cell) -> \(nb) # \(dist + 1)")
q.push((nb, dist + 1))
}
}
}
return jumps
}
*/
func cheats(from entry: Coord) -> [Coord: Int] {
let jumpList: [(Int, Int)] = (2...cheatMax).flatMap { dist in
(0..<dist).flatMap { d in
let asdf: [(Int, Int)] = [
(d, dist-d), (dist-d, -d), (-d, d-dist), (d-dist, d)
]
return asdf
return Dictionary(uniqueKeysWithValues: (2...cheatMax)
.flatMap { dist -> [(Int, Int)] in
(0..<dist).flatMap { d -> [(Int, Int)] in
[(d, dist-d), (dist-d, -d), (-d, d-dist), (d-dist, d)]
}
}
let jumpCoords: [Coord] = jumpList
.map { dx, dy in Coord(x: entry.x + dx, y: entry.y + dy) }
.filter(valid).filter(isPath)
var res: [Coord: Int] = [:]
jumpCoords.forEach { end in
res[end] = abs(end.x - entry.x) + abs(end.y - entry.y)
}
return res
.map { dx, dy -> Coord in Coord(x: entry.x + dx, y: entry.y + dy) }
.filter(valid)
.map { end -> (Coord, Int) in (end, entry.dist(to: end)) }
)
}
func cheats() -> [(Coord, Coord, Int, Int)] {
func cheats() -> [Int] {
var cost: [Coord: Int] = [start: 0]
var jumps: [(Coord, Coord, Int)] = []
var cell = start
@@ -131,16 +48,13 @@ struct Maze : CustomStringConvertible {
.map { dest, dist in (cell, dest, dist) }
jumps.append(contentsOf: newCheats)
// add cost to table
let next = neighbors(of: cell)
.filter(isPath)
.filter { $0 != prev }[0]
let next = neighbors(of: cell).filter { $0 != prev }[0]
currentCost += 1
cost[next] = currentCost
prev = cell
cell = next
//print("looking at \(cell) \(cost[cell]!)")
}
return jumps.map { from, to, dist in (from, to, cost[to]! - cost[from]! - dist, dist) }
return jumps.map { from, to, dist in cost[to]! - cost[from]! - dist }
}
}
@@ -168,19 +82,5 @@ func readInput(_ filePath: String, _ cheatMax: Int) throws -> Maze {
}
let maze = try readInput(CommandLine.arguments[1], Int(CommandLine.arguments[2])!)
print(maze)
// print(maze.cheats(from: maze.start))
let cheats = maze.cheats().filter { _, _, saving, _ in saving > 0 }
let hist = cheats.reduce(into: [:]) { n, t in n[t.2, default: 0] += 1 }
hist.keys.sorted().forEach { print("\(hist[$0]!) - \($0)") }
print(cheats.filter { $0.2 >= 100 }.count)
/*
cheats
.filter { _, _, saving, _ in saving == 72 }
.forEach { from, to, save, dist in
print("\(path[from]!) -> \(path[to]!) = \(dist)(\(save))")
}
print()
*/
print(maze.cheats().filter { $0 >= 100 }.count)