Nim(言語)で解く AtCoder Beginner Contest 063


AtCoder Beginner Contest 063

経緯

新しい言語学びたい!
特に作りたいものは無い!
じゃあ競プロだ!

事前準備

brew install nim

実行手順

下記のどちらでも。

$ nim c hoge.nim
$ ./hoge
$ nim c -r hoge.nim

A - Restricted

  • 複数空白区切り入力(int)
a.nim
import sequtils, strutils

let A = map(split(readLine(stdin)), parseInt)  # 複数空白区切り入力(int)
let total = A[0] + A[1]
if total >= 10:
    echo "error"
else:
    echo total

提出リンク

Pythonとの比較

a.py
A = list(map(int, input().split()))
total = A[0] + A[1]
if total >= 10:
    print('error')
else:
    print(total)

記述方法がPythonと似ていたので、PythonにてNimのコードに似せて書きました。

提出を比較すると、実行時間とメモリにおいてはPythonより優れていることが伺えます。
コンパイル言語なので速いです。

B - Varied

  • 単一入力(string)
  • 重複検出
b.nim
import sets

let str: string = readLine(stdin) # 単一入力(string)

var charSets = initSet[char]()
var ok = true
for s in str:
    if charSets.contains(s):  # 重複検出
        ok = false
        break
    charSets.incl(s)

if ok:
    echo "yes"
else:
    echo "no"

提出リンク

let str: string = readLine(stdin)

Nimは静的型付を使用できるので、上記のように型を明示的にして変数を宣言することができます。

C - Bugged

  • 複数行入力(int)
  • 剰余
c.nim
import strutils
import algorithm

let n = parseInt(readLine(stdin))
var A: seq[int] = @[]  # 空の配列
var total: int = 0

# 複数行入力(int)
for i in 0..<n:
    A.add(parseInt(readLine(stdin)))
    total += A[i]

if total mod 10 != 0:  # 剰余
    echo total
else:
    A.sort(system.cmp[int])  # 配列のソート
    var ok = false
    for a in A:
        if (total - a) mod 10 != 0:  # 剰余
            ok = true
            total -= a
            break
    if ok:
        echo total
    else:
        echo 0

提出リンク

echo 11 div 3  # 3
echo 11 mod 3  # 2

Nimにおける除算、剰余演算は上記の通り。

D - Widespread

  • 関数
d.nim
import sequtils, strutils

var n: int
var a: int
var b: int
var H: seq[int] = @[]

# 関数宣言(引数、戻り値)
proc f(num: int): bool =
    var total = 0
    for h in H:
        if h - b * num > 0:
            total += (h - b * num + a - b - 1) div (a - b)
    return total > num

# 関数宣言
proc main() = 
    let inputs = map(split(readLine(stdin)), parseInt)
    n = inputs[0]
    a = inputs[1]
    b = inputs[2]

    for i in 0..<n:
        H.add(parseInt(readLine(stdin)))

    var ng = 0
    var ok = 1000000010
    while (ok - ng) > 1:
        let mid: int = (ng + ok) div 2

        if f(mid):
            ng = mid
        else:
            ok = mid

    echo ok

main()

提出リンク