Two Fer

Two Fer

쉬움

소개

일부 영어 억양에서는 "two for"를 빠르게 말하면 "two fer"처럼 들려요. Two-for-one은 하나를 사면 하나를 무료로 더 준다는 뜻을 나타내는 표현이에요. 그래서 "two-fer"라는 말은 흔히 하나를 사면 하나를 더 주는 혜택을 의미해요.

쿠키 두 개를 하나 가격으로 살 수 있는 휴일 특별 행사를 하는 빵집을 상상해 봐요 ("two-fer one!"). 이 혜택을 받아들이고, (아주 관대하게도) 남은 쿠키 하나를 줄에 서 있는 다른 사람에게 주기로 해요.

지침

여분의 쿠키를 나눠 줄 때 무슨 말을 할지 정하는 것이 이번 과제예요.

그 사람의 이름을 안다면(예를 들어 이름이 Do-yun이라면) 이렇게 말해요:

One for Do-yun, one for me.

이름을 모른다면 대신 _you_라고 말해요.

One for you, one for me.

몇 가지 예를 볼까요?

이름 대화
Alice One for Alice, one for me.
Bohdan One for Bohdan, one for me.
One for you, one for me.
Zaphod One for Zaphod, one for me.

Odin 관련 지침

Odin은 기본 인자를 지원해요. 기본 인자는 서로 연관되어 있지만 조금씩 다른 API가 필요한 상황에서, 프로시저를 여러 가지 매개변수 조합으로 호출할 수 있게 해주는 유용한 기능이에요.

기본 인자가 없다면, API에 필요한 프로시저의 수가 폭발적으로 늘어날 수 있어요. Java처럼 기본 인자를 지원하지 않는 언어는 같은 효과를 내기 위해 메서드 오버로딩에 의존하거나(코드는 더 많아져요), 아주 많은 인자를 가진 프로시저를 제공해야 해요.

greeting 프로시저를 예로 들어볼까요? 여기서는 언어와, 이름을 대문자로 쓸지, 그리고 인사말 끝에 느낌표를 붙일지를 지정할 수 있으면 해요. 분석해 보니 가장 많은 사용자가 언어로 영어를 지정하고, 이름을 대문자로 쓰지 않으며, 끝에 느낌표를 원하지 않았어요. 두 번째로 많은 사용자는 인사말 끝에 느낌표를 붙였고요.

모든 인자를 가진 프로시저 하나를 만들 수도 있어요:

greeting :: proc(name: string, language: Language, do_uppercase: bool, add_exclamation: bool) {
	...
}

그러면 모든 사용자가 모든 인자에 대한 문서를 읽고 항상 값을 채워야 해요.

기본 인자가 없다면, 다음과 같이 매개변수 조합이 다른 여러 프로시저를 정의할 수도 있어요:

greeting_common :: proc(name: string) {...}

greeting_with_exclamation :: proc(name: string) {...}

greeting_general :: proc(name: string, language: Language, do_uppercase: bool, add_exclamation: bool) {...}

// Odin supports overloading but it has to be explicitly defined
greeting :: proc {
	greeting_common,
	greeting_with_exclamation,
	greeting_general,
}

Odin처럼 기본 인자를 지원하는 언어라면, 가장 적게 쓰이는 인자에 적절한 기본값을 지정하면 돼요. 호출하는 쪽에서는 기본 인자를 생략해서 프로시저가 지정된 기본값을 사용하게 하거나, 값을 덮어쓸 수 있어요.

greeting :: proc(name: string, language: Language = Language.English, do_uppercase : bool = false, add_exclamation: bool = false) {...}

// Note: because Odin supports type inference, we can simplify the interface.
greeting :: proc(name: string, language:= Language.English, do_uppercase := false, add_exclamation:= false) {...}

모든 인자를 기본값으로 두고 프로시저를 호출할 수도 있어요:

greeting("John Doe")

호출자에게 중요한 인자는 덮어쓸 수 있어요:

greeting("John Doe", Language.Spanish)

필요한 인자가 위 예시처럼 위치 순서대로라면 이름을 붙일 필요가 없어요. 하지만 일부 인자를 건너뛰어야 한다면, 건너뛴 첫 번째 인자 이후의 인자에는 이름을 붙여야 해요.

greeting("John Doe", add_exclamation=true)

메모리 관리

이 연습 문제에서는 반환하는 문자열을 할당하도록 만들어진 프로시저를 구현해요. 문자열을 해제하는 것은 프로시저를 호출한 쪽의 책임이에요.

// The procedure will be called like that:
str := two_fer("Alice")
// ...
// and eventually the caller will delete the string
delete(str)

Odin 공식 문서의 default arguments와 Odin의 named arguments도 참고해 보면 좋아요.


출처

이 연습 문제의 출처를 살펴보세요.

GitHub에서 편집 링크가 새 창이나 탭에서 열려요
Odin Exercism

Two Fer 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 Odin 트랙을 연습 문제 73개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.