文書の過去の版を表示しています。
AtCoder
競技プログラミングサイトの1つ。
プログラム的に解けるような問題が出題されるので、入力から正しい答えを出力できるプログラムを書く。ちゃんと出力があってたら正解。合計得点や回答の速さを競う。
ステキ周辺サービス(公式とは限らない)
関連記事
登録
入出力
最初に解くべき問題
PythonでAtCoder
競技プログラミングは計算速度が求められるため、基本的に C++ などの高速なコンパイル言語を使うことが半ば暗黙の常識となっている面がある。
Pythonはスクリプト言語で、計算速度は速いとは言えない、というか遅い。
だが、AtCoderでは1000点~などの高難度の問題でもない限り、きちんと実装すればほとんどの問題は通る。
この「きちんと実装すれば」がポイントで、逆に言うと C++ などでは多少効率の悪いプログラムを書いても通ってしまうことがあるが、Pythonだとなかなかそうはいかない。
ポジティブに考えると、それだけアルゴリズムを正しく使いこなす力が身につくって事だね!(本当か?)
メリット
デメリット
遅い
難しい問題はPythonで挑戦している人が少ないので、参考に出来るコードが無いことが多い
他の競技プログラミングサイトでは、AtCoderほどPythonでも通せることに配慮されてない、かも
Pythonの強みである豊富な第三者モジュールがあまり使えないので、自前で実装する必要があることがある
競技プログラミングを「競技」として勝ちにこだわるのであれば、最初から C++ やるか、少なくともPythonと平行で C++ などを書けた方がいいだろなあという気はする。
Python他の高機能言語も、計算量が問題にならない問題に対しては簡単に素早く書けるというメリットはあるとは思う。
従って理想を言うなら言語の選択肢は多い方がいいが、その判断が競技中に適切に出来るかというと……まぁ難しいので、基本は高速な言語を優先した方がいい。
そうでは無くて、言語の習得がてらとか、元からPythonやってたとかで、敷居低く楽しみながら参加するのであれば、「Pythonでも十分戦えるよ」ということは言えると思う。
Python3ライブラリ・テクニック・読み物
個人用dokuwiki記事用てんぷれ
Dokuwiki記事用テンプレート自動生成Pythonスクリプト(コンテスト名・問題名・リンクを埋める)
開催中のコンテストなど、ログインが必要なコンテストでも取得するべくセッションを利用するように変更。(参考: GitHub - kyuridenamida/atcoder-tools: Convenient modules & tools for AtCoder users, written in Python 3.5)
import os
from typing import Optional
from http.cookiejar import LWPCookieJar
import pyperclip
import requests
import bs4
CONTEST = 'abc124'
USERNAME = ''
PASSWORD = ''
url_root = 'https://atcoder.jp'
default_cookie_path = os.path.dirname(__file__) + '/session.txt'
def dokuwiki_link(url, title):
return '[[' + url + '|' + title + ']]'
def save_cookie(session: requests.Session, cookie_path: Optional[str] = None):
cookie_path = cookie_path or default_cookie_path
os.makedirs(os.path.dirname(cookie_path), exist_ok=True)
session.cookies.save()
os.chmod(cookie_path, 0o600)
def load_cookie_to(session: requests.Session, cookie_path: Optional[str] = None):
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 + '/login'
# ユーザー名がログインページに含まれるかで、ログイン状態を判定
# もしユーザー名が一般的で非ログイン時でも当てはまってしまう場合はもう少し工夫が必要
r = session.get(login_url)
if USERNAME in r.text:
# print('Already logged in.')
return True
# csrf_token取得
s = bs4.BeautifulSoup(r.text, 'lxml')
csrf_token = s.find(attrs={'name': 'csrf_token'}).get('value')
post_data = {
"csrf_token": csrf_token,
"username": USERNAME,
"password": PASSWORD,
}
r = session.post(login_url, data=post_data)
if 'tokens mismatch.' in r.text:
print('Login error.')
print(r.text)
return False
save_cookie(session)
return True
def main():
# セッション開始
session = requests.Session()
load_cookie_to(session)
if try_login(session):
pass
else:
return
tasks_url = url_root + f'/contests/{CONTEST}/tasks'
r = session.get(tasks_url)
bs = bs4.BeautifulSoup(r.text, 'lxml')
problem_urls = []
tbl = bs.find('table').find('tbody')
for tr in tbl.find_all('tr'):
problem_url = tr.find('td').find('a').get('href')
problem_urls.append(problem_url)
contest_title = bs.select('#main-div a.contest-title')[0]
dokuwiki_buf = []
dokuwiki_buf.append('======' + contest_title.text + '======\n\n')
dokuwiki_buf.append(dokuwiki_link(url_root + contest_title.get('href'), contest_title.text) + '\n\n')
for problem_url in problem_urls:
problem_url = url_root + problem_url
r = session.get(problem_url)
bs = bs4.BeautifulSoup(r.text, 'lxml')
title = bs.find('title').text
dokuwiki_buf.append('===== ' + title + ' =====\n\n')
dokuwiki_buf.append(dokuwiki_link(problem_url, title) + '\n\n')
dokuwiki_buf.append('==== 問題 ====\n\n\n')
dokuwiki_buf.append('==== 例 ====\n\n\n')
dokuwiki_buf.append('==== 解法 ====\n\n\n')
dokuwiki_buf.append('<sxh python>\n\n\n< /sxh>\n\n\n')
# print(''.join(dokuwiki_buf))
pyperclip.copy(''.join(dokuwiki_buf))
if __name__ == '__main__':
main()
41行目の</sxh>が干渉しちゃうのでスペース入れてるけど、取る。