Work to Survive!

From Esolang
Jump to navigation Jump to search

Work to Survive! is a type of esolang (as well as a language standard) that forces the user to waste CPU cycles to "work" in order not to get the main process killed.

Specifications (Work to Survive! 1.0)

The user can work in Work to Survive! by calling the obscure work_to_survive function and specifying the amount of work (usually represented by a duration of time) that they are willing to do.

The user starts with some remaining_time worth of time, and must complete works to gain more remaining_time. When a Work to survive! runtime environment detects that a program's remaining_time is equal to or less than 0ms, it must terminate the program immediately.

Tips for Work to Survive! implementation vendors:

  • If you choose to use some units of time to represent the work amount (for this example: milliseconds), then completing the work is required to take at least work milliseconds. It doesn't matter how much more time it actually takes, so it is fine to write a work_to_survive function with considerable overhead.
  • Regarding the time reward that the user gets for working, it is not specified in the standards. But the general recommendation is 1.5x the amount of work done in a fast language like C++ and 2x in a slower one like Python.
  • In order to promote fair trade, the user is not allowed to hoard more than 1 second of remaining time. All implementations can freely define how to punish the user should this rule be violated.
  • It is not allowed to use anything other than the main thread to do the works. However, what actually happens when the user violates this rule is implementation-defined.

Implementations

The following is a C++ implementation that anyone can include into their C++ source code to create a program that is accepted by the Work to Survive! 1.0 standards:

#include <chrono>
#include <future>
#include <iostream>
#include <thread>

////////////////////////// Work now or Die!! ///////////////////////////
// * You have to work to survive                                      //
// * You can only work in the main thread                             //
// * You start with 100ms of time                                     //
// * It is illegal to have more than 1000ms of time                   //
// * work >  0ms : Do work and get 1.5x the time you worked as reward //
// * work <= 0ms : See the remaining time                             //
////////////////////////////////////////////////////////////////////////
auto work_to_survive(std::chrono::milliseconds work = {}) -> std::chrono::milliseconds {
  using namespace std::chrono_literals;
  
  static std::thread::id           main_thread_id = std::this_thread::get_id();
  static std::mutex                time_mutex;
  static std::chrono::milliseconds remaining_time = 100ms;
  static std::chrono::time_point   prev_time = std::chrono::high_resolution_clock::now();
  
  //// Time is ticking
  time_mutex.lock();
  auto now = std::chrono::high_resolution_clock::now();
  // std::max punishes those who call the function too frequently
  remaining_time -= std::max(std::chrono::duration_cast<std::chrono::milliseconds>(now - prev_time), 1ms);
  prev_time = now;
  time_mutex.unlock();
  
  //// Return the remaining time if not working
  if (work <= 0ms || std::this_thread::get_id() != main_thread_id) return remaining_time;
  
  //// It's Working Time!
  std::this_thread::sleep_for(work); // Do work
  std::lock_guard lock(time_mutex);
  remaining_time += std::chrono::duration_cast<std::chrono::milliseconds>(work * 1.5); // Get your reward
  return remaining_time;
}

////// Set up a time bomb to punish those who don't work (or those who work too much!)
const volatile auto ____start_working_now_or_die = (work_to_survive(), std::async([]() {
  using namespace std::chrono_literals;
  
  while (true) {
    std::this_thread::sleep_for(10ms); // Check on the employee every 10ms 😈😈
    auto remaining_time = work_to_survive(0ms); // Check the time
    if (remaining_time <= 0ms || remaining_time > 1000ms) break;
  }
  
  std::terminate(); // Punish the lazy or overworking employee
}));