Last active
December 5, 2018 18:54
-
-
Save mrnkr/1f1db7073334eaffb3b5b17485554616 to your computer and use it in GitHub Desktop.
Backtracking exercise - You just got home and it's late, get to your bedroom making as little noise as humanly possible (alla home invasion in GTA SA)
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
import Foundation | |
func calcNoise(standingOn: Character) -> Int { | |
switch standingOn { | |
case "A": | |
return 1 | |
case "S": | |
return 3 | |
case "H": | |
return 5 | |
default: | |
return -1 | |
} | |
} | |
func adjacentPositions(house: [[Character]], visited: [[Bool]], current: [Int]) -> [[Int]] { | |
var ret: [[Int]] = [] | |
for i in -1...1 { | |
if abs(i) > 0 { | |
if current[0] + i >= 0 && current[0] + i < house.count { | |
if !visited[current[0] + i][current[1]] { | |
ret.append([current[0] + i, current[1]]) | |
} | |
} | |
if current[1] + i >= 0 && current[1] + i < house.count { | |
if !visited[current[0]][current[1] + i] { | |
ret.append([current[0], current[1] + i]) | |
} | |
} | |
} | |
} | |
return ret | |
} | |
func malaMiaDisculpame(house: [[Character]], current: [Int], bedroomDoor: [Int], maxNoise: Int, curSolution: [[Int]], curNoise: Int, optimSolution: inout [[Int]], optimNoise: inout Int, vis: [[Bool]]) { | |
var sol = curSolution | |
sol.append(current) | |
let noise = curNoise + calcNoise(standingOn: house[current[0]][current[1]]) | |
var visited = vis | |
visited[current[0]][current[1]] = true | |
if current == bedroomDoor { | |
// Potential solution right here | |
if noise < optimNoise { | |
// Better solution | |
optimSolution = sol | |
optimNoise = noise | |
} | |
} else { | |
let adjacent = adjacentPositions(house: house, visited: visited, current: current) | |
adjacent.forEach { (adj) in | |
let wouldMakeNoise = noise + calcNoise(standingOn: house[adj[0]][adj[1]]) | |
let couldWork = wouldMakeNoise <= maxNoise && wouldMakeNoise <= optimNoise | |
// Only do the recursive call when there can be a solution | |
if couldWork { | |
malaMiaDisculpame(house: house, current: adj, bedroomDoor: bedroomDoor, maxNoise: maxNoise, curSolution: sol, curNoise: noise, optimSolution: &optimSolution, optimNoise: &optimNoise, vis: visited) | |
} | |
} | |
} | |
} | |
// Different characters represent different things | |
// If you step on an A you are stepping on the carpet - making noise of level 1 | |
// If you step on an S you are stepping on a rattle - making noise of level 3 | |
// If you step on an H you are stepping on a rubber duck - making noise of level 5 | |
// You cannot step on a P since it is the wall | |
let house: [[Character]] = [["A", "A", "A", "A", "A", "P", "A"], | |
["A", "A", "A", "A", "A", "P", "A"], | |
["P", "P", "P", "P", "A", "A", "A"], | |
["A", "A", "A", "A", "A", "A", "A"], | |
["A", "S", "S", "S", "S", "S", "H"], | |
["A", "A", "A", "A", "A", "A", "A"], | |
["A", "A", "A", "A", "A", "A", "A"]] | |
var vis: [[Bool]] = Array.init(repeating: Array.init(repeating: false, count: 7), count: 7) | |
// Make sure the walls are a no-go | |
for i in 0...house.count-1 { | |
for j in 0...house[i].count-1 { | |
if house[i][j] == "P" { | |
vis[i][j] = true | |
} | |
} | |
} | |
var optimSolution: [[Int]] = [] | |
var optimNoise: Int = 999999 | |
malaMiaDisculpame(house: house, current: [5,6], bedroomDoor: [1,0], maxNoise: 20, curSolution: [], curNoise: 0, optimSolution: &optimSolution, optimNoise: &optimNoise, vis: vis) | |
print(optimNoise) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment