Emacs로 AtCoder 환경 조정

개시하다


나는 Emacs+Ruby에서 퀴즈 프로 선수를 할 때 기본적으로 필요하지 않다고 생각하지만, 동시에 비망록을 소개한다.
지령마다 뜻이 많기 때문에 의식적으로 간결하게 써서 조개껍질로 흐르게 하면 된다.
이후 Rust로 문제를 풀고 싶어 Rust용 환경도 무료로 제공할 수 있다.

루비용


atcoder-cli를 가져오기, 테스트, 제출하려면
pip3 install online-judge-tools
yarn global add atcoder-cli
acc check-oj
acc login
acc session
acc config default-test-dirname-format test
acc config default-task-choice all
acc config default-template ruby

cd ~/Library/Preferences/atcoder-cli-nodejs
mkdir ruby
cd ruby
emacsclient template.json
emacsclient main.rb

mkdir -p ~/src/procon/ruby
cd ~/src/procon/ruby
acc new math-and-algorithm
cd math-and-algorithm/001
echo "p gets.to_i + 5" > main.rb
oj t -c "ruby main.rb"
acc s main.rb -- -w 0 -y
template.json
{
  "task":{
    "program": ["main.rb"],
    "submit": "main.rb"
  }
}
main.rb
$stdin = DATA
n = gets.to_i
p gets.split.take(n).collect(&:to_i)
__END__
3
10 20 30
  • atcoder-cli의 실제 명령 이름은 acc
  • acc는 AtCoder Command line interface의 약자로 간주됨
  • atcoder-cli는 Ruby에 의존하지 않음
  • 파이톤 C++도 가능
  • Rust도 가능하지만 외부 크레인에 의존하지 않고 rustc만 있으면 컴파일할 수 있는 간단한 코드
  • 카고를 사용하지 않으면 외부 크레인과 함께 건설할 수 없나요?
  • acc config default-test-dirname-format test 중요
  • 이걸 하지 않으면 oj t -c "ruby main.rb" 움직일 수 없거나, 빠져든다거나
  • oj t -c "ruby main.rb" -d tests라면 나중에 움직일 줄 알았는데 어쨌든 빠졌어
  • 따라서 처음부터 test 만들면 -d tests 필요없어acc s -- -w 0 -y 걸지 않아
  • atcoder-cli의 테스트 디렉터리 이름에 대한 영향
  • template.제이슨에서main.rb를 제출해야 한다고 쓰여 있지만 쓸 수 없다cargo-compete는 수수께끼다
    그래서 template.json의submit의 지정은 무의미하다
  • Rust용


    cargo compoet의 가져오기, 테스트, 제출 절차
    mkdir -p ~/src/procon/rust
    cd ~/src/procon/rust
    
    cargo install cargo-compete
    cargo compete init atcoder
    cargo compete login atcoder
    rustup install 1.42.0
    
    cargo compete new math-and-algorithm
    cd math-and-algorithm/bin
    cargo compete open --bin 001
    cat <<'EOF' > 001.rs
    use proconio::input;
    fn main() {
        input! { n: isize, }
        println!("{}", n + 5);
    }
    EOF
    cargo compete test 001
    cargo compete submit --no-test --no-watch 001
    
  • cargo-atcoder는 이전에 주류였던 것 같지만 기본적인 부분이 계승되어 도입의 편의성과 사용 편의성math-and-algorithm이 더 좋다
  • 경기cargo compete open에서 브라우저가 104개의 탭을 열 수 있음을 주의하십시오
  • 5문제만 예상한 경기
  • --bin 001면 질문 001
  • 만 엽니다.
  • eshellcargo compete submit로 하면 표가 엉망진창이 됩니다--no-watch
  • 디렉터리 구조는atcoder-cli와 크게 다르다
  • 어떻게든 카고로 의존crate를 관리해야 하기 때문에 구성도 카고에 의존
  • acc에서 디렉터리 이름은 문제 색인 이름이지만 여기 파일 이름은 문제 색인 이름
  • Emacs 설정


    CLI는 무엇이든 할 수 있지만 이런 명령은 반나절 만에 잊어버리기 때문에 아래처럼 메뉴를 꺼내 한 글자를 입력하면 실행할 수 있다.

    이렇게 하면 매직 활용transient.el이 딱 좋아요.
    간단한 사용법
    (transient-define-prefix my-procon-launcher ()
      [
        ("a" "説明1" (lambda () (interactive) (message "A")))
        ("b" "説明2" (lambda () (interactive) (message "B")))
      ]
     )
    
  • a를 눌러 "A"를 표시합니다.
  • b를 눌러 B를 표시합니다.
  • 나는 이것을 끊임없이 확장해서 반자동화된 것을 추가로 생각할 것이다.
    my-procon.el
    (require 'transient)
    (require 'f)
    
    (defun my-procon-eshell-send (command)
      "eshellを現在のディレクトリに移動して指定のコマンドを実行"
      (interactive)
      (let ((dir default-directory))
        (eshell)
        (goto-char (point-max))
        (eshell-bol)
        (unless (eobp)
          (kill-line))
        (insert (format "pushd '%s'" dir))
        (eshell-send-input)
        (insert command)
        (eshell-send-input)))
    
    (transient-define-prefix my-procon-launcher ()
      "競プロ用ランチャー"
      ["Ruby"
       ("i" "問題情報入力"
        (lambda ()
          (interactive)
          (beginning-of-buffer)
          (insert (shell-command-to-string (format "ruby -e \"
    require 'pathname'
    require 'json'
    file = Pathname('../contest.acc.json')
    info = JSON.parse(file.read, symbolize_names: true)[:tasks].find { |e| e[:label].casecmp?(ARGV[0]) }
    puts '# [' + info[:label] + '] ' + info[:title]
    puts '# ' + info[:url]
    \" %s" (f-filename (f-dirname (buffer-file-name))))))))
       ("o" "問題URLをブラウザで開く"
        (lambda ()
          (interactive)
          (beginning-of-buffer)
          (shell-command (format "ruby -e \"
    require 'pathname'
    require 'json'
    file = Pathname('../contest.acc.json')
    info = JSON.parse(file.read, symbolize_names: true)[:tasks].find { |e| e[:label].casecmp?(ARGV[0]) }
    system 'open ' + info[:url]
    \" %s" (f-filename (f-dirname (buffer-file-name)))))))
       ("1" "単体実行"
        (lambda ()
          (interactive)
          (set (make-local-variable 'compile-command) "ruby main.rb")
          (call-interactively 'compile)))
       ("t" "テスト"
        (lambda ()
          (interactive)
          (set (make-local-variable 'compile-command) "oj t -c 'ruby main.rb'")
          (call-interactively 'compile)))
       ("s" "提出"
        (lambda ()
          (interactive)
          (my-procon-eshell-send "acc s main.rb -- -w 0 -y")))
       ("l" "問題一覧の確認"
        (lambda ()
          (interactive)
          (my-procon-eshell-send "acc tasks")))
       ("c" "コンテスト名の確認"
        (lambda ()
          (interactive)
          (my-procon-eshell-send "acc contest")))
       ("n" "次の問題を取得"
        (lambda ()
          (interactive)
          (my-procon-eshell-send "acc add -c next")))
       ("e" "テンプレート編集"
        (lambda ()
          (interactive)
          (find-file "~/Library/Preferences/atcoder-cli-nodejs/ruby/main.rb")))
       ("z" "設定"
        (lambda ()
          (interactive)
          (dired "~/Library/Preferences/atcoder-cli-nodejs")))
       ]
      ["Rust"
       ("rt" "テスト (cargo compete test)"
        (lambda ()
          (interactive)
          (set (make-local-variable 'compile-command) (format "cargo compete t %s" (f-base (buffer-file-name))))
          (call-interactively 'compile)))
       ("rs" "提出 (cargo compete submit)"
        (lambda ()
          (interactive)
          (my-procon-eshell-send (format "cargo compete s --no-test --no-watch %s" (f-base (buffer-file-name))))))
       ]
      )
    
    ;; (my-procon-launcher)
    ;; (global-set-key (kbd "C-j p") 'my-procon-launcher)
    
  • 설명문을 독특하게 하다
  • 동일한 명령으로 간주
  • 끝맺다


    자신의 상황은 대부분 아래의 순서에 따라 진행한다.
  • i→문제 정보 입력
  • o→ 브라우저에서 질문 URL 열기
  • 1→단일 실행
  • t→테스트
  • s→제출
  • n→다음 질문 받기
  • Emacs를 사용한 더 간단한 CLI 반자동화 작업에 대해 설명합니다.

    인용하다


    http://tatamo.81.la/blog/2018/12/07/atcoder-cli/
    https://github.com/online-judge-tools/oj
    https://github.com/qryxip/cargo-compete
    https://github.com/magit/transient

    좋은 웹페이지 즐겨찾기