結果

問題 No.117 組み合わせの数
ユーザー NyanNecoNyanNeco
提出日時 2018-12-16 22:33:31
言語 Nim
(2.0.2)
結果
CE  
(最新)
AC  
(最初)
実行時間 -
コード長 3,123 bytes
コンパイル時間 814 ms
コンパイル使用メモリ 64,916 KB
最終ジャッジ日時 2024-04-27 02:45:16
合計ジャッジ時間 1,154 ms
ジャッジサーバーID
(参考情報)
judge1 / judge2
このコードへのチャレンジ
(要ログイン)
コンパイルエラー時のメッセージ・ソースコードは、提出者また管理者しか表示できないようにしております。(リジャッジ後のコンパイルエラーは公開されます)
ただし、clay言語の場合は開発者のデバッグのため、公開されます。

コンパイルメッセージ
/home/judge/data/code/Main.nim(14, 30) Warning: inherit from a more precise exception type like ValueError, IOError or OSError. If these don't suit, inherit from CatchableError or Defect. [InheritFromException]
stack trace: (most recent call last)
Main.nim(8, 9)           unpack
/home/judge/data/code/Main.nim(91, 12) template/generic instantiation of `input` from here
/home/judge/data/code/Main.nim(23, 43) template/generic instantiation of `unpack` from here
/home/judge/data/code/Main.nim(8, 9) Error: index out of bounds, the container is empty

ソースコード

diff #

from sequtils import map, mapIt
from strutils import split, parseInt, parseFloat

import macros
macro unpack*(input: seq; count: static[int]): untyped =
  result = quote do: ()
  when NimMinor <= 13:
    for i in 0..<count: result[0].add quote do: `input`[`i`]
  else:
    for i in 0..<count: result.add quote do: `input`[`i`]

## count == 0 のとき unpackしない(seq)
## count >  0 のとき count個分 unpack した結果の tuple を返す
type UnselectableTypeError = object of Exception
template input*(typ: typedesc; count: Natural = 0): untyped =
  let line = stdin.readLine.split
  when count == 0:
    when typ is int:    line.map(parseInt)
    elif typ is float:  line.map(parseFloat)
    elif typ is string: line
    else: raise newException(UnselectableTypeError, "You selected a type other than int, float or string")
  else:
    when typ is int:    line.map(parseInt).unpack(count)
    elif typ is float:  line.map(parseFloat).unpack(count)
    elif typ is string: line.unpack(count)
    else: raise newException(UnselectableTypeError, "You selected a type other than int, float or string")

template inputs*(typ: typedesc; count = 0; rows = 1): untyped =
  (1..rows).mapIt(input(typ, count))

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
template secretEcho*(x: varargs[string, `$`]) =
  for v in x:
    stderr.write(v)
  echo ""

template secretEcho*[T](x: seq[seq[T]]) =
  for v in x: secretEcho v

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
type ModComb* = ref object of RootObj
  modFacs: seq[int]
  modFacInvs: seq[int]
  MOD: int

proc modPow(n, p, m: int): int =
  if p == 0:
    1
  elif p mod 2 == 0:
    let half = modPow(n, p div 2, m)
    half * half mod m
  else:
    n * modPow(n, p - 1, m) mod m

proc newModComb*(MOD = 1_000_000_007; size = 10_000_000): ModComb =
  result = ModComb(modFacs: newSeq[int](size + 1), modFacInvs: newSeq[int](size + 1), MOD: MOD)
  result.modFacs[0] = 1
  result.modFacInvs[0] = 1

  for i in 1..size:
    result.modFacs[i] = result.modFacs[i - 1] * i mod MOD

  result.modFacInvs[size] = modPow(result.modFacs[size], MOD - 2, MOD)
  for i in countdown(size - 1, 0):
    result.modFacInvs[i] = result.modFacInvs[i + 1] * (i + 1) mod MOD

proc C*(this: ModComb; n, r: int): int =
  if r < 0 or n < r:
    0
  else:
    this.modFacs[n] * (this.modFacInvs[r] * this.modFacInvs[n - r] mod this.MOD) mod this.MOD

proc P*(this: ModComb; n, r: int): int =
  if r < 0 or n < r:
    0
  else:
    this.modFacs[n] * this.modFacInvs[n - r] mod this.MOD

proc H*(this: ModComb; n, r: int): int =
  if r == 0:
    1
  elif n == 0:
    0
  else:
    this.C(n + r - 1, r)

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
from strutils import join

let
  T = input(int, 1)
  S = inputs(string, 1, T).map(proc (s: string): seq[string] = s.split({'(', ')', ','}))
  comb = newModComb()

for s in S:
  let
    n = s[1].parseInt
    r = s[2].parseInt
  case s[0]:
    of "C":
      echo comb.C(n, r)
    of "P":
      echo comb.P(n, r)
    of "H":
      echo comb.H(n, r)
    else:
      discard
0