-
-
Save AvdLee/0ff618b7d149be631050994ee8246bff to your computer and use it in GitHub Desktop.
let keyTimeValues: [TimeInterval: Float] = [ | |
0.4: 0.0, | |
0.45: 1.0, | |
0.475: 1.0, | |
0.5: 1.0, | |
0.525: 1.0, | |
0.55: 0.0, | |
0.575: 1.0, | |
0.6: 1.0, | |
0.65: 1.0, | |
0.7: 0.0 | |
] | |
/// The challenge: | |
/// The keys represent animation key times, the values represent values. Some key times repeat the same value of the previous keytime. | |
/// How would you reduce the above dictionary in such way that the values do not repeat themselves | |
/// more than once? | |
/// For example, this group: | |
/// 0.45: 1.0, | |
/// 0.475: 1.0, | |
/// 0.5: 1.0, | |
/// 0.525: 1.0, | |
/// | |
/// The keytime 0.475 and 0.5 don't change the value and are, therefore, redundant in key frame animations. | |
/// | |
/// Expected outcome: | |
let expectedOutcome: [TimeInterval: Float] = [ | |
0.4: 0.0, | |
0.45: 1.0, | |
0.525: 1.0, | |
0.55: 0.0, | |
0.575: 1.0, | |
0.65: 1.0, | |
0.7: 0.0 | |
] |
Great solutions, all! Thanks a lot for joining the challenge. It's been an experiment for me and looking at the number of solutions submitted, it's definitely worth another challenge in the future.
Next time I'll make sure to provide an actual project together with a suite of tests that should succeed. Stay tuned!
Great stuff @AvdLee ! Even if it takes me ages to solve such challenges, keep those coming 🙂
Here is what I came up with:
/// Reduce repeating values if they occur more than once in a dictionary.
/// - Parameter keyTimeValues: A dictionary of key-time-value pairs.
/// - Returns: A reduced dictionary.
func reduceRepeatingValues(_ keyTimeValues: [TimeInterval : Float]) -> Dictionary<TimeInterval, Float> {
var result: [TimeInterval : Float] = [:]
var previousValue: Float?
var previousKey: TimeInterval?
for key in keyTimeValues.keys.sorted() {
let currentValue = keyTimeValues[key]
// If the previous value has not changed, cache the current key as previousKey and continue with the next key in the loop
if previousValue == currentValue {
previousKey = key
continue
}
// Value has changed: unwrap (because these vars are defined as optional) and add the previous key/value pair to the result
if let pKey = previousKey, let pValue = previousValue {
result[pKey] = pValue
}
// Store the current key/value pair to the result
result[key] = currentValue
// Cache the current key/value pair as the new previous pair
previousKey = key
previousValue = currentValue
}
return result
}
var result = reduceRepeatingValues(keyTimeValues)
assert(result == expectedOutcome, "Oh no, I failed!")
Well done @simonberner 💪🏼
I guess I'm struggling with the example or explanation
let keyTimeValues: [TimeInterval: Float] = [
0.4: 0.0,
0.45: 1.0,
0.475: 1.0,
0.5: 1.0,
0.525: 1.0,
0.55: 0.0,
0.575: 1.0,
0.6: 1.0,
0.65: 1.0,
0.7: 0.0
]
/// Expected outcome:
let expectedOutcome: [TimeInterval: Float] = [
0.4: 0.0,
0.45: 1.0,
0.525: 1.0,
0.55: 0.0,
0.575: 1.0,
0.65: 1.0,
0.7: 0.0
]
Why does 0.475 and 0.5 get removed but not 0.525? It's still repeating a value of 1.0.
I guess I'm missing out on something, would you mind pointing me towards that?
@KieranConlon : Thank you !!
@AvdLee It's my solution:
let keyTimeValues: [TimeInterval: Float] = [
0.4: 0.0,
0.45: 1.0,
0.475: 1.0,
0.5: 1.0,
0.525: 1.0,
0.55: 0.0,
0.575: 1.0,
0.6: 1.0,
0.65: 1.0,
0.7: 0.0
]
extension Dictionary<TimeInterval, Float>{
func optmizedDict() -> Dictionary<TimeInterval, Float>{
var tempElement: Dictionary<TimeInterval, Float>.Element? = nil
return reduce([:]) { partialResult, element in
var partialResult = partialResult
if element.value != tempElement?.value && tempElement != nil {
partialResult[tempElement!.key] = tempElement!.value
partialResult[element.key] = element.value
}
tempElement = element
return partialResult
}
}
}
let result = keyTimeValues.optmizedDict().sorted{$0.0 < $1.0}
Golfed using Swift Algorithms:
(Convert to/from a dictionary as needed, but I think that was probably the incorrect choice of data structure to begin with)