{% extends "common-content.html" %}
{% block description %}
  <style>
    article {
      padding: 2.5em 3.5em;
      font-size: 1.1em;
    }
    li {
      padding: 0.2em;
    }
    #content-right {
      display: none;
    }
  </style>
  <article id="py">
    <h2>1. Custom checker (PY)</h2>
    <hr>
    <p>
      Đây là checker mặc định của website, cho phép người dùng cập nhật được nhiều thông tin nhất (chi tiết xem ở  bên dưới). Chúng ta cần hoàn thành hàm check dưới đây:
    </p>

    {{
    """
    def check(process_output, judge_output, **kwargs):
    # return True/False
    """|highlight('py')}}

    <p>
      Trong đó, <code>**kwargs</code> có thể chứa các biến sau:
    </p>
    <ul>
      <li><code>process_output:</code> output</li>
      <li><code>judge_output:</code> đáp án</li>
      <li><code>submission_source</code>: Code bài nộp</li>
      <li><code>judge_input</code>: input</li>
      <li><code>point_value:</code> điểm của test đang chấm</li>
      <li><code>case_position:</code> thứ tự của test</li>
      <li><code>submission_language:</code> ngôn ngữ của bài nộp</li>
      <li><code>execution_time:</code> thời gian chạy</li>
    </ul>
    <h2>Return: </h2>
    <ul>
      <li>Cách 1: Trả về True/False</li>
      <li>Cách 2: Trả về một object <code>CheckerResult</code> có thể được gọi như sau <pre class="code2">CheckerResult(case_passed_bool, points_awarded, feedback='')</pre></li>
    </ul>

    <h2>Ví dụ: </h2>
    <p>Dưới đây là ví dụ cho bài toán: Input gồm 1 số nguyên n. In ra 2 số nguyên a, b sao cho a + b = n.
    </p>
    {{
    """
    from dmoj.result import CheckerResult


    def wa(feedback):
    return CheckerResult(False, 0, feedback)


    def check(process_output, judge_output, judge_input, **kwargs):
    # process the input
    input_arr = judge_input.split()
    assert(len(input_arr) == 1)
    n = int(input_arr[0])

    #  process the contestant's output
    output_arr = process_output.split()

    if (len(output_arr) != 2):
    return wa('Wrong output format')

    try:
    a, b = int(output_arr[0]), int(output_arr[1])
    except:
    return wa('Wrong output format')

    if (n == a + b):
    return True
    return wa('a + b != n')
    """| highlight('py')}}
  </article>
  <article id="cpp">
    <h2>2. Custom validator (CPP)</h2>
    <hr>
    <p>
      Để sử dụng chức năng này, cần viết một chương trình C++ pass vào 3 arguments theo thứ tự <code>input_file</code>, <code>output_file</code>, <code>ans_file</code> tương ứng với các file input, output, đáp án.
    </p>
    <p>
      Để test chương trình trên máy tính, có thể dùng lệnh như sau (Windows):
      <pre class="code2">
main.exe [input_file] [output_file] [ans_file]</pre> 
      hoặc thay bằng <code>./main</code> trên Linux/MacOS.
    </p>
    <h2>Return: </h2>
    <p>
      Chương trình trả về giá trị:
      <ul>
        <li> 0 nếu AC (100% điểm)</li>
        <li> 1 nếu WA (0 điểm)</li>
        <li> 2 nếu điểm thành phần. Khi đó cần in ra stderr một số thực trong đoạn [0, 1] thể hiện cho tỷ lệ điểm. Nếu điểm < 1 thì hiển thị WA, điểm = 1 thì hiển thị AC.  </li>
      </ul>
      Những thông tin được viết ra stdout (bằng cout) sẽ được in ra màn hình cho người nộp bài(feedback)
    </p>

    <h2>Ví dụ: </h2>
    <p>Chương trình sau dùng để chấm bài toán: Cho n là một số nguyên dương. In ra hai số tự nhiên a, b sao cho a + b = n. </p>
    <p>Nếu in ra a + b = n và a, b >= 0 thì được 100% số điểm, nếu a + b = n nhưng một trong 2 số a, b âm thì được 50% số điểm. </p>
    {{
    """
    #include <bits/stdc++.h>
      using namespace std;

      int main(int argc, char** argv) {
      ifstream inp(argv[1]);
      ifstream out(argv[2]);
      ifstream ans(argv[3]);

      int n, a, b, c, d;

      inp >> n;
      out >> a >> b;
      ans >> c >> d;

      if (a + b == c + d) {
      cout << a << \" + \" << b << \" = \" << c << \" + \" << d << endl;

      if (a >= 0 && b >= 0) {
      return 0; // AC
      }
      else {
      cerr << 0.5;
      return 2; // PARTIAL
      }
      }
      else {
      cout << \"a + b = \" << a + b << \" != \" << n << endl;
      return 1; // WA
      }
      }
      """ | highlight('cpp')}}
    </article>
    <article id="interactive">
      <h2>3. Interactive (CPP)</h2>
      <hr>
      <p>
        Để sử dụng chức năng này, cần viết một chương trình C++ pass vào 2 arguments <code>input_file</code> <code>answer_file</code> tương ứng file input và đáp án (nếu cần thiết).
      </p>
      <p>
        Để test chương trình trên máy tính với tư cách thí sinh, có thể dùng lệnh như sau (Windows):
        <pre class="code2">
main.exe [input_file] [answer_file]</pre> 
        hoặc thay bằng <code>./main</code> trên Linux/MacOS.
      </p>
      <h2>Return: </h2>
      <p>
        Chương trình trả về giá trị:
        <ul>
          <li> 0 nếu AC (100% điểm)</li>
          <li> 1 nếu WA (0 điểm)</li>
          <li> 2 nếu điểm thành phần. Khi đó cần in ra stderr một số thực trong đoạn [0, 1] thể hiện cho tỷ lệ điểm. Nếu điểm < 1 thì hiển thị WA, điểm = 1 thì hiển thị AC. </li>
        </ul>
        Thông tin được in ra trong stderr (bằng cerr) sẽ là feedback hiển thị cho người dùng.
      </p>

      <h2>Ví dụ: </h2>
      <p>Chương trình sau dùng để chấm bài toán guessgame: Người chơi phải tìm 1 số bí mật n (n chứa trong file input). Mỗi lần họ được hỏi một số x, và chương trình sẽ trả về "SMALLER", "BIGGER" hoặc "HOLA" dựa trên giá trị của n và x. Cần tìm ra n sau không quá 31 câu hỏi. </p>
      {{
      """
      #include <bits/stdc++.h>
        using namespace std;

        void quit(string reason) {
        cerr << reason << endl;
        exit(1);
        }

        void read(long long& guess) {
        if (!(cin >> guess)) exit(1); // Nếu không có dòng này, chương trình sẽ chờ vô hạn
        if (guess < 1 || guess > 2e9) exit(1);
        }

        int main(int argc, char *argv[]) {
        ifstream inp(argv[1]);
        int N, guesses = 0;
        long long guess;
        inp >> N;

        while (guess != N && guesses <= 31) {
        read(guess);
        if (guess == N) {
        cout << \"HOLA\" << endl;
        } else if (guess > N) {
        cout << \"SMALLER\" << endl;
        } else {
        cout << \"BIGGER\" << endl;
        }
        guesses++;
        }
        cerr << \"Number of used guesses: \" << guesses << endl;
        if (guesses <= 31)
        return 0; // AC
        else {
        cerr << \"Used too many guesses\" << endl;
        return 1; // WA
        }
        }
        """ | highlight('cpp')}}
      </article>
{% endblock %}