Nimで競プロをする テンプレ編
僕のテンプレ → https://github.com/kemuniku/cplib/blob/main/src/cplib/tmpl/sheep.nim
入力
整数の入力
いろいろな入力の受け取り方があるが、自分は競プロ で Nim を使う際のまとめにあるCのscanfを用いる方法が好き。
自分のテンプレ
code:nim
proc scanf(formatstr: cstring){.header: "<stdio.h>", varargs.}
proc ii(): int = scanf("%lld\n", addr result)
いろいろな入力
code:nim
#一つの入力
var N = ii()
#複数個の入力
var A,B,C = ii() #Nimはこういう書き方をすると、右が3回呼ばれて、それぞれA,B,Cに結果が代入される。
#配列の入力
var X = newSeqWith(N, ii()) #sequtilsのimportが必要
デメリットを挙げるとすると、intの範囲を超える整数を受けようとすると、無理やりintに収めた値になるので、WAになる。制約は、ちゃんと読もうという話ですが...
文字列の入力
ふつうに一行入力する
code:nim
var S = stdin.readLine
自分は前述した記事にあるgetchar()とかを呼ぶテンプレを書いていたり...
code:nim
proc getchar(): char {.importc: "getchar_unlocked", header: "<stdio.h>", discardable.}
proc si(): string {.inline.} =
result = ""
var c: char
while true:
c = getchar()
if c == ' ' or c == '\n':
break
result &= c
こうするとスペース区切りの文字とかを取れてちょっと便利。
これ、絶対もっときれいに書けるので書き直したい気持ちがある。何かアイデアがあったらおねがいします。
終端文字で終わらないのはやばいと思っていて、なんとかしたいきもち...
四則演算
+-*はいつもの
整数同士の/は小数を返す
切り捨て除算はdiv、あまりはmodで求められる。
さすがに文字なのは嫌なのでこれもテンプレに書く。
code:nim
proc %(x: int, y: int): int = (((x mod y)+y) mod y)
proc //(x: int, y: int): int = (((x) - (x%y)) div (y))
proc %=(x: var int, y: int): void = x = x%y
proc //=(x: var int, y: int): void = x = x//y
累乗の記号は^(mathをimportすると使える)なのだけど、これも微妙に嫌なのでテンプレに書いている。
code:nim
proc **(x: int, y: int): int = x^y
好みに併せて小数などにも定義してあげてください
ビット演算
全部文字。andとかorとかxorとか
さすがにやってらんないので文字で定義しなおしておく。
code:nim
proc ^(x: int, y: int): int = x xor y
proc |(x: int, y: int): int = x or y
proc &(x: int, y: int): int = x and y
proc >>(x: int, y: int): int = x shr y
proc <<(x: int, y: int): int = x shl y
proc ~(x: int): int = not x
proc ^=(x: var int, y: int): void = x = x ^ y
proc &=(x: var int, y: int): void = x = x & y
proc |=(x: var int, y: int): void = x = x | y
proc >>=(x: var int, y: int): void = x = x >> y
proc <<=(x: var int, y: int): void = x = x << y