/problem-solving

Tools for efficient competitive programming

Primary LanguageC++

What is this?

Tools for efficient competitive programming in C++, Golang, Java or Python using Visual Studio Code.

Dependencies

  • Visual Studio Code: https://code.visualstudio.com/
  • POSIX Shell: /bin/sh
  • [Optional] Golang for Go problem solving: https://go.dev/
  • [Optional] G++ for C++ problem solving: $ g++ --version
  • [Optional] pipenv and python
  • [Optional] Java

Quickstart

In order for all the scripts to run you have to give them permission:

chmod +x scripts/**/*.sh

The following is an example of how to use golang to solve a classic A+B problem.

Create a solution for problem A (folder ./workspace/A):

./create -l go A

This sets the ${Lang} variable to "go" and ${Problem} variable to to "A" in ./config. The ${Problem} variable makes the ./run and ./add_case commands to work in the ./workspace/A directory. Also, the script creates and opens in VSCode the files:

  • ./workspace/A/main.go: For your solution file.
  • ./workspace/A/cases/0.in: Input file for case 0.
  • ./workspace/A/cases/0.out: Expected output for case 0.

Save the following in 0.in:

10 12

And save the following in 0.out (add a single newline after the number):

22

NOTE: It is possible to get the example cases directly from Codeforces problem description. See: Get cases from Codeforces section

Replace the contents of ./workspace/A/main.go with:

package main

import "fmt"

func main() {
	var a, b int
	fmt.Scan(&a, &b)
	fmt.Printf("%d\n", a+b)
}

Now run your solution for problem A with case 0:

./run 0

You do not need to specify the problem since the ${Problem} variable is already set in ./config from the previous ./create A call.

To add a new test case for problem A run:

./add_case

This will create and open in VSCode the files workspace/A/cases/1.in and workspace/A/cases/1.out. You can add a case with input 1 2 and output 3 and test your solution against it with:

./run 1

Scripts

The following scripts are available in the root folder: ./open, ./create, ./add_case, ./run and , ./polygon.

You can see the manual for any script by running them with the -h or --help flag, for example: ./create -h.

Folder structure

|- add_case
|- config
|- create
|- polygon
|- open
|- run
|- .vscode/
|  |- snippets.code-snippets
|  |- c_cpp_properties.json
|- scripts/
|- notebook/
|  |- go/
|  |  |- template.go
|  |- cpp/
|  |  |- template.cpp
|- workspace/
|  | ...
|  |- ${Problem}/
|  |  |- main.go
|  |  |- cases/
|  |  |  |- 0.in
|  |  |  |- 0.out
|  |  |  |- 0.txt
|  |  |  | ...
|  |  |  |- ${CaseId}.in
|  |  |  |- ${CaseId}.out
|  |  |  |- ${CaseId}.txt

File/folder description:

  • ./add_case: Create input and output files for a new test case for the current problem.
  • ./config: File containing the current values for ${Lang}, ${Problem} and ${CaseId} variables.
  • ./create: Creates a new folder in workspace/ for a new problem and sets the ${Problem} variable.
  • ./run: Runs one or all test cases for the current problem.
  • ./open: Opens the given test case for the current problem.
  • ./polygon: Runs a polygon validator or generator for the current problem.
  • ./scripts/: Contains helper scripts used by the main scripts in the root folder.
  • ./notebook/: Folder with tested implementations of algorithms, data structures or utilities to be copy pasted when needed.
  • ./.vscode/snippets.code-snippets: Handy (VSCode snippets)[https://code.visualstudio.com/docs/editor/userdefinedsnippets] for faster problem solving.
  • ./.vscode/c_cpp_properties.json: Updates the VSCode "include path" for C++, so that C++ programns can include testlib.h.
  • ./notebook/go/template.go: Default code for ./workspace/${Problem}/main.go when ./create --l go ${Problem} is called.
  • ./notebook/go/template.cpp: Default code for ./workspace/${Problem}/main.cpp when ./create -l cpp ${Problem} is called.
  • ./workspace/${Problem}/: Folder with the source code and test cases for problem ${Problem}, it is created by ./create ${Problem}
  • ./workspace/${Problem}/main.go: Solution file for problem ${Problem}.
  • ./workspace/${Problem}/cases/: Folder containing inputs, answers and the solution outputs for the problem ${Problem}.
  • ./workspace/${Problem}/cases/${CaseId}.in: Input file for case ${CaseId} of problem ${Problem}.
  • ./workspace/${Problem}/cases/${CaseId}.txt: Solution's output for case ${CaseId} of problem ${Problem}. This is your solution's output.
  • ./workspace/${Problem}/cases/${CaseId}.out: Answer file for case ${CaseId} of problem ${Problem}. This is the expected output.

Get cases from Codeforces

For this feature python is required. Please install it and run pip install -r requirements.txt

If you want to automaticaly get the example cases from Codeforces problem description. When creating the solution problem you can add the -u or --url flag to pass the problem url. Thats all

For example:

	./create F -u https://codeforces.com/contest/1637/problem/F

Will create:

|- workspace/
|  |- F/
|  |  |- main.cpp   # Sample solution file
|  |  |- cases/
|  |  |  |- 0.in    # Sample input 0 
|  |  |  |- 0.out   # Sample output 0 
|  |  |  |- 1.in    # Sample input 1
|  |  |  |- 1.out   # Sample output 1
|  |  |  |- 2.in    # Sample input 2
|  |  |  |- 2.out   # Sample output 2
|  |  |- polygon/
|  |  |- |- checker.cpp # Sample checker

As three cases where found in the given url, three .in .out files were created. If no cases found in the given url there will be created two empty 0.in 0.out files

Polygon quickstart

Here's an example of how to prepare an "A+B problem" for polygon.

Create a problem called "aplusb" by using ./create with the --polygon (or -p) flag:

./create aplusb --polygon

This will create

|- workspace/
|  |- aplusb/
|  |  |- main.cpp   # Sample solution file
|  |  |- cases/
|  |  |  |- 0.in    # Sample input 0
|  |  |  |- 0.out   # Sample output 0
|  |  |- polygon/
|  |  |- |- validator.cpp # Sample input validator
|  |  |- |- checker.cpp # Sample checker
|  |  |- |- gen-random.cpp # Sample random case generator

This autogenerated template are correct for a simple A+B problem. So you can run the solution file against case 0:

./run 0

Now you can add a new test case running:

./add_case

And saving 10 10\n in workspace/aplusb/cases/0.in and 20\n in workspace/aplusb/cases/1.out.

In order to run the solution against all test cases you can run:

./run -a

Validator

In order to use the validator to check that all the inputs are valid you can run:

./polygon validator

If you want to validate only workspace/aplusb/cases/1.in you can run:

./polygon validator 1

A shortcut for ./polygon validator is ./polygon v.

Generators

In order to generate a case with the sample generator (workspace/aplusb/polygon/gen-random.cpp) you can run:

./polygon generator gen-random

Since the generator uses testlib, it always outputs the same numbers. But you can add a random extra argument to change the output, for example:

./polygon generator gen-random random-seed-value-12341

A shortcut for ./polygon generator is ./polygon g.

Contribute

See contributing guidelines.