Scala言語の基礎確認用練習問題

March 23, 2023

Scala basic exercise for beginners

No.1

任意の 2 つの整数形式の文字列の和を算出するメソッドを完成させてください。

def add(x: String, y: String): Option[Int] = {
  val xOpt = x.toIntOption
  val yOpt = y.toIntOption
  ???
}

No.2

整数形式を想定した任意の文字列について、以下の条件で返す文字列を決めるメソッドを完成させてください。

  • 整数以外の場合: "Nan"を返す
  • 0 の場合: "0"を返す
  • 正の整数の場合: "P"を返す
  • 負の整数の場合: "N"を返す
  • -10 億以下の場合: "-∞"を返す
  • 10 億以上の場合: "∞"を返す
def check(s: String): String = {
  val opt = s.toIntOption
  ???
}

No.3

整数形式を想定した任意の4つの文字列について、総和を算出するメソッドを完成させてください。ただしコレクションの使用は禁止します。

def sum(a: String, b: String, c: String, d: String): Option[Int] = {
  val aOpt = a.toIntOption
  val bOpt = b.toIntOption
  val cOpt = c.toIntOption
  val dOpt = d.toIntOption
  ???
}

No.4

任意の数の整数形式の文字列を入力として受け取り、それらの値を合計した結果を返すメソッドを完成させてください。

def sum(strings: String*): Int = {
  val integers = strings.map(s => s.toIntOption)
  ???
}

No.5

任意の数の有限時間を入力として受け取り、それらの時間をを合計した結果を返すメソッドを完成させてください。

def sum(durations: Seq[FiniteDuration]): FiniteDuration = {
  ???
}

No.6

非同期でドル円とユーロドルのレートを I/O で取得し、その結果をもとにユーロ円のレートを計算するメソッドを完成させてください。なお、ユーロ円のレートとは、1 ユーロを購入するために必要な円の額を表します。具体的には、ドルを購入し、そのドルを使って 1 ユーロを購入するためには、何円必要かを計算することになります。今回の例では、1 ドルを購入するのに 123.45 円が必要であり、1 ユーロを購入するのには 1.2345 ドルが必要です。

def calcEurJpyRate: Future[BigDecimal] = {

  import scala.concurrent.ExecutionContext.Implicits.global

  // ドル円のレートを非同期のI/O操作で取得することを想定
  val usdjpy = Future.successful(BigDecimal("123.45"))
  // ユーロドルのレートを非同期のI/O操作で取得することを想定
  val eurusd = Future.successful(BigDecimal("1.2345"))
  // ユーロ円のレート
  val eurjpy = ???

  eurjpy
}

No.7

為替レートを適用して入力された円をドルに変換する API があります。この API を非同期で呼び出して、ドルの合計値を計算するメソッドを完成させてください。

def sumDollar(jpy: BigDecimal*): Future[BigDecimal] = {

  import scala.concurrent.ExecutionContext.Implicits.global

  // 為替レートを適用して入力された円をドルに変換するAPIを想定した関数
  val usdjpy = BigDecimal("123.45")
  val api = (jpy: BigDecimal) => Future.successful(jpy * usdjpy)

  // 合計値
  val sum = ???

  sum
}

No.8

為替レートを適用して入力されたドルをユーロに変換する API があります。この API を使用して、ユーロの合計値を計算するメソッドを完成させてください。ただし、ユーロドルに関する API には多くのアクセスがあるため、リクエストのレート制限がかかっており、同時に API を呼び出すことができません。

def sumEuro(usd: BigDecimal*): Future[BigDecimal] = {

  import scala.concurrent.ExecutionContext.Implicits.global

  // 為替レートを適用して入力されたドルをユーロに変換するAPIを想定したオブジェクト
  object RateLimitedApi {

    private var available = true

    private def lockFor(millisSec: Long): Unit = {
      available = false
      Thread.sleep(millisSec)
      available = true
    }

    private val eurusd = BigDecimal("1.2345")

    def call(usd: BigDecimal): Future[BigDecimal] = Future {
      assert(available)
      lockFor(1000)
      usd * eurusd
    }
  }

  // 合計値
  val sum = ???

  sum
}

No.9

以下の文字列を整数に変換する関数は機能的に問題ありませんが、冗長で不適切です。機能を維持しながら、よりシンプルな実装に切り替えてください。

def toInt(str: String): Either[Throwable, Int] = {
  try {
    Right(str.toInt)
  } catch {
    case e: Throwable => Left(e)
  }
}

No.10

以下の文字列を整数に非同期で変換する関数は機能的に問題ありませんが、冗長で不適切です。機能を維持しながら、よりシンプルな実装に切り替えてください。

def toIntAsync(str: String): Future[Try[Int]] = {
  import scala.concurrent.ExecutionContext.Implicits.global
  Future(Try(str.toInt))
}

Written by Gayamasan who lives and works in Japan.