ScalaでCodeforces#97 Div2参加してみた

Codeforcesはコンテストの告知を律儀にメールで送ってくれます。

毎回ほとんど内容が同じなので、「もう配信停止にしようかなー」と思っていたのですが、今回のメールには私の目を引くものが。

The allowed programming languages are C/C++, Pascal, Java, C#, Python, Ruby, PHP, Haskell and (New!) Scala, OCaml.
C/C++, Pascal, Java, C#, Python, Ruby, PHP, Haskell and (New!) Scala, OCaml
Haskell and (New!) Scala, OCaml.
(New!) Scala

な、なんだってー!(AA略

これは使うしかない!!

A. Presents

1 <= n <= 100 なので indexOf するだけ。

import java.util.Scanner

object MainA extends App {
  val sc = new Scanner(System.in)
  
  val N = sc.nextInt
  val l = for(t <- 0 until N) yield sc.nextInt
  val res = for(i <- 1 to N) yield l.indexOf(i) + 1
  println(res.mkString(" "))
}

for式かわいいよfor式。

B. Ternary Logic

進数変換するだけ・・・なんだけど、実装に手間取ってしまいました。

import java.util.Scanner

object MainB extends App {
  val sc = new Scanner(System.in)

  def conv(n: Int): List[Int] = {
    def inner(n: Int): List[Int] = {
      if (n < 3) n :: Nil
      else (n % 3) :: inner(n / 3)
    }

    inner(n).reverse
  }

  def sum(a: List[Int], b: List[Int]): List[Int] = {
    val la = List.make(a.size.max(b.size) - a.size, 0) ++ a
    val lb = List.make(a.size.max(b.size) - b.size, 0) ++ b

    val res = for (d <- la zip lb) yield (d._1 + d._2) % 3
    res
  }

  def diff(a: List[Int], c: List[Int]): List[Int] = {
    val la = List.make(a.size.max(c.size) - a.size, 0) ++ a
    val lc = List.make(a.size.max(c.size) - c.size, 0) ++ c

    for(d <- la zip lc) yield (d._2 - d._1 + 3) % 3
  }

  def rest(l: List[Int]): String = {
    val s = for (i <- l.reverse zip Stream.from(0)) yield i._1 * (Math.pow(3, i._2)).toInt
    s.sum.toString()
  }

  val a = sc.nextInt()
  val c = sc.nextInt()
  val ca = conv(a)
  val cc = conv(c)

  println(rest(diff(ca, cc)))
}

zipメソッドは競技プログラミングだと乱用することになりそう。
l.reverse zip Stream.from(0) とか楽しかった。

Int に ** が定義されていなかったのでMath.powを使いましたが、自分で implicit conversion で定義してみるといいかもしれませんね。

C. Replacement

not allowed を見逃して減点/(^o^)\

import java.util.Scanner

object MainC extends App {
  val sc = new Scanner(System.in)

  val N = sc.nextInt
  val arr = for (i <- 0 until N) yield sc.nextInt
  if (arr.forall(1 ==)) {
    print(List.make(arr.size - 1, 1).mkString(" "))
    if(arr.size != 1) print(" ")
    println(2)
  } else {
    val vmax = arr.max
    val after = arr.updated(arr.indexOf(vmax), 1).sorted
    println(after.mkString(" "))
  }
}

ソートしてから最後の要素見れば arr.forall(1 ==) なんてやらずに済んだのに。(仮定法過去)

D

幾何あんまり勉強してないんですよね・・・

E

見てない

Result

1499 -> 1466
下がるなんてひどいよ