Skip to content

Instantly share code, notes, and snippets.

@krofna
Last active February 22, 2019 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krofna/61d8d0f8854786b9b475f4a9cbb5aa4c to your computer and use it in GitHub Desktop.
Save krofna/61d8d0f8854786b9b475f4a9cbb5aa4c to your computer and use it in GitHub Desktop.
;;; uva.el --- interface to UVa online judge
;;; Commentary:
;;; Code:
(require 'json)
(require 'cc-mode)
(require 'cl)
(defconst uva-dir "~/Hacking/uva/")
(defconst uva-pdf-dir "~/Hacking/uva/pdf/")
(defconst uva-id "831136")
(defconst uva-last-subs 10)
(defconst uva-base "https://uhunt.onlinejudge.org/api/")
(defconst uva-subs-user-last (concat uva-base "subs-user-last/"))
(defconst uva-pid (concat uva-base "p/id/"))
(defconst uva-verdict '((10 . "Submission error")
(15 . "Can't be judged")
(20 . "In queue")
(30 . "Compile error")
(35 . "Restricted function")
(40 . "Runtime error")
(45 . "Output limit")
(50 . "Time limit")
(60 . "Memory limit")
(70 . "Wrong answer")
(80 . "PresentationE")
(90 . "Accepted")))
(defconst uva-lang '((1 . "ANSI C")
(2 . "Java")
(3 . "C++")
(4 . "Pascal")
(5 . "C++11")))
(defvar uva-loop nil)
(defvar uva-last-id 0)
(defun uva-format-sub (s n)
"Pretty print N th element of submition S."
(let ((a (aref s n)))
(cond
((= n 1) (cdr (nth 2 (uva-get-prob a))))
((= n 2) (cdr (assoc a uva-verdict)))
((= n 3) (number-to-string (/ a 1000.0)))
((= n 4) (format-time-string "%F %T" (seconds-to-time a)))
((= n 5) (cdr (assoc a uva-lang)))
(t (int-to-string a)))))
(defun uva-print-sub(s)
"Pretty print submition S."
(loop for i from 1 to 6 do (insert (uva-format-sub s i) " "))
(insert "\n"))
(defun uva-print-last(n)
"Pretty print last N submissions."
(let ((sub-list (cdar (last (uva-get-subs n)))))
(loop for j from (- n 1) downto 0 do (uva-print-sub (aref sub-list j)))))
(defun uva-refresh ()
"Periodically update *uva* buffer (if visible)."
(if (get-buffer "*uva*")
(when (get-buffer-window "*uva*")
(with-current-buffer "*uva*"
(erase-buffer)
(uva-print-last uva-last-subs)))
(setq uva-loop nil))
(when uva-loop (run-at-time 1 nil 'uva-refresh)))
(defun uva-status ()
"Switch to uva buffer."
(interactive)
(switch-to-buffer "*uva*")
(unless uva-loop
(setq uva-loop t)
(uva-refresh)))
(defun uva-get-subs (n)
"Get N last submition jsons from uhunt."
(uva-get-json (concat uva-subs-user-last uva-id "/" (int-to-string n))))
(defun uva-get-prob (n)
"Get info about problem N from uhunt."
(uva-get-json (concat uva-pid (int-to-string n))))
(defun uva-get-json (url)
"Get json from URL."
(with-current-buffer (url-retrieve-synchronously url)
(goto-char (point-min))
(re-search-forward "^$")
(delete-region (point) (point-min))
(json-read-from-string (buffer-string))))
(defun uva-feedback ()
"Feedback from last uva submition."
(interactive)
(let ((verdict (aref (aref (cdar (last (uva-get-subs 1))) 0) 2)))
(let ((vpair (assoc verdict uva-verdict)))
(when vpair
(message (cdr vpair)))
vpair)))
(defun compile-exec-cpp ()
"Compile and run cpp program."
(interactive)
(let ((exec (if (string= major-mode "python-mode")
(concat "python " (buffer-name))
(concat "g++ -g -std=c++17 -fsanitize=address -fsanitize=undefined -D_GLIBCXX_DEBUG " (buffer-name) " && ./a.out"))))
(kill-cpp)
(save-buffer)
(when (get-buffer "in")
(set-buffer "in")
(save-buffer)
(setq exec (concat exec " < in")))
(unless (get-buffer "out")
(find-file-other-window "out"))
(set-buffer "out")
(erase-buffer)
(start-process-shell-command "cpp-prog" "out" exec)))
(defun kill-cpp ()
"Kill cpp program."
(interactive)
(when (get-process "cpp-prog")
(delete-process "cpp-prog")))
(defun find-uva (uva)
"Download and open uva problem UVA."
(interactive "sProblem ID: ")
(let ((fn) (url) (vol))
(setq fn (concat uva-pdf-dir uva ".pdf"))
(unless (file-exists-p fn)
(setq vol (substring uva 0 -2))
(setq url (concat "https://uva.onlinejudge.org/external/" vol "/" uva ".pdf"))
(url-copy-file url fn))
(find-file fn)))
(defun uva-tick ()
"Start checking uhunt for new submition."
;(run-at-time 2 nil 'uva-update)
)
(defun uva-update (&optional r)
"Check uhunt for new submition. R is ignored."
(let ((new-id (aref (aref (cdar (last (uva-get-subs 1))) 0) 0)))
(if (and (/= new-id uva-last-id) (uva-feedback))
(setq uva-last-id new-id)
(uva-tick))))
(defun uva-send ()
"Submit a solution to uva problem."
(interactive)
(save-buffer)
(let ((args (concat "send " (substring (buffer-name) 0 -4) " " (buffer-name))))
(async-start-process "uva" "uva" (lambda (r) (message "Upload done.") (uva-tick)) args)))
(defun uva-split ()
"Create windows for uva input and output."
(with-selected-window (split-window-below)
(switch-to-buffer (get-buffer-create "in"))
(write-file "in")
(select-window (split-window-right))
(switch-to-buffer (get-buffer-create "out"))))
(defun uva (uva)
"Start uva mode with problem UVA."
(interactive "sProblemID: ")
(delete-other-windows)
(find-file (concat uva-dir uva ".cpp"))
(uva-split))
(defun uva-ide (uva)
"Start uva ide with problem UVA."
(interactive "sProblemID: ")
(delete-other-windows)
(find-file (concat uva-dir uva ".cpp"))
(unless (memq (frame-parameter nil 'fullscreen) '(fullscreen fullboth))
(toggle-frame-fullscreen))
(with-selected-window (split-window-right)
(find-uva uva))
(uva-split))
(define-key c++-mode-map (kbd "<f5>") 'compile-exec-cpp)
(define-key c++-mode-map (kbd "<f6>") 'kill-cpp)
(define-key c++-mode-map (kbd "<f7>") 'uva-send)
(add-hook 'python-mode-hook
'(lambda () (define-key python-mode-map (kbd "<f5>") 'compile-exec-cpp)))
(provide 'uva)
;;; uva.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment