Skip to content

Instantly share code, notes, and snippets.

@O-O-wl
Last active April 4, 2019 12:15
Show Gist options
  • Save O-O-wl/0ca3796702b6a7e4e2b21c9bfd935b0d to your computer and use it in GitHub Desktop.
Save O-O-wl/0ca3796702b6a7e4e2b21c9bfd935b0d to your computer and use it in GitHub Desktop.
STEP2 - 추가 학습꺼리
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 [.cm,.m,.inch,.yard]
case .g,.kg,.oz,.lb:
return [.g,.kg,.oz,.lb]
case .L,.pt,.qt,.gal :
return [.L,.pt,.qt,.gal]
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: 39.3701,
.yard: 1.09361
],
.cm:
[ .m: 0.01,
.inch: 0.393701,
.yard: 0.0109361
],
.inch:
[
.m: 0.0254,
.cm: 2.54,
.yard: 0.0277778
],
.yard:
[
.cm: 91.44,
.m: 0.9144,
.inch: 36
],
.g:
[
.kg: 0.001,
.oz: 0.035274,
.lb: 0.00220462
],
.kg:
[
.g: 1000,
.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 getRatios( units: (beforeUnit,[afterUnit])) ->[(UnitRatio)]{
var unitRatioTable = getUnitRatioTable()
var (beforeUnit,afterUnits) = units
var ratios = [UnitRatio]()
for i in 0..<afterUnits.count{
ratios.append(unitRatioTable[beforeUnit]![afterUnits[i]]!)
}
return ratios
}
func convert(userInput:String)->[String]{
let (value,units) = recognize(userInput: userInput)
if units == (.error,[.error]){
return ["지원하지 않는 단위 입니다."]
}
let ratios = getRatios(units:units)
var results = [String]()
for i in 0..<ratios.count {
results.append( " \(calculatedValueString(value: value, ratio: ratios[i])) \(units.1[i]) \n")
}
return results
}
func calculatedValueString(value:Double,ratio:UnitRatio)->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 beforeAndAfterUnits = units.split(separator: " ")
guard let beforeUnit = Unit.init(rawValue: String(beforeAndAfterUnits[0])) else{
return (.error,[.error])
}
var afterUnits = [afterUnit]()
// 변경할 단위값 입력
if beforeAndAfterUnits.count > 1 {
afterUnits = getAfterUnits(afterUnits: String(beforeAndAfterUnits[1]))
// 변경할 단위값 미 입력
}else{
afterUnits = beforeUnit.defaultUnit().filter{
unit in
if unit == beforeUnit{
return false
}
return true
}
}
return (beforeUnit,afterUnits)
}
func getAfterUnits(afterUnits:String)->[afterUnit]{
let afterUnitsArray = afterUnits.split(separator: ",")
var afterUnits = [afterUnit]()
for unit in afterUnitsArray {
afterUnits.append(Unit.init(rawValue: String(unit))!)
}
return afterUnits
}
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 availableUnits = getUnitRatioTable().keys.map{
unit in
return unit.rawValue
}
print(" 변환할 값을 입력하세요 \n 가능한 단위: \(availableUnits)\n")
let inputValue = readLine()
for quitCommend in quitCommends {
if(quitCommend == inputValue){
break
}
}
let results = convert(userInput: inputValue!)
for result in results {
print(result)
}
}
}
unitConverter()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment