Use make to ease standard input of competition pro (AtCorder) C ++ / Java / Python sample Makefile posted

Introduction

Recently, competitive programming has become popular among student programmers and active programmers (experience). I don't participate in contests, but I often solve competition pro problems as a test shot when learning a new language. It's quite interesting.

The problem is usually ** input examples are provided, but isn't it a hassle ** to input them as standard? I want to automate it if possible. ** If you automate it, you can expect more efficient trial and error and higher score **! There are many ways to automate it, but this article will show you how to use the make command. Makefile is for C ++, Java, Python as a sample. If you provide samples of compilation languages, Java-based languages, and scripting languages, the user will rewrite them according to the language. There is a soul.

I uploaded the Makefile and directory structure of this article to github. Please use when it is good. https://github.com/aoi-stoic/AtcorderTemplate

Assumed reader

--Those who have used the make command --Linux / Mac users --Those who input standard input for each input example → Those who think "It would be easier if it could be done automatically"

Unexpected readers

--Windows users (because I don't use windows) --Those who can write Makefile by themselves --Those who can already automate "standard input" by another method

Verification environment

OS

$ cat /etc/os-release | head -n 2
NAME="Ubuntu"
VERSION="20.04.1 LTS (Focal Fossa)"

I'm using ubuntu. Other OSs and distributions are omitted, so please read as appropriate.

C++

gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2)

Java

$ echo `javac -version` `java -version`
javac 1.8.0_265
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (build 1.8.0_265-8u265-b01-0ubuntu2~20.04-b01)
OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)

Java is suitable because I have hardly written it. If you are challenging the contest in Java, please choose the version that matches the contest.

Python3

$ python3 --version
Python 3.8.2

Things that are not used such as virtual environment

How to use

Pseudo-contest ABCXXX A problem "Receive four standard inputs and output the sum as standard" is used as a theme to present a working directory construction and make command execution example. Solve in C ++.

A problem input and output examples are as follows ** Input example 1 ** 1 1 1 1 ** Output example 1 ** 4

** Input example 2 ** 1 2 3 4 ** Output example 2 ** 10

** Input example 3 ** 1000 100 10 1 ** Output example 3 ** 1111

0. Preparation

make command install

sudo apt isntall make

Building a working directory

#Create & move working directory
mkdir ABCXXX && cd ABCXXX   
#Template directory clone (--depth=Clone with 1 for minimal history)
git clone --depth=1  https://github.com/aoi-stoic/AtcorderTemplate.git
#Atcorder Template for A problem/Copy Template Cpp&Move
cp AtcorderTemplate/TemplateCpp/ problemA -r && cd problemA

At this point, the contents of the problemmA directory looks like this If you want to reproduce this configuration, you can build it manually without cloning from git, and just copy the Makefile from this article.

$ tree 
.
├── main.cpp  #Source file for answer
├── Makefile  # C++Makefile for
└── Testfiles #Test file directory
    ├── test1.test  #Test file of input example 1
    ├── test2.test
    ├── test3.test
    └── test4.test

1. Copy and paste of input example

Copy and paste the input example into each test file. The result is: Since there are only 1 to 3 input examples of ABCXXX A problem, test4.test is an empty file.

$ cat Testfiles/test1.test
1 1
1 1
$ cat Testfiles/test2.test
1 2
3 4
$ cat Testfiles/test3.test
1000 100
10 1
$ cat Testfiles/test4.test

2. Coding

As usual, I wrote the answer code in main.cpp.

// main.cpp
#include <iostream>

int main(){
    int a, b, c, d;
    std::cin >> a >> b >> c >> d;
    std::cout << a + b + c + d << std::endl;
}

3. Execute the make command

When I run the make command in the problemA directory, After compiling, it will be executed automatically for each input example. Input example 4 is not executed because test4.test is empty.

$ make 
g++ -std=c++11 -Wall main.cpp -o main.out
----------------------
exec Testfiles/test1.test
input:
1 1
1 1

output:
4
----------------------
exec Testfiles/test2.test
input:
1 2
3 4

output:
10
----------------------
exec Testfiles/test3.test
input:
1000 100
10 1

output:
1111

4. Submission or correction

Make sure that the input and output examples correspond correctly, and submit it when you are confident that the code is correct. If you want to move on to the next B problem, copy the TemplateCpp directory to create problemB and work in that directory as well.

make target

The following targets are prepared in the Makefile posted this time. Since python has no compilation work, it does not have targets such as build and clean.

target command Overview
(None) make Run make test
build make build Compile only
run make run Compile and run as needed.
Standard input is done manually.
test make test Compile and run as needed.
Enter the contents of the test file as standard.
clean make clean Delete the compiled product.
clean_test make clean_test Empty the contents of the test file.
It is used when copying the directory of question A and reusing it for the answer to question B.

Makefile

Makefile for C ++

COMP = g++ -std=c++11 -Wall
SRC = main.cpp
BIN = main.out
TESTDIR = Testfiles
#Disable implicit rules,Disable output when moving directories
MAKEFLAGS :=+ --no-builtin-rules --no-print-directory

