Kotlin KoansでKotlin入門　第１７回：Operators overloading

# はじめに
公式の問題集[「Kotlin Koans」](https://play.kotlinlang.org/koans/overview)を解きながらKotlinを学習します。

過去記事はこちら
- Introduction
  - [第０回：Kotlin Koansについて](https://qiita.com/kosuke1/items/41d192af63485bfc8cb8)
  - [第１回：Simple Functions](https://qiita.com/kosuke1/items/5862a3ece96082a62e67)
  - [第２回：Named arguments](https://qiita.com/kosuke1/items/2af11262852ee41b5da7)
  - [第３回：Default arguments](https://qiita.com/kosuke1/items/16cb8ac780df58dc8054)
  - [第４回：Triple-quoted strings](https://qiita.com/kosuke1/items/52cfeed2c49b0252d40e)
  - [第５回：String templates](https://qiita.com/kosuke1/items/0221bbbc5bc70847be6f)
  - [第６回：Nullable types](https://qiita.com/kosuke1/items/aa96e422c5313b6961bc)
  - [第７回：Nothing type](https://qiita.com/kosuke1/items/1ca0e48820d58c9dfe16)
  - [第８回：Lambdas](https://qiita.com/kosuke1/items/8de74f9491e003127f53)
- Classes
  - [第９回：Data classes](https://qiita.com/kosuke1/items/1be2de1b4406b8d914bf) 
  - [第１０回：Smart casts](https://qiita.com/kosuke1/items/50bdecaa0740eb0e1a17)
  - [第１１回：Sealed classes](https://qiita.com/kosuke1/items/71a4da02fe1e99da5d63)
  - [第１２回：Rename on import](https://qiita.com/kosuke1/items/f11465cc15a94e7589a3)
  - [第１３回：Extension functions](https://qiita.com/kosuke1/items/d4a1da00bc142c297221)
- Conventions
  - [第１４回：Comparison](https://qiita.com/kosuke1/items/e9486d044cae32167f36) 
  - [第１５回：Ranges](https://qiita.com/kosuke1/items/797f049ce5f33b1810c9)
  - [第１６回：For loop](https://qiita.com/kosuke1/items/f5f6eeea41fb89b2a20c)


# 問題
[Operators overloading](https://play.kotlinlang.org/koans/Conventions/Operators%20overloading/Task.kt)

日付に年、週、日を加えることをサポートする日付演算を実装してください。```date + YEAR * 2 + WEEK * 3 + DAY * 15```のようなコードを書くことができます。
まず、MyDateにTimeIntervalを引数として、拡張関数plus()を追加します。DateUtil.kt で宣言されているユーティリティ関数 MyDate.addTimeIntervals() を使用します。
そして、1つの日付にいくつかの時間間隔を加えることに対応してみてください。追加クラスが必要かもしれません。


修正前のコード
```Kotlin
import TimeInterval.*

data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int)

// Supported intervals that might be added to dates:
enum class TimeInterval { DAY, WEEK, YEAR }

operator fun MyDate.plus(timeInterval: TimeInterval): MyDate = TODO()

fun task1(today: MyDate): MyDate {
    return today + YEAR + WEEK
}

// fun task2(today: MyDate): MyDate {
//     TODO("Uncomment") //return today + YEAR * 2 + WEEK * 3 + DAY * 5
// }

```


# 問題のポイント
[算術演算子](https://kotlinlang.org/docs/operator-overloading.html#arithmetic-operators)の```+```と```*```をオーバーライドします。

# 解答例

```Kotlin
import TimeInterval.*

data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int)

// Supported intervals that might be added to dates:
enum class TimeInterval { DAY, WEEK, YEAR }

operator fun MyDate.plus(timeInterval: TimeInterval): MyDate = addTimeIntervals(timeInterval, 1)

class RepeatedTimeInterval(val timeInterval: TimeInterval, val number: Int)

operator fun TimeInterval.times(number: Int) = RepeatedTimeInterval(this, number)

operator fun MyDate.plus(timeIntervals: RepeatedTimeInterval) =
    addTimeIntervals(timeIntervals.timeInterval, timeIntervals.number)

fun task1(today: MyDate): MyDate {
    return today + YEAR + WEEK
}

fun task2(today: MyDate): MyDate {
    return today + YEAR * 2 + WEEK * 3 + DAY * 5
}
```