Skip to content

Instantly share code, notes, and snippets.

@O-O-wl
Created April 4, 2019 10:23
Show Gist options
  • Save O-O-wl/6549a86a330e553764f368aca71fb8ca to your computer and use it in GitHub Desktop.
Save O-O-wl/6549a86a330e553764f368aca71fb8ca to your computer and use it in GitHub Desktop.
STEP 2-7
import Foundation
enum Unit : String {
case cm = "cm"
case m = "m"
case inch = "inch"
case yard = "yard"
case g = "g"
case kg = "kg"
case oz = "oz"
case lb = "lb"
case L = "L"
case pt = "pt"
case qt = "qt"
case gal = "gal"
case error = "error"
func defaultUnit ()->Unit{
switch self {
case .cm,.m,.inch,.yard:
return .m
case .g,.kg,.oz,.lb:
return .kg
case .L,.pt,.qt,.gal :
return .L
case .error:
return .error
}
}
}
typealias value = Double
typealias UnitRatio = Double
typealias beforeUnit = Unit
typealias afterUnit = Unit
struct units {
var beforeUnit : beforeUnit
var afterUnit : afterUnit
}
func getUnitRatioTable()->[beforeUnit:[afterUnit:UnitRatio]]{
let unitRatioTable : [beforeUnit:[afterUnit:UnitRatio]] =
[
.m:
[ .cm: 100,
.inch: 0.393701,
.yard: 0.0109361
],
.cm:
[ .m: 0.01,
.inch: 39.3701,
.yard: 1.09361
],
.inch:
[
.m: 0.0254,
.cm: 2.54,
.yard: 0.0277778
],
.yard:
[
.cm: 91.44,
.m: 0.9144,
.inch: 36
],
.g:
[
.kg: 1000,
.oz: 0.035274,
.lb: 0.00220462
],
.kg:
[
.g: 0.001,
.oz: 35.274,
.lb: 2.20462
],
.oz:
[
.g: 28.3495,
.kg: 0.0283495,
.lb: 0.0625
],
.lb:[
.g: 453.592,
.kg: 0.453592,
.oz: 16
],
.L:[
.pt: 2.11338,
.qt: 1.05669,
.gal: 0.21997
],
.pt:[
.L: 0.56826,
.qt: 0.516027,
.gal: 0.129007
],
.qt:[
.L: 1.136520,
.pt: 2.401895,
.gal: 0.300237
],
.gal:[
.L: 4.404884,
.pt: 9.309178,
.qt: 4.654589
]
]
return unitRatioTable
}
func getRatio( units: (beforeUnit,afterUnit)) ->(Double){
var unitRatioTable = getUnitRatioTable()
let (beforeUnit,afterUnit) = units
let ratio = beforeUnit == afterUnit ? 1 :(unitRatioTable[beforeUnit])![afterUnit]
return ratio!
}
func convert(userInput:String)->String{
let (value,units) = recognize(userInput: userInput)
if units == (.error,.error){
return "지원하지 않는 단위 입니다."
}
let ratio = getRatio(units:units)
return "\(calculatedValueString(value: value, ratio: ratio))\(units.1)"
}
func calculatedValueString(value:Double,ratio:Double)->String{
let result = value * ratio
return confirmNumber(number: result)
}
func confirmNumber(number:Double)->String{
if(number.remainder(dividingBy: 1)==0){
return "\(Int.init(number))"
}else{
return "\(number)"
}
}
func recognize(userInput : String)->(value,(beforeUnit,afterUnit)){
let value = getValue(userInput: userInput)
let units = getUnits(userInput: userInput)
return (value,units)
}
func getValue (userInput:String)->Double{
let pattern = "[0-9.]+"
let value = usingRegex(userInput: userInput, pattern: pattern)
return Double.init(value)!
}
func getUnits(userInput:String)->(beforeUnit,afterUnit){
let pattern = "[^0-9.]+"
let units = usingRegex(userInput: userInput, pattern: pattern)
let unitArray = units.split(separator: " ")
guard let beforeUnit = Unit.init(rawValue: String(unitArray[0])) else{
return (.error,.error)
}
let afterUnit:Unit
if unitArray.count == 2 {
afterUnit = Unit.init(rawValue: String(unitArray[1]))!
}else{
afterUnit = beforeUnit.defaultUnit()
}
return (beforeUnit,afterUnit)
}
func usingRegex( userInput:String ,pattern:String ) -> String{
let regexUnits = try! NSRegularExpression.init(pattern: pattern, options: [])
let matchs = regexUnits.firstMatch(in: userInput, options: [], range: NSRange.init(location: 0, length: userInput.count))
let part = NSString.init(string: userInput).substring(with: (matchs?.range)!)
return part
}
func unitConverter(){
let quitCommends = ["q","quit"]
while(true){
let units = getUnitRatioTable().keys.map{
unit in
return unit.rawValue
}
print(" 변환할 값을 입력하세요 \n 가능한 단위: \(units)\n")
let inputValue = readLine()
for quitCommend in quitCommends {
if(quitCommend == inputValue){
break
}
}
print(convert(userInput: inputValue!))
}
}
unitConverter()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment