Skip to content

Instantly share code, notes, and snippets.

@mrnkr
Created December 5, 2018 18:18
Show Gist options
  • Save mrnkr/9d84139b4f09a4156d48429dd66eb155 to your computer and use it in GitHub Desktop.
Save mrnkr/9d84139b4f09a4156d48429dd66eb155 to your computer and use it in GitHub Desktop.
Backtracking/Dynamic Programming exercise - Find out the minimum number of throws needed to know which floor to throw a marker from in order to know whether it breaks
import Foundation
func max(a: Int, b: Int) -> Int {
return a > b ? a : b
}
// Assume this one works just fine, since I copied it
func pedritoBt(markers: Int, floors: Int) -> Int {
if floors <= 1 {
return floors
} else if markers == 1 {
return floors
} else {
var min = 999999
for i in 1...floors {
let breaks = pedritoBt(markers: markers - 1, floors: i - 1)
let doesntBreak = pedritoBt(markers: markers, floors: floors - i)
let maxCant = 1 + max(breaks, doesntBreak)
if min > maxCant {
min = maxCant
}
}
return min
}
}
// Will fail 4 times in the first 100 data sets
func pedritoDynamic(markers: Int, floors: Int) -> Int {
var res: [[Int]] = Array.init(repeating: Array.init(repeating: 0, count: floors + 1), count: markers + 1)
for m in 1...markers {
for f in 1...floors {
if m == 1 && f > 0 {
res[m][f] = f
} else if m > 1 && f > 0 {
res[m][f] = 1 + res[m-1][Int(floor(Double(f/2)))]
} else {
res[m][f] = 0
}
}
}
return res[markers][floors]
}
// Will not fail
func pedritoDynamicByDani(markers: Int, floors: Int) -> Int {
var res: [[Int]] = Array.init(repeating: Array.init(repeating: 0, count: floors + 1), count: markers + 1)
for m in 1...markers {
for f in 1...floors {
if m == 1 && f > 0 {
res[m][f] = f
} else if m > 1 && f > 0 {
var min = 999999
for i in 1...f {
let breaks = res[m-1][i-1]
let doesntBreak = res[m][f-i]
let maxCant = 1 + max(breaks, doesntBreak)
if min > maxCant {
min = maxCant
}
}
res[m][f] = min
} else {
res[m][f] = 0
}
}
}
return res[markers][floors]
}
var errors = 0
// Compare the backtracking solution with the Dynamic programming solution
// Backtracking works like a charm
for m in 1...10 {
for f in 1...10 {
let bt = pedritoBt(markers: m, floors: f)
let dyna = pedritoDynamicByDani(markers: m, floors: f)
if bt != dyna {
errors = errors + 1
}
}
}
print("Errors: \(errors)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment