Open4
Scalaでjr-pricingの実装
はじめに
scalaで https://github.com/masuda220/jr-pricing を実装する
Scalaインストール
ランタイム系
appseed246@appseed246mbp src % sdk version
SDKMAN!
script: 5.18.2
native: 0.4.2
appseed246@appseed246mbp src % java --version
openjdk 21 2023-09-19 LTS
OpenJDK Runtime Environment Corretto-21.0.0.35.1 (build 21+35-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.0.35.1 (build 21+35-LTS, mixed mode, sharing)
Intellij
- Intellij IDEA Community Editionをインストール
- PluginからScalaプラグインをインストールし再起動
- プロジェクト作成
- Scala: v2.13.12
参考資料
文法
数値の型変換
opaque type
- 既存の型に別名をつけられる。
- IntのOpaque Typeを作成しても、四則演算はextensionとして定義する必要がある
package models
import scala.annotation.targetName
object Prices {
opaque type Price = Int
object Price {
// 10円以下切り捨て
def apply(value: Int): Price = (value / 10) * 10
}
extension (x: Price)
def value: Int = x
@targetName("append")
def +(y: Price): Price = Price(x.intValue + y.intValue)
@targetName("subtract")
def -(y: Price): Price = Price(x.intValue - y.intValue)
@targetName("multiple")
def *(y: Double): Price = Price((x.intValue * y).toInt)
}
日時
javaのjoda-timeを利用する
libraryDependencies += "joda-time" % "joda-time" % "2.12.5"
参考
実装のための整理
料金体系
- 料金 = 運賃(basic fare) + 特急料金(super express surcharge)
片道の料金計算に必要な要素
- 出発地(東京固定)
- 目的地
- 指定席/自由席
- 大人/子供
- 特急種別
往復の運賃計算に必要な要素
- 片道の営業キロ
- 利用人数
- 日時
料金計算に影響のあるデータ
- (0) のぞみ割増
- 特急料金に対して、目的地ごとに設定された固定額を加算する
- (1) 自由席割引
- 特急料金から530円減算
- (2) 子供割引
- 運賃・特急料金から5額引
- (3) 往復割引
- 往復601km以上で、片道の運賃を1割引
- (4) 団体割引(全員大人として扱う)
- 8人以上の割引
- 1人あたりの運賃・特急料金を一定額割引
- 12/21 ~ 1/10: 10%
- 上記期間以外: 15%
- 1人あたりの運賃・特急料金を一定額割引
- 31人以上の割引
- 31~50人: 1人分の運賃・特急料金が無料
- 51人以上: 50人増えるごとに1人ずつ運賃・特急料金が無料
- 8人以上の割引
- (5) 季節による変動
-
指定席特急料金が増減。自由席は変動なし
- 繁忙期(12/25 ~ 1/10): 指定席特急料金から +200円
- 閑散期(1/16 ~ 1/30): 指定特急料金から -200円
-
指定席特急料金が増減。自由席は変動なし
料金ルールの適用順番
(0) -> (1) -> (5) -> (2) -> (3) -> (4)
ハマりどころ
if-then- else
Scala3ではif ... then ... else(if)
スタイルで記述する
def compare(a: Int, b: Int): Int =
if a < b then
-1
else if a == b then
0
else
1