Browse Source

Recrder / Utils / Example

Marcelo Fornet 5 years ago
parent
commit
e1155a8e1a
5 changed files with 193 additions and 0 deletions
  1. 2 0
      .gitignore
  2. 63 0
      example.cpp
  3. 101 0
      recorder.h
  4. 0 0
      tasks/.gitkeep
  5. 27 0
      utils.h

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+.vscode/
+a.out

+ 63 - 0
example.cpp

@@ -0,0 +1,63 @@
+#include "recorder.h"
+#include "utils.h"
+
+#include <fstream>
+#include <ostream>
+#include <istream>
+#include <string>
+
+using namespace std;
+
+struct ExampleTask
+{
+    string s;
+
+    long long score()
+    {
+        auto answer = 0;
+
+        for (auto x : s)
+        {
+            answer += x == 'a';
+        }
+
+        return answer;
+    }
+
+    void save(ostream &output, ostream &info)
+    {
+        output << s << endl;
+        info << "string: " << s << endl;
+    }
+
+    void load(istream &output, istream &info)
+    {
+        output >> s;
+    }
+};
+
+int main()
+{
+    Recorder<ExampleTask> rec("a");
+
+    ExampleTask task;
+
+    rec.load(task);
+
+    task.s = "aafasfasfasfasfdasdf";
+
+    rec.submit(task);
+
+    long long pig = 0;
+
+    // This function will be called multiple times for 10 milliseconds.
+    // It will be checked every 2_000_000 iterations.
+    run_while([&]() {
+        pig++;
+    },
+              2000000, 10);
+
+    cout << pig << endl;
+
+    return 0;
+}

+ 101 - 0
recorder.h

@@ -0,0 +1,101 @@
+#ifndef _RECORDER
+#define _RECORDER
+
+#include <iostream>
+#include <fstream>
+#include <ostream>
+#include <istream>
+#include <streambuf>
+#include <filesystem>
+
+namespace fs = std::filesystem;
+
+template <typename T>
+struct Recorder
+{
+    bool verbose;
+    std::string name;
+    T global_best_task;
+    T current_best_task;
+    long long global_best_score;
+    long long current_best_score;
+
+    Recorder(std::string name = "") : name(name)
+    {
+        verbose = false;
+        global_best_score = 0;
+        current_best_score = 0;
+    }
+
+    void set_verbose(bool verbose = true)
+    {
+        this->verbose = verbose;
+    }
+
+    void submit(T &task)
+    {
+        auto task_score = task.score();
+
+        if (task_score > global_best_score)
+        {
+            std::cout << "Best improved: " << task_score << " <-- " << global_best_score << std::endl;
+            current_best_score = global_best_score = task_score;
+            current_best_task = global_best_task = task;
+
+            if (name == "")
+            {
+                std::cout << "Warning: No name assigned for this recorder." << std::endl;
+                return;
+            }
+
+            fs::path tasks = "tasks";
+            std::fstream fs_score, fs_submit, fs_info;
+
+            fs_score.open(tasks / (name + ".score"));
+            fs_score << task_score << std::endl;
+            fs_score.close();
+
+            fs_submit.open(tasks / (name + ".out"));
+            fs_info.open(tasks / (name + ".info"));
+            task.save(fs_submit, fs_info);
+            fs_submit.close();
+            fs_info.close();
+        }
+        else if (task_score > current_best_score)
+        {
+            std::cout << "Current improved: " << task_score << " <-- " << current_best_score << std::endl;
+            current_best_score = task_score;
+            current_best_task = task;
+
+            if (verbose)
+            {
+                task.save(std::cout, std::cerr);
+            }
+        }
+    }
+
+    void load(T &task)
+    {
+        fs::path tasks = "tasks";
+        std::ifstream fs_score, fs_submit, fs_info;
+        auto cur_name = tasks / (name + ".score");
+        fs_score.open(tasks / (name + ".score"));
+        fs_score >> global_best_score;
+        fs_score.close();
+        fs_submit.open(tasks / (name + ".out"));
+        fs_info.open(tasks / (name + ".info"));
+        task.load(fs_submit, fs_info);
+        fs_submit.close();
+        fs_info.close();
+
+        std::cout << "Loaded Task: " << name << " Score: " << global_best_score << std::endl;
+    }
+};
+
+template <typename T>
+void print(T &task)
+{
+    task.save(std::cout, std::cerr);
+}
+
+#endif

+ 0 - 0
tasks/.gitkeep


+ 27 - 0
utils.h

@@ -0,0 +1,27 @@
+#ifndef _UTILS
+#define _UTILS
+
+#include <chrono>
+
+template <typename function_name>
+void run_while(function_name predicate, int times, int milliseconds)
+{
+    auto start = std::clock();
+    int steps = 0;
+
+    while (true)
+    {
+        predicate();
+
+        if (++steps == times)
+        {
+            steps = 0;
+            if ((std::clock() - start) * 1000 > milliseconds * CLOCKS_PER_SEC)
+            {
+                break;
+            }
+        }
+    }
+}
+
+#endif