트랙
/
F#
F#
/
연습 문제
/
Tisbury 보물찾기
Tisbury 보물찾기

Tisbury 보물찾기

학습 연습 문제

소개

튜플

튜플은 이름은 없지만 순서가 있는 값들을 _불변_으로 묶은 것이에요. 튜플은 다른 튜플을 포함해 어떤 데이터 타입이든 (또는 여러 데이터 타입을) 담을 수 있어요.

튜플은 (와 ) 문자 사이에 쉼표로 구분한 값들로 정의해요: (<element_1>, ... , <element_n>).

("one", 2) // Tuple pair (2 values)
("one", 2, true) // Tuple triplet (3 values)

길이와 타입(순서까지)이 같은 튜플끼리만 비교할 수 있어요. 튜플은 구조적 동등성을 가져요. 즉, 모든 값이 같을 때만 두 튜플이 같아요.

(1, 2) = (1, 2) // Same length, same types, same values, same order
// => true

(1, 2) = (2, 1) // Same length, same types, same values, different order
// => false

(1, 2) = (1, "2") // Same length, different types
// compiler error

(1, 2) = (1, 2, 3) // Different length
// compiler error

튜플에서 값을 꺼내는 방법은 세 가지가 있어요:

  • fst와 snd 함수
  • 튜플 분해
  • 패턴 매칭
let person = ("Jordan", 170)

// Option 1: fst/snd
let name1 = fst person
let length2 = snd person

// Option 2: deconstruction
let (name2, length2) = person
// => name2 = "Jordan"
// => length2 = 170

// Option 3: pattern matching
match person with
| name3, length3 -> printf "%s: %d" name3 length3

지침

Azara와 Rui는 해적을 테마로 한 보물찾기 대회에 함께 참가한 팀원이에요. 한 명은 지도 좌표가 적힌 보물 목록을, 다른 한 명은 지도 좌표가 적힌 장소 이름 목록을 가지고 있어요. 두 사람은 시작 지점에 '현재 위치'라고 표시된 빈 지도도 함께 받았어요.

Azara의 목록 Rui의 목록
보물 좌표
Amethyst Octopus 1F
Angry Monkey Figurine 5B
Antique Glass Fishnet Float 3D
Brass Spyglass 4B
Carved Wooden Elephant 8C
Crystal Crab 6A
Glass Starfish 6D
Model Ship in Large Bottle 8A
Pirate Flag 7F
Robot Parrot 1C
Scrimshaw Whale's Tooth 2A
Silver Seahorse 4E
Vintage Pirate Hat 7E
장소 이름 좌표 사분면
Seaside Cottages (1, 'C') Blue
Aqua Lagoon (Island of Mystery) (1, 'F') Yellow
Deserted Docks (2, 'A') Blue
Spiky Rocks (3, 'D') Yellow
Abandoned Lighthouse (4, 'B') Blue
Hidden Spring (Island of Mystery) (4, 'E') Yellow
Stormy Breakwater (5, 'B') Purple
Old Schooner (6, 'A') Purple
Tangled Seaweed Patch (6, 'D') Orange
Quiet Inlet (Island of Mystery) (7, 'E') Orange
Windswept Hilltop (Island of Mystery) (7, 'F') Orange
Harbor Managers Office (8, 'A') Purple
Foggy Seacave (8, 'C') Purple

그런데 정리가 좀 엉망이에요. Azara의 좌표는 Rui의 좌표와 형식도 다르고 정렬 순서도 달라 보여서, 어떤 보물이 어떤 장소에 짝을 이루는지 알아내려면 두 목록을 번갈아 확인해야 해요. F#을 갓 배우기 시작한 두 사람은 보물찾기 정보를 더 잘 정리할 수 있도록 작은 프로그램(사실은 함수 몇 개예요)을 짜 달라고 도움을 청하러 왔어요.

1. 좌표 추출하기

Azara의 목록에서 (treasure, coordinate) 쌍을 받아 지도 좌표만 추출해서 반환하는 getCooordinate() 함수를 구현해요.

getCoordinate ("Scrimshaw Whale's Tooth", "2A")
// "2A"

2. 좌표 형식 변환하기

"2A" 형식의 좌표를 받아 (2, 'A') 형식의 튜플을 반환하는 convertCoordinate() 함수를 구현해요.

convertCoordinate "2A"
// (2, 'A')

3. 좌표 일치 확인하기

compareRecords() 함수를 구현해요. 이 함수는 (treasure, coordinate) 쌍과 (location, coordinate, quadrant) 레코드를 받아 각각의 좌표를 비교해요. 좌표가 "일치"하면 **true**를, 그렇지 않으면 **false**를 반환해요. 정확하게 비교하려면 필요에 따라 좌표 형식을 다시 맞춰 줘요.

compareRecords ("Brass Spyglass", "4B") ("Seaside Cottages", (1, 'C'), "blue")
// false

compareRecords ("Model Ship in Large Bottle", "8A") ("Harbor Managers Office", (8, 'A'), "purple")
// true

4. 일치하는 레코드 합치기

createrecord() 함수를 구현해요. 이 함수는 Azara의 목록에서 온 (treasure, coordinate) 쌍과 Rui의 목록에서 온 (location, coordinate, quadrant) 레코드를 받아, 좌표가 일치하면 (coordinate, location, quadrant, treasure)를 반환해요. 좌표가 일치하지 않으면 같은 모양의 튜플을 반환하되 ""로 채워요. 정확하게 비교하려면 필요에 따라 좌표 형식을 다시 맞춰 줘요.

createRecord ("Brass Spyglass", "4B") ("Abandoned Lighthouse", (4, 'B'), "Blue")
// ("4B", "Abandoned Lighthouse", "Blue", "Brass Spyglass")

createRecord ("Brass Spyglass", "4B") ("Seaside Cottages", (1, 'C'), "Blue")
// ("", "", "", "")
GitHub에서 편집 링크가 새 창이나 탭에서 열려요
F# Exercism

Tisbury 보물찾기 문제를 시작해 볼 준비가 됐나요?

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