class AOC
{
/**
* Get the path for a given day
*
* @param string $file
* @param int $year
* @param int $day
* @return string
*/
public static function path($file, $year = null, $day = null)
{
return "./".($year?:static::year())."/".($day?:static::day())."/{$file}";
}
/**
* Get all utilities
*
* @return array
*/
public static function utilities($year = false)
{
if ($year) {
$files = array_filter(scandir("$year"), fn ($f) => strpos($f, ".php"));
} else {
$files = array_diff(scandir("includes/utils"), [".", ".."]);
}
return array_map(fn ($f) => str_replace(".php", "", $f), $files);
}
/**
* Load all utilities
*
* @return void
*/
public static function loadUtilities()
{
// Global utilities
foreach (static::utilities() as $class) {
require_once("includes/utils/{$class}.php");
}
// Year-specific utilities
foreach (static::utilities(static::year()) as $class) {
require_once(static::year()."/{$class}.php");
}
}
/**
* Create a new directory with the base files for the given year/day
*
* @param int $year
* @param int $day
* @return void
*/
public static function create($year, $day)
{
$path = static::path("", $year, $day);
if (is_dir($path)) {
echo "Directory already exists";
exit;
}
// Create base directory
mkdir($path, 0777, true);
// Create each file with default content
$files = [
"README.md" => "# Day {$day}",
"solution.php" => "\n\n",
"input.txt" => "",
];
foreach ($files as $file => $content) {
file_put_contents($path . "/" . $file, $content);
}
exit;
}
/**
* Load the right template/file based on the parameters
*
* @return void
*/
public static function routing()
{
// Display list of utilities
if (isset($_GET["utilities"])) {
require_once("./includes/views/utilities.php");
exit;
}
// Load and execute solution if requested
if (AOC::direct() || AOC::ajax() || AOC::CLI()) {
require_once("./includes/views/partial/solution.php");
};
// Display the homepage by default
require_once("./includes/views/home.php");
}
/**
* Link to a specific day
*
* @return string
*/
public static function url($args)
{
return "?" . http_build_query(array_filter(array_merge($_GET, ["utilities" => 0], $args)));
}
// =============================================================================
// > STATE VARIABLES
// =============================================================================
/**
* The current state
*/
public static $year;
public static $day;
public static $input;
public static $question;
public static $solution;
public static $years;
public static $days;
public static $direct;
public static $ajax;
/**
* The current input
*
* @return string
*/
public static function input()
{
return static::$input ??= file_get_contents(static::path("input.txt"));
}
/**
* The current question
*
* @return string
*/
public static function question()
{
return static::$question ??= file_get_contents(static::path("README.md"));
}
/**
* The current solution's code
*
* @return string
*/
public static function solution()
{
$version = isset($_GET["version"]) ? "_" . $_GET["version"] : "";
return static::$solution ??= file_get_contents(static::path("solution{$version}.php"));
}
/**
* The visualisation link, if any
*
* @return void
*/
public static function visualisation()
{
if (file_exists(static::path("visualisation.php"))) {
return AOC::url(["visualisation" => 1, "direct" => 1]);
}
return false;
}
/**
* The current year
*
* @return int
*/
public static function year()
{
return static::$year ??= (int) ($_GET["year"] ?? static::years()->last());
}
/**
* The available years
*
* @return Set
*/
public static function years()
{
return static::$years ??= set(scandir("./"))->filter(fn ($dir) => intval($dir))->values();
}
/**
* The current day
*
* @return int
*/
public static function day()
{
return static::$day ??= (int) ($_GET["day"] ?? static::days()->last());
}
/**
* The available days
*
* @return Set
*/
public static function days($year = null)
{
return static::$days ??= set(scandir("./" . ($year ?: static::year()) . "/"))->filter(fn ($dir) => intval($dir))->values()->sort();
}
/**
* The solution should be loaded directly and not via ajax
*
* @return bool
*/
public static function direct()
{
return static::$direct ??= ($_GET["direct"] ?? false);
}
/**
* The solution was loaded via ajax
*
* @return bool
*/
public static function ajax()
{
return static::$ajax ??= ($_GET["ajax"] ?? false);
}
/**
* The solution was loaded via the CLI
*
* @return bool
*/
public static function CLI()
{
if (php_sapi_name() === "cli") {
global $argv;
[static::$year, static::$day] = explode("/", $argv[1]);
if (static::$year[0] == "+") {
static::create(trim(static::$year, "+"), static::$day);
}
return true;
}
return false;
}
}