mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
96 lines
2.2 KiB
Swift
96 lines
2.2 KiB
Swift
//===--- RomanNumbers.swift -----------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import TestsUtils
|
|
|
|
//
|
|
// Mini benchmark implementing roman numeral conversions to/from integers.
|
|
// Measures performance of Substring.starts(with:) and String.append(),
|
|
// with very short string arguments.
|
|
//
|
|
|
|
public let RomanNumbers = [
|
|
BenchmarkInfo(
|
|
name: "RomanNumbers",
|
|
runFunction: run_RomanNumbers,
|
|
tags: [.api, .String, .algorithm])
|
|
]
|
|
|
|
let romanTable: DictionaryLiteral<String, Int> = [
|
|
"M": 1000,
|
|
"CM": 900,
|
|
"D": 500,
|
|
"CD": 400,
|
|
"C": 100,
|
|
"XC": 90,
|
|
"L": 50,
|
|
"XL": 40,
|
|
"X": 10,
|
|
"IX": 9,
|
|
"V": 5,
|
|
"IV": 4,
|
|
"I": 1,
|
|
]
|
|
|
|
extension BinaryInteger {
|
|
var romanNumeral: String {
|
|
var result = ""
|
|
var value = self
|
|
outer:
|
|
while value > 0 {
|
|
var position = 0
|
|
for (i, (key: s, value: v)) in romanTable[position...].enumerated() {
|
|
if value >= v {
|
|
result += s
|
|
value -= Self(v)
|
|
position = i
|
|
continue outer
|
|
}
|
|
}
|
|
fatalError("Unreachable")
|
|
}
|
|
return result
|
|
}
|
|
|
|
init?(romanNumeral: String) {
|
|
self = 0
|
|
var input = Substring(romanNumeral)
|
|
outer:
|
|
while !input.isEmpty {
|
|
var position = 0
|
|
for (i, (key: s, value: v)) in romanTable[position...].enumerated() {
|
|
if input.starts(with: s) {
|
|
self += Self(v)
|
|
input = input.dropFirst(s.count)
|
|
position = i
|
|
continue outer
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
@inline(never)
|
|
func checkRomanNumerals(upTo limit: Int) {
|
|
for i in 0 ..< limit {
|
|
CheckResults(Int(romanNumeral: identity(i.romanNumeral)) == i)
|
|
}
|
|
}
|
|
|
|
@inline(never)
|
|
public func run_RomanNumbers(_ N: Int) {
|
|
for _ in 0 ..< 10 * N {
|
|
checkRomanNumerals(upTo: 1100)
|
|
}
|
|
}
|