#Target test with no argument (target) execution
all: test

$(BIN): $(SRC)
	$(COMP) $(SRC) -o $(BIN)

#make run is a manual input standard input
.phony:run
run: $(BIN)
	./$(BIN)

# make test
#Execute to input the contents of the test file in TESTDIR as standard (ignore empty files)
.phony:test
test: $(BIN)
	@for testfile in $(wildcard $(TESTDIR)/*.test) ; \
	do \
		if [ -s $$testfile ]; then \
			echo ---------------------- ;\
			echo "exec $$testfile " ;\
			echo "input: "; \
			cat $$testfile ; \
			echo "" ;\
			echo "output: " ;\
			cat $$testfile | ./$(BIN) ;\
		fi \
	done

.phony:clean
clean:
	-rm $(BIN)

#Empty all test files
.phony:clean_test
clean_test:
	@for testfile in $(wildcard $(TESTDIR)/*.test) ; \
	do \
		: > $$testfile ;\
	done

Makefile for Java

I have hardly written Java.

COMP = javac
EXEC = java
SRC = Main.java
CLASS = Main.class
# Main.class -> Main
APP = $(basename $(CLASS) .class)
TESTDIR = Testfiles
#Disable implicit rules,Disable output when moving directories
MAKEFLAGS :=+ --no-builtin-rules --no-print-directory
#
#Target test with no argument (target) execution
all: test

$(CLASS): $(SRC)
	$(COMP) $(SRC)

#make run is a manual input standard input
run: $(CLASS)
	$(EXEC) $(APP)

# make test
#Execute to input the contents of the test file in TESTDIR as standard (ignore empty files)
test: $(CLASS)
	@for testfile in $(wildcard $(TESTDIR)/*.test) ; \
	do \
		if [ -s $$testfile ]; \
			then \
			echo ---------------------- ;\
			echo "exec $$testfile" ;\
			echo "input: " ; \
			cat $$testfile ; \
			echo "" ;\
			echo "output: " ;\
			cat $$testfile | $(EXEC) $(APP) ;\
		fi \
	done \

.phony:clean
clean:
	-rm $(CLASS)

#Empty all test files
.phony:clean_test
clean_test:
	@for testfile in $(wildcard $(TESTDIR)/*.test) ; \
	do \
		: > $$testfile ;\
	done

Makefile for Python

In terms of Makefile, the scripting language Makefile seems strange.

SRC = main.py
EXEC = python3
TESTDIR = Testfiles
#Disable implicit rules,Disable output when moving directories
MAKEFLAGS :=+ --no-builtin-rules --no-print-directory

#Target test with no argument (target) execution
all: test

#make run is a manual input standard input
.phony:run
run: 
	$(EXEC) $(SRC)

# make test
#Execute to input the contents of the test file in TESTDIR as standard (ignore empty files)
.phony:test
test: 
	@for testfile in $(wildcard $(TESTDIR)/*.test) ; \
	do \
		if [ -s $$testfile ]; then \
			echo ---------------------- ;\
			echo "exec $$testfile " ;\
			echo "input: "; \
			cat $$testfile ; \
			echo "" ;\
			echo "output: " ;\
			cat $$testfile | $(EXEC) $(SRC) ;\
		fi \
	done

#Empty all test files
.phony:clean_test
clean_test:
	@for testfile in $(wildcard $(TESTDIR)/*.test) ; \
	do \
		: > $$testfile ;\
	done

Digression

pipeline

You can use the pipeline (|) to bridge the output of a command to the input of the next command.

$ cat Testfiles/test1.test
1 1
1 1
$ cat Testfiles/test1.test | ./main.out  #The output of the cat command./main.I'm using out input
4

You can use it to script the standard input of an executable file. make test Is taking advantage of this feature.

How to empty the contents of an existing file

When creating a new empty file

touch empty_file

That's enough, but this method doesn't work for existing files. The method of "delete and touch" as shown below is not my hobby


rm empty_file & touch empty_file  #This doesn't suit my taste

I often use the following two types.


#Command to do nothing(:)Redirect the result of
: > empty_file
# /dev/cp null
cp /dev/null empty_file

There seem to be various other methods.

Isn't a shell script enough for this scale?

exactly. However, considering setting shortcuts for execution commands in the editor, I think it is better to set shortcuts for the more versatile make command than for executing shell scripts.

Isn't it easier to see if you color the output of echo?

exactly. Please color according to the environment.

Some ubuntu distributions use dash instead of bash to execute shell scripts. There are some differences in the behavior of some commands between bash and dash. For example, in bash you can use an escape code to color the echo output as ```echo -e "\ 033 [31m GREEN \ 033 [m" `` `, but in dash you don't need the -e option. Does not analyze the options. I didn't color the echo output this time because it was expected that this difference would be a problem when publishing this time.

Recommended Posts

Use make to ease standard input of competition pro (AtCorder) C ++ / Java / Python sample Makefile posted
[Java] Input to stdin of Process
Story of paiza.jp [Java standard input solution]
[Java] [Maven3] Summary of how to use Maven3