トラック
/
Julia
Julia
/
演習
/
ティズベリーの宝探し
ティズベリーの宝探し

ティズベリーの宝探し

学習演習

はじめに

Tupleは、多くの点でVector(1次元のarray)とよく似ています。 ただし、いくつか重要な違いがあります。

  • タプルは角括弧[ ]ではなく、丸括弧( )で書きます。ただし、意味が曖昧でない場合は、丸括弧を省略できます。
  • タプルは同じ型である必要はありません。各要素の型は個別に保持されます。
  • タプルはイミュータブルです。

イミュータブルであることにより、コンパイラーによる最適化がより多く行われ、タプルはベクトルよりも性能が高くなります。そのため、可変である必要がない場合は、タプルを選ぶとよいでしょう。

julia> t = (3, 5.2, "xyz")
(3, 5.2, "xyz")

# Non-homogeneous:
julia> dump(t)
Tuple{Int64, Float64, String}
  1: Int64 3
  2: Float64 5.2
  3: String "xyz"

julia> t[2]
5.2

# Immutable:
julia> t[2] = 7.3
ERROR: MethodError: no method matching setindex!(::Tuple{Int64, Float64, String})

Tuple()というコンストラクターもあり、これは任意の反復可能なコレクションをタプルに変換します。便利なことに、文字列は文字の反復可能なコレクションとして扱われます。

julia> Tuple("Julia")
('J', 'u', 'l', 'i', 'a')

どのタプルでも、インデックスで要素にアクセスしたり、ループで要素を順に取り出したりできます。

数値だけからなるタプルは、配列とまったく同じように、sum()などの数学関数で使うこともできます。

アンパック

タプルは、多重代入を使うことで個々の要素にアンパックできます。 必要のない要素には、ダミー変数としてアンダースコア_を使います。

julia> tup = (1, "Julia", true)
(1, "Julia", true)

julia> num, name, _ = tup
(1, "Julia", true)

julia> uppercase(name), 2num
("JULIA", 2)

Pythonを使っている人なら、この多重代入の構文にはとても馴染みがあるでしょう。

名前付きタプル

Tupleは値だけを持ちます。 NamedTupleは、それぞれの値に名前を組み合わせたものです。

個々のフィールドには、ドット記法でアクセスできます。

julia> nt = (a = 1, b = 7.3)
(a = 1, b = 7.3)

julia> dump(nt)
@NamedTuple{a::Int64, b::Float64}
  a: Int64 1
  b: Float64 7.3

julia> nt.b
7.3

名前は内部的にはSymbol(イミュータブルな型で、コロン:が先頭に付きます)として保持されるため、別の構文も使えます。

julia> nt[:b]
7.3

名前(「キー」とも呼ばれます)だけ、あるいは値だけを別々に取り出すのは簡単です。

julia> nt
(a = 1, b = 7.3)

julia> keys(nt)
(:a, :b)

julia> values(nt)
(1, 7.3)

名前付きタプルを繰り返し処理しても取り出せるのは_値_だけで、_名前_は無視されることに注意してください。

タプルは(名前付きかどうかに関わらず)、構造化されたデータを関数に渡したり、関数から受け取ったりするためによく使われる方法です。 このような用途ではイミュータブルであることが役立ち、データの安全性を確保し、コンパイラーによるより積極的な最適化を可能にします。

説明

AzaraとRuiは、海賊をテーマにした宝探しに挑むチームメイトです。 一人は地図の座標が付いた宝物のリストを、もう一人は地図の座標が付いた場所の名前のリストを持っています。 二人には、出発地点に YOU ARE HERE と印を付けた白地図も渡されています。

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のものとは書式や並び順が違うようなのです。そのため、どの宝物がどの場所に対応するのかを知るには、二人は何度もリストを見比べなければなりません。 二人は駆け出しのJuliaプログラマーで、宝探しの情報をうまく整理するための小さなプログラム(実際にはいくつかの関数です)を書くのを手伝ってほしいと、助けを求めてきました。

1. 座標を取り出す

Azaraのリストから(treasure, coordinate)のペアを受け取り、そこから取り出した地図の座標だけを返すget_cooordinate()関数を実装してください。

julia> get_cooordinate( ("Scrimshaw Whale's Tooth", "2A") )
"2A"

2. 座標を整形する

"2A"という形式の座標を受け取り、('2', 'A')という形式のタプルを返すconvert_coordinate()関数を実装してください。

julia> convert_coordinate("2A")
('2', 'A')

3. 座標を照合する

(treasure, coordinate)のペアと(location, coordinate, quadrant)のレコードを受け取り、それぞれの座標を比較するcompare_records()関数を実装してください。 座標が「一致」すれば**trueを、一致しなければfalse**を返します。 正確に比較するために、必要に応じて座標を整形し直してください。

julia> compare_records(("Brass Spyglass", "4B"), ("Seaside Cottages", ('1', 'C'), "blue"))
false

julia> compare_records(("Model Ship in Large Bottle", "8A"), ("Harbor Managers Office", ('8', 'A'), "purple"))
true

4. 一致したレコードを組み合わせる

Azaraのリストから(treasure, coordinate)のペアを、Ruiのリストから(location, coordinate, quadrant)のレコードを受け取り、座標が一致すれば(coordinate, location, quadrant, treasure)を返すcreate_record()関数を実装してください。

座標が一致_しなければ_、空のタプルを返します。 正確に比較するために、必要に応じて座標を整形し直してください。

julia> create_record(("Brass Spyglass", "4B"), ("Abandoned Lighthouse", ('4', 'B'), "Blue"))
("4B", "Abandoned Lighthouse", "Blue", "Brass Spyglass")

julia> create_record(("Brass Spyglass", "4B"), ("Seaside Cottages", ('1', 'C'), "Blue"))
()
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Julia Exercism

ティズベリーの宝探しを始める準備はできましたか?

Exercismに登録すれば、35個のコンセプト128個の演習、そして本物の人間によるメンタリングとともに、Juliaを学んでマスターできます。すべて無料です。