Please enable JavaScript to view the comments powered by Disqus.Gleam: for 문을 recursion 으로 대체하기
Search
🪩

Gleam: for 문을 recursion 으로 대체하기

태그
Gleam
recursive
Lambda Expression
Lambda
Functional Interface
공개여부
작성일자
2024/04/20
Gleam은 erlang 기반의 language이기 때문에 erlang으로 치환될 수 있어야 하며 따라서 for, while 을 사용하지 않고 recursion을 사용한다.
이러한 Recursive 는 기존에 아래 포스트에서 다룬적이 있다.
Gleam의 문제는 exercism에서 가져왔다.
구현은 아래와 같다.
(1+2+...+n)2(12+22+...+n2)(1 + 2 + ... + n)^2 - (1^2 + 2^2 + ... + n^2)
이것을 해결하기 위한 함수를 구현하는 것이다.
pub fn square_of_sum(n: Int) -> Int { } pub fn sum_of_squares(n: Int) -> Int { } pub fn difference(n: Int) -> Int { }
Elixir
복사
Recursion으로 푸는 생각이 아직 자리 잡기전 아래와 같이 문제를 해결했다.
pub fn square_of_sum(n: Int) -> Int { let sum = n * { n + 1 } / 2 sum * sum } pub fn sum_of_squares(n: Int) -> Int { { n * { n + 1 } * { 2 * n + 1 } } / 6 } pub fn difference(n: Int) -> Int { square_of_sum(n) - sum_of_squares(n) }
Elixir
복사
이 방법은 공차수열의 합공식과 같이 수학으로 해결한 것이지 gleam을 통해 문제를 해결한 것이 아니다.
먼저 square_of_sum 은 아래와 같이 리팩토링을 하였다.
pub fn square_of_sum(n: Int) -> Int { let sum = sum(n) sum * sum }
Elixir
복사
fn sum(n: Int) -> Int { case n { n if n >= 1 -> sum(n - 1) + n _ -> 0 } }
Elixir
복사
여기서 핵심은 sum 함수이다.
Recursion 으로 문제를 해결할 때 핵심은 언제 recursion을 break 하느냐 이다.
이것은 for, while 도 동일하다. 언제 반복을 중지시킬 것 인지 그 지점을 아는것이 핵심이다.
여기선 1 ~ n 까지 합을 구하는 것이고 n이 주어지기 때문에 n-1 을 수행하면서 특정 지점에서 recursion을 빠져나와야 한다.
Python이나 java 에서 recursion을 계속 시도하면 stackoverlow 와 같은 에러가 나는데 이는 recursion이 끝나지 않았기 때문이다.
그래서 다음과 같이 수정하여 recursion 으로 for를 대체한다.
fn sum(n: Int) -> Int { case n { n if n >= 1 -> sum(n - 1) + n _ -> 0 } }
Elixir
복사
이는 1 부터 n 까지의 합을 구하는 함수이다.
pub fn square_of_sum(n: Int) -> Int { let sum = sum(n) sum * sum }
Elixir
복사
square_of_sum 은 위와 같이 구현한다.