Suppose you have an array of values in your Swift app and you need to compress it to a smaller size, with the intention of making it occupy less memory. If the array contains many consecutive repeated values it could be compressed by only including a repeated value once, and tracking the number of consecutive occurrences for that value.
How might that code work? What about the code to decompress an array, how can that be implemented in Swift?
If you are interested in figuring this out yourself, I posted a gist that you can use as a starting point to test your code:
This file contains 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 | |
/** | |
Returns a compacted array, with repeated values coalesced. | |
Example: [a, a, b, c, c, c] yields [(a, 2), (b, 1), (c, 3)] | |
*/ | |
func compressArray<T: Comparable>(input: [T]) -> [(T, Int)] { | |
// TODO – implement this function | |
return [] | |
} | |
/** | |
Returns the original, expanded form of a compressed array. | |
Example: [(a, 2), (b, 1), (c, 3)] yields [a, a, b, c, c, c] | |
*/ | |
func decompressArray<T>(input: [(T, Int)]) -> [T] { | |
// TODO – implement this function | |
return [] | |
} | |
let uncompressedInts = [ | |
8, 8, 8, | |
2, 2, 2, 2, 2, 2, 2, 2, 2, | |
8, | |
3, | |
5, 5, 5, 5, | |
0, 0, 0, 0, 0, 0, 0, | |
9] | |
let expectedCompressedArray = [ | |
(8, 3), | |
(2, 9), | |
(8, 1), | |
(3, 1), | |
(5, 4), | |
(0, 7), | |
(9, 1)] | |
let compressedArray = compressArray(uncompressedInts) | |
let isCompressionCorrect = compressedArray.elementsEqual(expectedCompressedArray) { | |
$0.0 == $1.0 && $0.1 == $1.1 | |
} | |
if isCompressionCorrect { | |
print("Compression success!") | |
} else { | |
print("Compression failure: \(compressedArray)") | |
} | |
let decompressedArray = decompressArray(compressedArray) | |
let isDecompressionCorrect = decompressedArray == uncompressedInts | |
if isDecompressionCorrect { | |
print("Decompression success!") | |
} else { | |
print("Decompression failure: \(decompressedArray)") | |
} |
My solution is shown below. It uses some slick Swift goodness, such as a where clause, the flatMap method, and tuple decomposition.
The full source code is available, as a playground, here:
https://github.com/ijoshsmith/swift-array-compression
Happy Swifting!
Pingback: Dew Drop – November 27, 2015 (#2140) | Morning Dew