Skip to content

trodrigueza/cf-clojure-tool

Repository files navigation

cf-clojure-tool

Tool made in Clojure for testing Clojure solutions for Codeforces problems. At the moment, test cases must be added manually, the idea is to automate this for public test cases (via scrapping) and also to generate stronger ones (Codeforces doesn't allow to get hidden test cases).

This is just to make easier the process of practicing/studying Clojure with CF problems.

Prerequisites

Installation

git clone https://github.com/trodrigueza/cf-clojure-tool.git
cd cf-clojure-tool
lein deps

Usage

  1. Create a file .clj with your namespace in src/cf_tool/solutions/. Check that the namespace matches the path:
    (ns cf-tool.solutions.solution_XXX)
    (defn -main []
        ;; ur code
    )
  2. Add test cases. For example: :
    mkdir -p tests/<contest><problem> # `path/to/cf-clojure-tool/tests`
    cat > tests/<contest><problem>/input1.txt << 'EOF'
    <sample 1 input>
    EOF
    cat > tests/<contest><problem>/output1.txt << 'EOF'
    <sample 1 output>
    EOF
    # Repeat for input2/output2...
    Note: I know this is frustating, actually the idea of avoiding this is why I wanted to do this mini project but one has to start with something :).
  3. Execute runner (aka "judge"):
    lein run -m cf_tool.runner cf_tool.solutions.solution_XXX tests/<contest><problem>

Uberjar Alternative

If you don't want to install Leiningen (I'm new to Clojure but not having Leiningen may be weird if you use Clojure), you can use the .jar file: target/cf-clojure-tool-0.1.0-SNAPSHOT-standalone.jar:

java -jar path/to/target/cf-clojure-tool-0.1.0-SNAPSHOT-standalone.jar \
  cf_tool.solutions.solution_XYZ \
  path/to/tests/<contest><problem>

Examples

Let's consider this problem. You can create a directory A with the following schema:

A
|--- main.clj
|--- test
     |--- input1.txt
     |--- input2.txt
     |--- output1.txt
     |--- output2.txt

In main.clj you would write the problem logic, in this case:

(ns main)

(defn -main []
  (let [w (Integer/parseInt (read-line))]
    (println (if (and (even? w) (> w 2)) "YES" "NO"))))

And in tests you would have the test-cases.

You can simply run:

java -cp path/to/cf-clojure-tool/target/uberjar/cf-clojure-tool-0.1.0-SNAPSHOT-standalone.jar:. cf_tool.runner main ./tests

Obtaining:

Starting runner for namespace: main tests at: ./tests
Input files detected: (input1.txt input2.txt)

----- Test: input1.txt -----
PASSED

----- Test: input2.txt -----
PASSED

Extra:

You can add the following function to your ~/.bashrc or ~/.zshrc and just type cf-runner in A:

cf-runner() {
  local JAR="path/to/cf-clojure-tool/target/uberjar/cf-clojure-tool-0.1.0-SNAPSHOT-standalone.jar"
  [[ -f main.clj ]] || { echo "Error: main.clj not found in $(pwd)"; return 1 }
  [[ -d tests ]] || { echo "Error: tests/ not found in $(pwd)"; return 1 }

  # get namespace
  local NS
  NS=$(
    awk '/^\(ns[[:space:]]/ {             
           name = $2;                    
           gsub(/[()]/, "", name);      
           print name;                 
           exit
         }'                             \
         main.clj
  )
  [[ -n $NS ]] || { echo "Error: namespace not found"; return 1 }

  # run
  java -cp "$JAR:." cf_tool.runner "$NS" tests
}

About

Tool made in Clojure for testing Clojure solutions for Codeforces problems.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published