Red-Green-Code

Deliberate practice techniques for software developers

  • Home
  • About
  • Contact
  • Project 462
  • CP FAQ
  • Newsletter

Command-Line Tools for Competitive Programming

By Duncan Smith Feb 3 4

Command Line

When they select their tools, programmers have a choice between command-line and GUI options. Most people use both. For example, I prefer to use GUI tools for diffing a set of files I’m preparing to commit to a source repository. I also like my editor to be graphical, though I use a lot of keyboard shortcuts. But command-line tools are preferable when I’ll be repeating the same action multiple times. It’s a lot more efficient to retrieve a typed command from the shell history than to do the same steps repeatedly using mouse clicks or even keyboard shortcuts. Today I’ll be explaining some commands that are useful for programming puzzles.

UVa OJ Submission

When I’m executing my puzzle solution process, I keep a lot of windows open: two editor windows (one for code, one for notes), a command prompt, and a few browser windows/tabs for sites like uHunt, uDebug, and Stack Overflow. I run local tests from the command line, but eventually I have to open the UVa OJ site to make an official submission. I recently tried out a way to do that from the command line.

uva-node is a Node.js-based command-line interface to UVa Online Judge. Here are the steps you can use to make your first command-line submission.

Install Node.js

uva-node runs in Node.js, which you can install from the Node.js home page. When I installed it, I used the installer’s suggested settings.

Install uva-node using npm

npm is the Node Package Manager, which installs by default with Node.js. Once Node is installed, you can run this at a command prompt:

npm install -g uva-node

If all goes well, you’ll see the names of the directories the installer is using, and a list of uva-node dependencies and versions.

Run uva-node

Next, you’ll want to run uva from a command prompt, which launches the interactive environment. The first time you run uva-node, you’ll see:

>uva
Setting file not found: (path)\.uva-node
A new one will be auto-created after exiting the program

Add your UVa account

To use uva-node, you have to add your UVa account and set it as current:

> add uva duncans (password)
Account added successfully

> use uva duncans
Account set as current

The account and password are the ones you use to log in to UVa Online Judge.

Submit a solution

uva-node has a few features that I didn’t try, like opening a problem statement by number, and launching an editor. It can also infer the source filename based on a problem number. Since all Java submissions to UVa OJ are named Main.java, this probably wouldn’t work for Java solutions. However, the send command accepts a full path to the solution file, so you don’t have to rely on uva-node figuring it out:

> send 1047 (path)\Main.java
Logging in...
Sending code...
Send ok

At this point, the solution is off to UVa Online Judge. I would then use the uHunt web site to monitor progress, since it automatically updates results as UVa OJ processes the submission. However, for a completely command-line solution, uva-node has a stat command that returns the status of the most recent submissions for the current user.

And that’s it. A painless process for submitting a solution without visiting the UVa OJ website.

Local Development and Testing

Before I tried out uva-node, I was already using some of my own command-line tools for developing and testing puzzle solutions in my local environment. Here’s how they work.

Setup

In the early stages of my problem-solving process, I run a shell script that accepts the UVa OJ problem number, like this:

> uva 1047

This command does the following:

  • Create a directory called 1047
  • Copy various template files into that directory, including Main.java with template code, text files for input and output, a 1047.txt notes file with sections for each step in the process, and several shell scripts.
  • Change to that directory.
  • Open the files in an editor.

After I run that command, I can immediately start taking notes on the problem in 1047.txt. Then once I have a plan of attack and a pseudocode solution, I can move on to Main.java, which is already open in my editor.

Code/Compile/Test

When I think I have some working code, I run this simple command:

> go

It does the following:

  • Compile Main.java.
  • Run Main, using input.txt as input.

Since I previously copied the sample input from the problem statement into input.txt, this is the first basic test of my program. It begins a code/compile/test cycle that continues until my output matches the sample output.

