본문 바로가기

ALGORITHM

[Swift] Codewars: Persistent Bugger

https://www.codewars.com/kata/55bf01e5a717a0d57e0000ec

 

Codewars - Achieve mastery through coding practice and developer mentorship

A coding practice website for all programming levels – Join a community of over 3 million developers and improve your coding skills in over 55 programming languages!

www.codewars.com

 

Codewars 사이트에서 처음 푼 문제

무슨 기준으로 추천해주는지 모르겠는데 나갔다가 다시 들어가니까 추천 문제가 바뀌어 있는..?!

 

과거 코드는 따로 Past Code로 저장해주는듯하다. 찾기 어려웠다ㅜ

 

문제 설명은..

28 이면 2 * 8 = 16 , 1 * 6 = 6  이렇게 자릿수를 곱해서 한자릿수가 나올때까지의 계산 횟수를 구하면 된다.

 

항상 이런 문제를 풀때 직접 10씩 나눠주면서 자릿수를 구했는데.. ㅇㅅㅇ

이렇게되면 항상 코드가 길어지고 가독성도 떨어졌다.

func persistence(for num: Int) -> Int {
  
  var num = num
  var count = 0
  
  while true {
    let decimalPoints = decimalPointsOf(num)
    if decimalPoints.isEmpty { break }
    num = decimalPoints.reduce(1, *)
    count += 1
  }
  
   return count
}

func decimalPointsOf(_ num: Int) -> [Int] {
  
  if num < 10 { return [] }
  
  var decimalPoints: [Int] = []
  var num = num
  let divisor = 10
  
  while 10 <= num {
    decimalPoints.append(num % divisor)
    num /= divisor
  }
  decimalPoints.append(num)
  
  return decimalPoints
}

 

String으로 바꿔서 각 자릿수를 배열로 바꾸고 다시 Int로 바꿔서 편안하게 한줄로 구할 수 있는 방법을 알 수 있었다.

심지어 여기서는 재귀를 썼넹..! 

오 .. Best 답변에 있는 이유를 알겠다..

Int로 형변환할때 flatMap 쓰는 방법도 새로운 사실 오...

func persistence(for num: Int) -> Int {
  let digits: [Int] = String(num).characters.flatMap { Int(String($0)) }
  
  return digits.count == 1 ? 0 : 1 + persistence(for: digits.reduce(1, *))
}

 

가장 짧은 코드길래 가져와봤는데 위와 비슷한 코드를 한줄로 줄여놓은 느낌dtd

func persistence(for num: Int) -> Int {
    return num < 10 ? 0 : 1 + persistence( for: String(num).characters.reduce( 1, {$0 * Int(String($1))!} ) )
}