Codewars(알고리즘)/5Kyu

[Codewars] [5kyu] Product of consecutive Fib numbers

Dannian 2021. 1. 26. 18:14
반응형

오랜만에 알고리즘 정리 올립니다...

 

Codewars: Achieve mastery through challenge

Codewars is where developers achieve code mastery through challenge. Train on kata in the dojo and reach your highest potential.

www.codewars.com

피보나치 수열의 값들을 이용해서 Input된 값과 비교해서 결과를 반환하는 문제입니다.

 

1. Swift

1-1. 본인의 풀이

입력된 값은 피보나치 숫자의 앞 뒤 값(F(n), F(n+1))을 곱한 값과의 일치여부를 계산해서 반환하는 문제입니다.

피보나치 수는 아시겠지만, 0과 1로 시작해서 다음 숫자는 그 바로 앞 두 숫자의 합이 되는 수열입니다.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...

이 문제에서는 F(n) * F(n+1)값이 입력된 값 prod와 동일한 경우에는 해당하는 F(n), F(n+1) 그리고 True값을,

일치하는 값을 찾을 수 없는 경우 F(n) * F(n+1) > prod 값 중 가장 작은 F(n)과 F(n+1), False값을 반환하는 문제입니다.

아래는 저의 풀이입니다.

func productFib(_ prod : UInt64) -> (UInt64,UInt64,Bool) {
  var breaker : Bool = true // for break
  var successBool: Bool = false // for result boolean
  var num1 : UInt64 = 0
  var num2 : UInt64 = 1
  // 반복
  while breaker {
    if num1 * num2 == prod {
      breaker = false
      successBool = true
    }else{
      if (num1 * num2 > prod) && ((num2 - num1) * num1 < prod) {
        breaker = false
        successBool = false
      }else{
        fibonacciCalc(num1: &num1, num2: &num2)
      }
    }
  }
  return (num1, num2, successBool)
}

// 피보나치 수열 계산용
func fibonacciCalc(num1 : inout UInt64, num2 : inout UInt64) {
  // num1 + num2 = num3
  let tempNum1 = num1
  num1 = num2
  num2 = tempNum1 + num2
}

(이러면 안되지만) 재밌어보여서 일 하면서 틈틈히 코드를 작성하다보니 줄이는건 생각도 안했네요 ㅎㅎ

일단 가장 처음 breaker, successBool이라는 Boolean 변수를 선언했습니다.

breaker는 while문 반복 및 벗어나기 위한 flag이고 successBool은 결과 반환을 위한 값입니다.

num1, num2는 각각 수열의 시작 포인트입니다.

7번째 줄 부터는 반복문 시작입니다.

breaker가 true인 상태인 동안 num1 * num2를 비교하고, 해당 값이 prod와 동일하면 바로 벗어나고, 아닌 경우는 prod값과 비교해서 벗어날지, 수열을 더 반복할지 판단합니다.

작성하면서 보니 ((num2 - num1) * num1 < prod)는 필요 없었네요 ㅎㅎ;

 

1-2. Best Solution

All Soluion에서 Best Practices와 Clever를 가장 많이 받은 답안입니다.

func productFib(_ prod: UInt64) -> (UInt64, UInt64, Bool) {
    var m: UInt64 = 0, n: UInt64 = 1
    while m * n < prod { (m, n) = (n, m + n) }
    return (m, n, m * n == prod)
}

timvermeulen 이라는 유저가 올린 답이네요.

m, n 변수로 수열의 시작을 정하고 while문을 돌리는데 m과 n의 곱이 prod보다 작은 동안 반복합니다.

이렇게 하면 동일하거나 큰 수의 경우 멈추게 되겠죠.

반복문이 시작 될 때 m * n < prod값을 비교하게 되기 때문에 prod 값보다 크거나 같은 경우는 바로 반복문을 벗어납니다.

그리고 결과값을 반환합니다.

간단하면서 명료한 답안인 것 같습니다.

전 언제 쯤이면 저런 답을 한 번에 낼 수 있을지..ㅠㅠ

 

이 외에는 삼항 연산자와 재귀문을 이용해서 값을 도출한 풀이, Struct를 이용해서  값을 계산하는 등 다양한 풀이가 있습니다.

5Kyu라고 해서 좀 쫄았는데, 생각보다 쉽고 재밌는 문제였습니다.

-차후 다른 언어의 풀이도 추가될 예정입니다.-

반응형