Last active
January 24, 2020 12:49
Revisions
-
rjstelling revised this gist
Jan 24, 2020 . 1 changed file with 28 additions and 29 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1,41 +1,56 @@ import Foundation public enum StringSearchError: Swift.Error { case didNotFind(Character) } extension String { static let ReducedDigits = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789" static let DefaultBase36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" static let DefaultDigits = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" static let DefaultEmoji = "π€β€οΈβ οΈπ€π¦ππ§πππ€’π§ π§Άππππ₯π₯β½οΈππΆπ§Ά" internal func character<T>(at index: T) -> String where T: FixedWidthInteger { return String(self[self.index(self.startIndex, offsetBy: Int(index))]) } fileprivate func position(of char: Character) throws -> Int { guard let idx = self.firstIndex(of: char) else { throw StringSearchError.didNotFind(char) } return Int( self.distance(from: self.startIndex, to: idx) ) } } extension String { public func decode<T: FixedWidthInteger & UnsignedInteger>() throws -> T { return try self.decode(T(String.ReducedDigits.count), using: .ReducedDigits) } private func decode<T>(_ redux: T, using digits: String = .DefaultDigits) throws -> T where T: FixedWidthInteger & UnsignedInteger { let decoded = try self.reduce(T(0)) { let value = T( try digits.position(of: $1) ) return ($0 * redux) + value } return decoded } } public enum BaseError: Swift.Error { case outOfRange } extension FixedWidthInteger where Self.Magnitude : UnsignedInteger { public func encode() throws -> String { return try self.base(String.ReducedDigits.count, using: .ReducedDigits) } private func encode<T>(_ redux: T, using digits: String = .DefaultDigits) throws -> String where T: FixedWidthInteger { guard 1...digits.count ~= Int(redux) else { throw BaseError.outOfRange } var result = "" var value = T(self) let rdx = redux repeat { result = digits.character(at: value % rdx) + result @@ -44,20 +59,4 @@ extension FixedWidthInteger where Self.Magnitude : UnsignedInteger { return result } } -
rjstelling revised this gist
Jan 9, 2019 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -55,7 +55,7 @@ extension String { let decoded = try self.reduce(0) { let value = Double( try digits.position(of: $1) ) return Int( Double($0) * Double(redux) + value ) } return decoded -
rjstelling created this gist
Jan 4, 2019 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,63 @@ import Foundation enum StringSearchError: Swift.Error { case didNotFind(Character) } extension String { fileprivate static let DefaultDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" fileprivate static let DefaultEmoji = "π€β€οΈβ οΈπ€π¦ππ§πππ€’π§ π§Άππππ₯π₯β½οΈππΆπ§Ά" func character<T>(at index: T) -> String where T: FixedWidthInteger { return String(self[self.index(self.startIndex, offsetBy: Int(index))]) } func position(of char: Character) throws -> Int { guard let idx = self.firstIndex(of: char) else { throw StringSearchError.didNotFind(char) } return Int( self.distance(from: self.startIndex, to: idx) ) } } enum BaseError: Swift.Error { case outOfRange } extension FixedWidthInteger where Self.Magnitude : UnsignedInteger { func base36() -> String { return try! self.base(36) } func base62() -> String { return try! self.base(62) } func baseEmoji() -> String { return try! self.base(String.DefaultEmoji.count, using: String.DefaultEmoji) } func base<T>(_ redux: T, using digits: String = .DefaultDigits) throws -> String where T: FixedWidthInteger { guard 1...digits.count ~= Int(redux) else { throw BaseError.outOfRange } var result = "" var value = Int(self) let rdx = Int(redux) repeat { result = digits.character(at: value % rdx) + result value /= rdx } while (value > 0) return result } } extension String { func decode36() -> Int { return try! self.decode(36) } func decode62() -> Int { return try! self.decode(62) } func decode(_ redux: Int, using digits: String = .DefaultDigits) throws -> Int { let decoded = try self.reduce(0) { let value = Double( try digits.position(of: $1) ) return Int( ( Double($0) + (value/Double(redux)) ) * Double(redux) ) } return decoded } }