Skip to content

Instantly share code, notes, and snippets.

@AvdLee
Last active July 1, 2024 14:07
Show Gist options
  • Save AvdLee/0ff618b7d149be631050994ee8246bff to your computer and use it in GitHub Desktop.
Save AvdLee/0ff618b7d149be631050994ee8246bff to your computer and use it in GitHub Desktop.
KeyTimeValues Coding Challenge
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
]
@KieranConlon
Copy link

If you have a repeating value, then keep the first and last instance of that value.
Not sure if this colour-coded version helps; essentially remove the values within the red boxes.
image

@Loradim
Copy link

Loradim commented Jul 31, 2023

@KieranConlon : Thank you !!

@MasoudRoosta
Copy link

MasoudRoosta commented Aug 1, 2023

@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}

@ipavlidakis
Copy link

import Foundation

final class LinkedList: CustomStringConvertible {
    private final class Node {
        let timing: TimeInterval
        let value: Float
        var next: Node?

        init(timing: TimeInterval, value: Float) {
            self.timing = timing
            self.value = value
        }
    }

    private var head: Node?
    private var tail: Node?

    func append(timing: TimeInterval, value: Float) {
        let newNode = Node(timing: timing, value: value)
        if let tailNode = tail {
            if tailNode.value != newNode.value {
                tailNode.next = newNode
                tail = newNode
            }
        } else {
            head = newNode
            tail = newNode
        }
    }

    var description: String {
        var result = ""
        var current = head
        while let node = current {
            result = result.isEmpty
            ? "[timing:\(node.timing), value:\(node.value)]"
            : "\(result) → [timing:\(node.timing), value:\(node.value)]"
            current = node.next
        }
        return result
    }
}

// Example usage
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
]

var list = LinkedList()

keyTimeValues.sorted { $0.key < $1.key }.forEach { (key: TimeInterval, value: Float) in
    list.append(timing: key, value: value)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment