思路

  • m 进制 -> 十进制 -> n 进制
  • 利用柯里化生成函数(炫技 🐶)

m 进制 -> 十进制

// carry 范围值: 2-36
// origin 范围值: 0-9 [ascii 48-58], A-Z [65-90], a-z [97-122]
func carryToDecimalism(_ carry: Int) -> (_ origin: String) -> Int {
    return { origin in
        // 得到字符串对应的 ascii 码
        let asciis = origin.uppercased().unicodeScalars.map { Int($0.value) }
        // 累加每一位
        let result = asciis.reversed().enumerated().map { (index, ascii) -> Int in
            var standard: Int
            if 65 <= ascii && ascii <= 90 {
                standard = ascii - 65 + 10
            } else {
                standard = ascii - 48
            }
            return standard * Int(pow(Double(carry), Double(index)))
        }.reduce(0, +)
        return result
    }
}

let 十六进制转十进制 = carryToDecimalism(16)
print(十六进制转十进制("1a")) // 26

let 二进制转十进制 = carryToDecimalism(2)
print(二进制转十进制("110")) // 6

十进制 -> n 进制

func decimalismToCarry(_ carry: Int) -> (_ origin: Int) -> String {
    return { origin in
        var result = [Int]()
        var remain = origin
        while remain > 0 {
            result.append(remain % carry)
            remain /= carry
        }
        if carry <= 10 {
            return result.reversed().map(String.init).joined()
        } else {
            return result.reversed().map { i -> String in
                return i < 10 ? String(i) : String(UnicodeScalar(i + 55)!)
            }.joined()
        }
    }
}

let 十进制转二进制 = decimalismToCarry(2)
print(十进制转二进制(26)) // "11010"

References

– EOF –