mirror of
https://github.com/HenkKalkwater/aoc-2020
synced 2024-11-22 11:05:18 +00:00
Improve framework
This commit is contained in:
parent
404605b092
commit
4902daebaf
159
source/app.d
159
source/app.d
|
@ -3,8 +3,9 @@ import core.stdc.stdlib;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.exception;
|
import std.exception;
|
||||||
import std.format;
|
import std.format;
|
||||||
import std.stdio;
|
|
||||||
import std.getopt;
|
import std.getopt;
|
||||||
|
import std.range;
|
||||||
|
import std.stdio;
|
||||||
import std.variant;
|
import std.variant;
|
||||||
|
|
||||||
import day1;
|
import day1;
|
||||||
|
@ -20,6 +21,10 @@ import dayutil;
|
||||||
|
|
||||||
immutable string progName = "aoc-2020";
|
immutable string progName = "aoc-2020";
|
||||||
|
|
||||||
|
version(Unix) {
|
||||||
|
extern(C) int isatty(int);
|
||||||
|
}
|
||||||
|
|
||||||
Variant function(int, File, bool, string[])[] programs = [
|
Variant function(int, File, bool, string[])[] programs = [
|
||||||
&day1.run,
|
&day1.run,
|
||||||
&day2.run,
|
&day2.run,
|
||||||
|
@ -32,68 +37,118 @@ Variant function(int, File, bool, string[])[] programs = [
|
||||||
&day9.run,
|
&day9.run,
|
||||||
];
|
];
|
||||||
|
|
||||||
void printUsage(string name) {
|
void printUsage(string message = null) {
|
||||||
printUsage(name, null);
|
import core.runtime;
|
||||||
}
|
string name = Runtime.args[0];
|
||||||
|
stderr.writeln("USAGE: %s [OPTIONS...] DAY PART [INPUT_FILE] (to run a specific day)".format(name));
|
||||||
void printUsage(string name, string message) {
|
stderr.writeln(" OR: %s [OPTIONS...] all (to run each day)".format(name));
|
||||||
stderr.writeln("USAGE: %s [DAY] [PART] <INPUT_FILE> ".format(name));
|
stderr.writeln();
|
||||||
stderr.writeln(" DAY = int between 1 and 25 (inclusive), specifiying the day to run");
|
stderr.writeln(" DAY = int between 1 and 25 (inclusive), specifiying the day to run");
|
||||||
stderr.writeln(" PART = int between 1 and 2 (inclusive), specifiying the part to run");
|
stderr.writeln(" PART = int between 1 and 2 (inclusive), specifiying the part to run");
|
||||||
stderr.writeln(" INPUT_FILE = file to read from. '-' or missing implies stdin");
|
stderr.writeln(" INPUT_FILE = file to read from. '-' for stdin. If not specified, use in/[DAY].txt");
|
||||||
|
stderr.writeln();
|
||||||
|
stderr.writeln("OPTIONS:");
|
||||||
|
stderr.writeln(" --bigboy, -B = use bigboy challenges");
|
||||||
|
stderr.writeln(" --benchmark, -b = record time it took to execute ");
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
|
stderr.writeln();
|
||||||
stderr.writeln(message);
|
stderr.writeln(message);
|
||||||
}
|
}
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File getDefaultFile(int day, bool bigboy) {
|
||||||
|
if (bigboy) {
|
||||||
|
return File("in/bigboy/%d.txt".format(day), "rb");
|
||||||
|
} else {
|
||||||
|
return File("in/%d.txt".format(day), "rb");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main(string[] args) {
|
void main(string[] args) {
|
||||||
bool bigboy = false;
|
bool bigboy = false;
|
||||||
int day;
|
bool benchmark = false;
|
||||||
getopt(args,
|
|
||||||
"bigboy", "Execute the so-named 'biboy' variant of this exercise", &bigboy);
|
|
||||||
if (args.length < 3) {
|
|
||||||
printUsage(args[0]);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
day = to!int(args[1]);
|
|
||||||
} catch (ConvException e) {
|
|
||||||
printUsage(args[0], "[day] is not an integer");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (day <= 0 || day > programs.length) {
|
|
||||||
printUsage(args[0], "[day] must be between 1 and %d".format(programs.length));
|
|
||||||
}
|
|
||||||
|
|
||||||
int part;
|
|
||||||
try {
|
try {
|
||||||
part = to!int(args[2]);
|
auto opts = getopt(args,
|
||||||
} catch (ConvException e) {
|
"bigboy|B", &bigboy,
|
||||||
printUsage(args[0], "[part] is not an integer");
|
"benchmark|b", &benchmark);
|
||||||
}
|
if (opts.helpWanted) {
|
||||||
|
printUsage();
|
||||||
File file;
|
|
||||||
try {
|
|
||||||
if (args.length < 4) {
|
|
||||||
if (bigboy) {
|
|
||||||
file = File("in/bigboy/%d.txt".format(day), "rb");
|
|
||||||
} else {
|
|
||||||
file = File("in/%d.txt".format(day), "rb");
|
|
||||||
}
|
|
||||||
} else if(args[3] == "-") {
|
|
||||||
file = stdin;
|
|
||||||
} else {
|
|
||||||
file = File(args[3], "rb");
|
|
||||||
}
|
}
|
||||||
} catch (ErrnoException e) {
|
} catch (GetOptException e) {
|
||||||
printUsage(args[0], "Error %d while opening input file: %s".format(e.errno, e.message));
|
printUsage(e.msg);
|
||||||
|
}
|
||||||
|
if (args.length < 2) {
|
||||||
|
printUsage();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
Variant result = programs[day - 1](part, file, bigboy, args[3..$]);
|
|
||||||
writeln(result);
|
|
||||||
} catch(ArgumentException e) {
|
|
||||||
printUsage(args[0], e.msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
bool runAll = false;
|
||||||
|
if (args[1] == "all") {
|
||||||
|
/+version(Posix) {
|
||||||
|
bool tty = cast(bool) isatty(stdout.fileNo);
|
||||||
|
} else {+/
|
||||||
|
bool tty = false;
|
||||||
|
//}
|
||||||
|
runAll = true;
|
||||||
|
writeln(tty);
|
||||||
|
writeln("STATUS\tDAY\tPART\tRESULT");
|
||||||
|
foreach (dayNo, day; programs.enumerate(1)) {
|
||||||
|
File file = getDefaultFile(dayNo, bigboy);
|
||||||
|
foreach(part; 1..3) {
|
||||||
|
if (tty) {
|
||||||
|
write("RUNNING\t%d\t%d\t...\r".format(dayNo, part));
|
||||||
|
stdout.flush();
|
||||||
|
}
|
||||||
|
Variant result = day(part, file, bigboy, []);
|
||||||
|
writeln("DONE \t%d\t%d\t%s ".format(dayNo, part, std.conv.to!string(result)));
|
||||||
|
file.rewind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (args.length < 3) {
|
||||||
|
printUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
int day;
|
||||||
|
try {
|
||||||
|
day = to!int(args[1]);
|
||||||
|
} catch (ConvException e) {
|
||||||
|
printUsage("DAY is not an integer");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (day <= 0 || day > programs.length) {
|
||||||
|
printUsage("DAY must be between 1 and %d".format(programs.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
int part;
|
||||||
|
try {
|
||||||
|
part = to!int(args[2]);
|
||||||
|
} catch (ConvException e) {
|
||||||
|
printUsage("PART is not an integer");
|
||||||
|
}
|
||||||
|
|
||||||
|
File file;
|
||||||
|
try {
|
||||||
|
if (args.length < 4) {
|
||||||
|
file = getDefaultFile(day, bigboy);
|
||||||
|
} else if(args[3] == "-") {
|
||||||
|
file = stdin;
|
||||||
|
} else {
|
||||||
|
file = File(args[3], "rb");
|
||||||
|
}
|
||||||
|
} catch (ErrnoException e) {
|
||||||
|
printUsage("Error %d while opening input file: %s".format(e.errno, e.message));
|
||||||
|
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Variant result = programs[day - 1](part, file, bigboy, args[3..$]);
|
||||||
|
writeln(result);
|
||||||
|
} catch(ArgumentException e) {
|
||||||
|
printUsage(e.msg);
|
||||||
|
} catch(Exception e) {
|
||||||
|
stderr.writeln("Fatal error occurred: " ~ e.msg);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@ Variant run(int part, File input, bool bigboy, string[] args) {
|
||||||
will make use of optimised implementations, in the case of contains(range, elem)
|
will make use of optimised implementations, in the case of contains(range, elem)
|
||||||
it will use a binary search instead of a linear search */
|
it will use a binary search instead of a linear search */
|
||||||
auto numbers = input.byLineCopy.map!(a => to!int(a)).array.sort;
|
auto numbers = input.byLineCopy.map!(a => to!int(a)).array.sort;
|
||||||
int target = bigboy ? 99920044 : 2020;
|
int target = 2020;
|
||||||
|
if(bigboy) target = 2020;
|
||||||
|
|
||||||
Variant solution = parts!int(part,
|
Variant solution = parts!int(part,
|
||||||
() => part1(numbers, target),
|
() => part1(numbers, target),
|
||||||
|
|
|
@ -10,7 +10,7 @@ import std.variant;
|
||||||
import dayutil;
|
import dayutil;
|
||||||
|
|
||||||
Variant run(int part, File input, bool bigboy, string[] args) {
|
Variant run(int part, File input, bool bigboy, string[] args) {
|
||||||
auto inputData = stdin.byLineCopy.array;
|
auto inputData = input.byLineCopy.array;
|
||||||
Variant count = parts!size_t(part,
|
Variant count = parts!size_t(part,
|
||||||
() => inputData.countTrees1,
|
() => inputData.countTrees1,
|
||||||
() => [[1,1], [3,1], [5,1], [7,1], [1,2]]
|
() => [[1,1], [3,1], [5,1], [7,1], [1,2]]
|
||||||
|
|
Loading…
Reference in a new issue