My go script accepts an optional second parameter, an integer that indicates which input file to use. Without a parameter, it uses input.txt. If I run go 2, then it uses input2.txt. I use input2.txt for the random input supplied by uDebug. Once I can produce the correct output for that input, I usually make an official submission to UVa OJ. If that submission isn’t accepted, I continue testing with input3.txt, input4.txt, etc. to narrow down the bug or performance issue.

When I’m having trouble writing the syntax that the compiler wants, and I’m getting compiler errors, I use a version of the go script called goc, which just executes the compile step. That allows me to fix compiler errors without worrying about output yet. I have an analogous script called gor for just the run step.

Diff

For problems with more than a few lines of output, it’s an error-prone process to compare my program output with the correct output. To facilitate this process, I wrote another version of the go script called goo. You can think of goo as “go with output comparison.” Like go, the goo script accepts an optional second parameter. So I can run this:

> goo 2

This command does the following:

  • Compile Main.java.
  • Run Main.class, using input2.txt as input, and writing output to output2.txt.
  • Diff output2.txt with output2-check.txt.

output2-check.txt is the accepted output that I previously copied from uDebug. The goo script provides a quick way to verify that my latest code change has fixed the bug I’m working on, and hasn’t broken anything that was previously working. If I have accumulated a few test input files, I can quickly run goo, goo 2, goo 3 and so on to make sure everything works as expected before I submit. This makes goo a kind of unit test suite. For a small set of tests, it’s almost as convenient as a jUnit run.

Since I started using my goo script, the uDebug team has added their own diff tool to the website. Their diff is convenient for quick checks, but it involves more copying and pasting than my command-line approach.

Test

Speaking of jUnit, I have one last script called test that does the following:

  • javac Main.java MainTest.java
  • java org.junit.runner.JUnitCore MainTest

This script runs unit tests and reports the results. I use it for puzzles that are complicated enough to require writing unit tests for sections of the code rather than testing the whole program at once.

Advantages of the Command Line

I’m not a command-line purist like 1990s-era Neal Stephenson. I do plenty of mouse clicking and window resizing as I’m working on puzzles. However, there are cases where a command-line approach is more efficient. UVa OJ solutions lend themselves to the command-line approach because they involve short single-file programs that read from stdin and write to stdout. Having shell scripts around to take care of things you do repeatedly can help move you through your solutions faster.

(Image credit: Osama Khalid)

Categories: Competitive Programming

Prev
Next

Stay in the Know

I'm trying out the latest learning techniques on software development concepts, and writing about what works best. Sound interesting? Subscribe to my free newsletter to keep up to date. Learn More
Unsubscribing is easy, and I'll keep your email address private.

Getting Started

Are you new here? Check out my review posts for a tour of the archives:

  • Lessons from the 2020 LeetCode Monthly Challenges
  • 2019 in Review
  • Competitive Programming Frequently Asked Questions: 2018 In Review
  • What I Learned Working On Time Tortoise in 2017
  • 2016 in Review
  • 2015 in Review
  • 2015 Summer Review

Archives

Recent Posts

  • LeetCode 227: Basic Calculator II January 13, 2021
  • A Project for 2021 January 6, 2021
  • Lessons from the 2020 LeetCode Monthly Challenges December 30, 2020
  • Quora: Are Math Courses Useful for Competitive Programming? December 23, 2020
  • Quora: Are Take-Home Assignments a Good Interview Technique? December 17, 2020
  • Quora: Why Don’t Coding Interviews Test Job Skills? December 9, 2020
  • Quora: How Much Time Should it Take to Solve a LeetCode Hard Problem? December 2, 2020
  • Quora: Quantity vs. Quality on LeetCode November 25, 2020
  • Quora: LeetCode Research November 18, 2020
  • Quora: Optimal LeetCoding November 11, 2020
Red-Green-Code
  • Home
  • About
  • Contact
  • Project 462
  • CP FAQ
  • Newsletter
Copyright © 2021 Duncan Smith