convert-m-number-to-n-number

思路

  • 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"

Reference:

– EOF –