Edited at

[Python] AtCoderで使えるPythonのversionは3.4.3


はじめに

皆さんはAtCoderで使用できる言語のversionは意識したことがあるでしょうか?

AtCoderに慣れるために過去問を解いていたところ、思わぬ落とし穴に落ちました。

今回は、version違いによるミスを書いていきます。


問題

今回の問題を以下に載せます。

C - Anti-Division


考え方

問題内容はシンプルで、整数$A~D$のうち、$A$以上$B$以下で、$C$でも$D$でも割り切れないものの個数を求めるという問題。

$A$以上$B$以下で、$C$でも$D$でも割り切れないものの個数を直接求めるよりは、$C$または$D$で割り切れる個数を、$A$以上$B$以下の個数から引くほうが簡単そうなのでその方法で行きます。

$C$または$D$で割り切れる個数は、$C$で割り切れる個数と$D$で割り切れる個数の合計から、$C$かつ$D$で割り切れる個数を引けば求められます。そのため、$C$と$D$の最小公倍数を求める必要があります。


実際に書いたコード

最小公倍数を求めるには、最大公約数を求める必要があります。調べてみると、Pythonには便利なことにmathモジュールにあるgcd()関数で最大公約数を求めることが出来ます。

書いたコードが以下になります。


C_Anti_Division

from sys import stdin

import math

def lcm(x, y):
return (x * y) // math.gcd(x, y)

def main():
A, B, C, D = [int(x) for x in stdin.readline().rstrip().split()]

C_D_lcm = lcm(C, D)

z = B//C_D_lcm - A//C_D_lcm

if A % C == 0:
x = (B//C) + 1 - (A//C)
else:
x = (B//C) - A//C

y = B//D - A//D

print((B-A+1)-(x+y-z))

if __name__ == "__main__":
main()



結果

実際に提出してみると結果はRE。

おかしい。自分の環境では確かに動いたはず。

もう一度自分の環境で動かしてみると、

$ python3 C_Anti_Division.py

314159265358979323 846264338327950288 419716939 937510582
532105071133627368

正しく動きました。


REの原因はversion違い!

リファレンスで調べてみると、math.gcd()はversion3.5に追加されたみたいです。AtCoderのPythonはversion3.4.3なので、使用できないのです。

さらに調べていくと、version3.4以前はmathモジュールではなくfractionsモジュールにgcd()関数があるみたいです。

mathモジュールではなくfractionsモジュールに変更したところ、無事に通りました。

ちなみに、fractionsモジュールのgcd()はversion3.5から非推奨らしく、version3.7.3で使用するとmath.gcd()を薦めてきます。

$ python3 -V

Python 3.7.3
$ python3 C_Anti_Division.py
314159265358979323 846264338327950288 419716939 937510582
C_Anti_Division.py:6: DeprecationWarning: fractions.gcd() is deprecated. Use math.gcd() instead.
return (x * y) // fractions.gcd(x, y)
532105071133627368


AtCoderで使用できる言語のversion

AtCoderで使用できる言語のversionはコンテストごとのルールに記載されています。

言語によっては使用できるライブラリ(Python3ではnumpy,scipy,scipy,C++ではBoostなど)があります。

また、コンテストによっては使えないものもあるので、参加する前にルールを確認したほうがいいかもしれません。

今回のコンテストで使用できる言語のversion一覧は以下になります。

https://atcoder.jp/contests/abc131/rules


まとめ

AtCoderと自分の環境を同じversionにしましょう。そうすればこのようなミスは起きません。

もし、今までversionを気にしずに解いていたのなら、このようなことが起こりえることを意識していただきたいです。