差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン最新のリビジョン両方とも次のリビジョン | ||
programming_algorithm:contest_history:atcoder [2019/04/15] – [PythonでAtCoder] ikatakos | programming_algorithm:contest_history:atcoder [2019/11/06] – [PythonでAtCoder] ikatakos | ||
---|---|---|---|
行 16: | 行 16: | ||
* コンテスト終了後に復習しやすい | * コンテスト終了後に復習しやすい | ||
* 他の人の解答が見られる | * 他の人の解答が見られる | ||
- | * 多くの問題に対して、出題者または運営による解説PDFがアップロードされる | + | * 定例的なコンテストに対して、出題者または運営による解説PDFがアップロードされる |
- | * YouTubeで解説生放送が開かれる | + | * 定例的なコンテストに対して、YouTubeで解説生放送が開かれる |
=====ステキ周辺サービス(公式とは限らない)===== | =====ステキ周辺サービス(公式とは限らない)===== | ||
* [[https:// | * [[https:// | ||
- | * 過去問を、自身やライバルの AC済み/ | + | * 過去問を、自身やライバルの AC済み/ |
+ | * 自分の解いた問題の難易度に合わせ、次に解けそうな未挑戦の問題を提案してくれる | ||
+ | * ユーザのStreak数、A問題, | ||
* [[https:// | * [[https:// | ||
* 過去問をスコア別に集計、自身やライバルのACしたスコア分布などを一覧できる | * 過去問をスコア別に集計、自身やライバルのACしたスコア分布などを一覧できる | ||
+ | * [[https:// | ||
+ | * 参加したコンテストの順位の時間変動を見られる | ||
* [[https:// | * [[https:// | ||
* 過去問を使って疑似コンテストを行える | * 過去問を使って疑似コンテストを行える | ||
* [[https:// | * [[https:// | ||
* レーティングを使って企業と求職者をマッチング | * レーティングを使って企業と求職者をマッチング | ||
+ | |||
+ | * 拡張 | ||
+ | * [[https:// | ||
+ | * 学習用言語Scratchで解ける(%%C++%%に変換して提出してくれる) | ||
+ | * [[https:// | ||
+ | * 公式ページの参加者やパフォーマンス表示箇所の横に、レーティングに応じた色付きの円を追加 | ||
+ | * [[http:// | ||
+ | * Dropbox上にテストケースが公開されている過去問は、提出詳細ページの各テストケース名の横に入力・出力へのリンクを追加 | ||
=====関連記事===== | =====関連記事===== | ||
行 54: | 行 66: | ||
Pythonはスクリプト言語で、計算速度は速いとは言えない、というか遅い。 | Pythonはスクリプト言語で、計算速度は速いとは言えない、というか遅い。 | ||
- | だが、AtCoderでは1000点~などの高難度の問題でもない限り、きちんと実装すればほとんどの問題は通る。 | + | だが、AtCoderでは1000点~などの高難度の問題でもない限り、きちんと実装すればほとんどの問題は通る。(注: 高難度の問題も多くは通るはず。ただし自分が多くは解けてないので、その割合は知らない) |
この「きちんと実装すれば」がポイントで、逆に言うと %%C++%% などでは多少効率の悪いプログラムを書いても通ってしまうことがあるが、Pythonだとなかなかそうはいかない。 | この「きちんと実装すれば」がポイントで、逆に言うと %%C++%% などでは多少効率の悪いプログラムを書いても通ってしまうことがあるが、Pythonだとなかなかそうはいかない。 | ||
行 61: | 行 73: | ||
* メリット | * メリット | ||
- | * 学びやすい | ||
* 環境構築しやすい | * 環境構築しやすい | ||
* 記述量が少ない | * 記述量が少ない | ||
- | * 整数だろうとリストだろうと '' | ||
* 最近、機械学習とかで流行りなので、本業の分野によっては知識を相互に活かせる | * 最近、機械学習とかで流行りなので、本業の分野によっては知識を相互に活かせる | ||
- | * AtCoderでは、PyPyという、Pythonコードを高速に実行する言語を使うことができる | ||
- | * ごく稀に使えるライブラリが異なることがあるが、基本的に同じコードで動き、書き換えの必要は無い | ||
- | * これにより、スクリプト言語では計算量が厳しい問題でも通せたりする | ||
* [[https:// | * [[https:// | ||
+ | * AtCoderでは、PyPyという、Pythonコードを高速に実行する実行時コンパイル言語を使うことができる | ||
+ | * NumPyなど一部のライブラリが使えないが、基本的に同じコードで動き、書き換えの必要は無い | ||
+ | * これにより、一般的なスクリプト言語では計算量が厳しい問題でも、PyPyなら通せたりする | ||
* デメリット | * デメリット | ||
* 遅い | * 遅い | ||
- | | + | |
- | * でも競プロで使うのは限られてるし、最近の高機能言語はこれぐらい普通かも | + | |
- | * 標準ライブラリの多くはC言語で実装されていて同じ処理を直に書くより高速なので、使うことが必須になる場面も | + | |
* 難しい問題はPythonで挑戦している人が少ないので、参考に出来るコードが無いことが多い | * 難しい問題はPythonで挑戦している人が少ないので、参考に出来るコードが無いことが多い | ||
+ | * %%C++%%、Java以外のほとんどの言語に同じ事が言えるかも | ||
* 他の競技プログラミングサイトでは、AtCoderほどPythonでも通せることに配慮されてない、かも | * 他の競技プログラミングサイトでは、AtCoderほどPythonでも通せることに配慮されてない、かも | ||
+ | * AtCoderでは、特にABCなどでは、遅い言語にも配慮されている感じがする(※個人の感想) | ||
+ | * だからといって別に全ての言語で通せる保証が無いことはきちんと明言されているので、通らなくても文句は言わない | ||
+ | * Pythonの強みである豊富な第三者モジュールがあまり使えないので、自前で実装する必要があることがある | ||
+ | 競技プログラミングを「競技」として勝ちにこだわるのであれば、最初から %%C++%% やるか、少なくともPythonと平行で %%C++%% などを書けた方がいいだろなあという気はする。 | ||
- | ====Python3ライブラリ・テクニック==== | + | Python他の高機能言語も、計算量が問題にならない問題に対しては簡単に素早く書けるというメリットはあるとは思う。 |
+ | 従って理想を言うなら両刀使いが強そうだが、言語の切り替え判断が競技中に適切に出来るかというと……まぁ難しいので、基本は高速な言語を優先した方がいい。 | ||
+ | |||
+ | そうでは無くて、言語の習得がてらとか、元からPythonやってたとかで、敷居低く楽しみながら参加するのであれば、「Pythonでも十分戦えるよ」ということは言えると思う。 | ||
+ | |||
+ | |||
+ | ====Python3ライブラリ・テクニック・読み物==== | ||
* [[http:// | * [[http:// | ||
* [[https:// | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
行 88: | 行 109: | ||
++++ Dokuwiki記事用テンプレート自動生成Pythonスクリプト(コンテスト名・問題名・リンクを埋める)| | ++++ Dokuwiki記事用テンプレート自動生成Pythonスクリプト(コンテスト名・問題名・リンクを埋める)| | ||
+ | |||
+ | 開催中のコンテストなど、ログインが必要なコンテストでも取得するべくセッションを利用するように変更。(参考: | ||
+ | |||
+ | |||
<sxh python> | <sxh python> | ||
import os | import os | ||
+ | from typing import Optional | ||
+ | from http.cookiejar import LWPCookieJar | ||
+ | import pyperclip | ||
import requests | import requests | ||
import bs4 | import bs4 | ||
- | import pyperclip | ||
- | contest | + | CONTEST |
+ | |||
+ | USERNAME = '' | ||
+ | PASSWORD = '' | ||
+ | |||
+ | url_root = ' | ||
+ | default_cookie_path = os.path.dirname(__file__) + '/ | ||
def dokuwiki_link(url, | def dokuwiki_link(url, | ||
return ' | return ' | ||
+ | |||
+ | |||
+ | def save_cookie(session: | ||
+ | cookie_path = cookie_path or default_cookie_path | ||
+ | os.makedirs(os.path.dirname(cookie_path), | ||
+ | session.cookies.save() | ||
+ | os.chmod(cookie_path, | ||
+ | |||
+ | |||
+ | def load_cookie_to(session: | ||
+ | cookie_path = cookie_path or default_cookie_path | ||
+ | session.cookies = LWPCookieJar(cookie_path) | ||
+ | if os.path.exists(cookie_path): | ||
+ | session.cookies.load() | ||
+ | return True | ||
+ | return False | ||
+ | |||
+ | |||
+ | def try_login(session): | ||
+ | login_url = url_root + '/ | ||
+ | |||
+ | # ユーザー名がログインページに含まれるかで、ログイン状態を判定 | ||
+ | # もしユーザー名が一般的で非ログイン時でも当てはまってしまう場合はもう少し工夫が必要 | ||
+ | r = session.get(login_url) | ||
+ | if USERNAME in r.text: | ||
+ | # print(' | ||
+ | return True | ||
+ | |||
+ | # csrf_token取得 | ||
+ | s = bs4.BeautifulSoup(r.text, | ||
+ | csrf_token = s.find(attrs={' | ||
+ | |||
+ | post_data = { | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | } | ||
+ | r = session.post(login_url, | ||
+ | if ' | ||
+ | print(' | ||
+ | print(r.text) | ||
+ | return False | ||
+ | |||
+ | save_cookie(session) | ||
+ | return True | ||
def main(): | def main(): | ||
- | | + | |
- | | + | |
+ | load_cookie_to(session) | ||
+ | |||
+ | if try_login(session): | ||
+ | pass | ||
+ | else: | ||
+ | return | ||
- | r = requests.get(tasks_url) | + | |
+ | | ||
bs = bs4.BeautifulSoup(r.text, | bs = bs4.BeautifulSoup(r.text, | ||
行 122: | 行 207: | ||
for problem_url in problem_urls: | for problem_url in problem_urls: | ||
problem_url = url_root + problem_url | problem_url = url_root + problem_url | ||
- | r = requests.get(problem_url) | + | r = session.get(problem_url) |
bs = bs4.BeautifulSoup(r.text, | bs = bs4.BeautifulSoup(r.text, | ||
title = bs.find(' | title = bs.find(' | ||
行 130: | 行 215: | ||
dokuwiki_buf.append(' | dokuwiki_buf.append(' | ||
dokuwiki_buf.append(' | dokuwiki_buf.append(' | ||
- | dokuwiki_buf.append('< | + | dokuwiki_buf.append('< |
+ | # print('' | ||
pyperclip.copy('' | pyperclip.copy('' | ||
行 137: | 行 223: | ||
if __name__ == ' | if __name__ == ' | ||
main() | main() | ||
+ | |||
</ | </ | ||