Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 52dfdcc4bb | |||
| 64040259cb |
@@ -0,0 +1,83 @@
|
|||||||
|
import "aoc" for AoC
|
||||||
|
|
||||||
|
class Entry {
|
||||||
|
construct dir(parent) {
|
||||||
|
_parent = parent
|
||||||
|
_files = {}
|
||||||
|
}
|
||||||
|
construct file(parent, size) {
|
||||||
|
_parent = parent
|
||||||
|
_size = size
|
||||||
|
}
|
||||||
|
|
||||||
|
size { _size }
|
||||||
|
files { _files }
|
||||||
|
parent { _parent }
|
||||||
|
type { _files == null ? "file" : "dir" }
|
||||||
|
|
||||||
|
total_size {
|
||||||
|
if(_size) {
|
||||||
|
return _size
|
||||||
|
} else {
|
||||||
|
return _files.map {|entry| entry.value.total_size}.reduce {|a, b| a+b}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toString {
|
||||||
|
if(_files) {
|
||||||
|
return "{" + _files.map {|entry| entry.key + ": " + entry.value.toString}.join(", ") + "}"
|
||||||
|
} else {
|
||||||
|
return _size.toString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iter_dirs(fn) {
|
||||||
|
if(_files) {
|
||||||
|
fn.call(this)
|
||||||
|
for(file in _files) {
|
||||||
|
file.value.iter_dirs(fn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var lines = AoC.input.split("\n").where {|x| x != ""}
|
||||||
|
|
||||||
|
var root = Entry.dir(null)
|
||||||
|
|
||||||
|
var current = root
|
||||||
|
for(line in lines) {
|
||||||
|
if(line.startsWith("$ cd")) {
|
||||||
|
var path = line.replace("$ cd ", "")
|
||||||
|
if(path == "/") {
|
||||||
|
current = root
|
||||||
|
} else if(path == "..") {
|
||||||
|
current = current.parent
|
||||||
|
} else {
|
||||||
|
current = current.files[path]
|
||||||
|
}
|
||||||
|
} else if(line == "$ ls") {
|
||||||
|
// ignore
|
||||||
|
} else if(line.startsWith("dir ")) {
|
||||||
|
var path = line.replace("dir ", "")
|
||||||
|
if(!current.files[path]) current.files[path] = Entry.dir(current)
|
||||||
|
} else {
|
||||||
|
var split = line.split(" ")
|
||||||
|
var size = Num.fromString(split[0])
|
||||||
|
var path = split[1]
|
||||||
|
if(!current.files[path]) current.files[path] = Entry.file(current, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sum_p1 = 0
|
||||||
|
var smallest_p2 = Num.infinity
|
||||||
|
|
||||||
|
var to_free = 30000000 - (70000000 - root.total_size)
|
||||||
|
root.iter_dirs {|dir|
|
||||||
|
var size = dir.total_size
|
||||||
|
if(size <= 100000) sum_p1 = sum_p1 + size
|
||||||
|
if(size >= to_free && size <= smallest_p2) smallest_p2 = size
|
||||||
|
}
|
||||||
|
|
||||||
|
System.print(sum_p1)
|
||||||
|
System.print(smallest_p2)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
*.a
|
||||||
|
*.o
|
||||||
|
aoc.c
|
||||||
|
wren_aoc
|
||||||
|
wren.h
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
var CC: 'gcc'
|
||||||
|
var CFLAGS: '-Wall', '-Wextra', '-Werror'
|
||||||
|
var LDFLAGS: '-lm'
|
||||||
|
|
||||||
|
with public default target 'all'
|
||||||
|
\depends 'wren_aoc'
|
||||||
|
|
||||||
|
with public target 'wren_aoc'
|
||||||
|
\depends 'main.o', 'aoc.o', 'libwren.a'
|
||||||
|
\produces '%'
|
||||||
|
\fn => _.cmd CC, CFLAGS, @infiles, '-o', @outfile, LDFLAGS
|
||||||
|
|
||||||
|
with target {'main.o', 'aoc.o'}, pattern: '%.o'
|
||||||
|
\depends '%.c'
|
||||||
|
\produces '%.o'
|
||||||
|
\fn => _.cmd CC, CFLAGS, @infile, '-o', @outfile, '-c'
|
||||||
|
|
||||||
|
with target 'aoc.c'
|
||||||
|
\depends 'aoc.wren'
|
||||||
|
\produces '%'
|
||||||
|
\fn =>
|
||||||
|
code = _.readfile @infile
|
||||||
|
c_code = "extern const char* aoc_mod = \"#{code\gsub('"', '\\"')\gsub('\n', '\\n')}\";\n"
|
||||||
|
_.writefile @outfile, c_code
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class AoC {
|
||||||
|
foreign static input
|
||||||
|
}
|
||||||
+117
@@ -0,0 +1,117 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "wren.h"
|
||||||
|
|
||||||
|
extern char* aoc_mod;
|
||||||
|
|
||||||
|
char* read_file(const char* path) {
|
||||||
|
FILE* fp = fopen(path, "rb");
|
||||||
|
if(fp == NULL) return NULL;
|
||||||
|
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
size_t len = ftell(fp);
|
||||||
|
fseek(fp, 0, SEEK_SET);
|
||||||
|
|
||||||
|
char* out = calloc(len + 1, 1);
|
||||||
|
if(out == NULL) {
|
||||||
|
fclose(fp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(len != fread(out, 1, len, fp)) {
|
||||||
|
fclose(fp);
|
||||||
|
free(out);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeFn(WrenVM* vm, const char* text) {
|
||||||
|
(void)(vm);
|
||||||
|
printf("%s", text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
|
||||||
|
(void)(vm);
|
||||||
|
switch (errorType) {
|
||||||
|
case WREN_ERROR_COMPILE:
|
||||||
|
printf("[%s line %d] [Error] %s\n", module, line, msg);
|
||||||
|
break;
|
||||||
|
case WREN_ERROR_STACK_TRACE:
|
||||||
|
printf("[%s line %d] in %s\n", module, line, msg);
|
||||||
|
break;
|
||||||
|
case WREN_ERROR_RUNTIME:
|
||||||
|
printf("[Runtime Error] %s\n", msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_input(WrenVM* vm) {
|
||||||
|
char* data = read_file("input.txt");
|
||||||
|
if(data != NULL) {
|
||||||
|
wrenSetSlotString(vm, 0, data);
|
||||||
|
free(data);
|
||||||
|
} else {
|
||||||
|
wrenSetSlotNull(vm, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WrenForeignMethodFn bindForeignMethodFn(WrenVM* vm, const char* module, const char* className, bool isStatic, const char* signature) {
|
||||||
|
(void)(vm);
|
||||||
|
if(!strcmp(module, "aoc") && !strcmp(className, "AoC") && isStatic && !strcmp(signature, "input")) {
|
||||||
|
return &load_input;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
WrenLoadModuleResult loadModuleFn(WrenVM* vm, const char* name) {
|
||||||
|
(void)(vm);
|
||||||
|
WrenLoadModuleResult result = {0};
|
||||||
|
if(!strcmp(name, "aoc")) {
|
||||||
|
result.source = aoc_mod;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
(void)(argc);
|
||||||
|
int exit_code = 0;
|
||||||
|
|
||||||
|
if(argv[1] == NULL) {
|
||||||
|
fprintf(stderr, "Syntax: %s <FILE>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* code = read_file(argv[1]);
|
||||||
|
if(code == NULL) {
|
||||||
|
fprintf(stderr, "Couldn't load file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
WrenConfiguration config;
|
||||||
|
wrenInitConfiguration(&config);
|
||||||
|
|
||||||
|
config.writeFn = &writeFn;
|
||||||
|
config.errorFn = &errorFn;
|
||||||
|
config.loadModuleFn = &loadModuleFn;
|
||||||
|
config.bindForeignMethodFn = &bindForeignMethodFn;
|
||||||
|
|
||||||
|
WrenVM* vm = wrenNewVM(&config);
|
||||||
|
WrenInterpretResult result = wrenInterpret(vm, "main", code);
|
||||||
|
free(code);
|
||||||
|
|
||||||
|
if(result == WREN_RESULT_COMPILE_ERROR) {
|
||||||
|
fprintf(stderr, "Wren exited with compile error\n");
|
||||||
|
exit_code = 1;
|
||||||
|
} else if(result == WREN_RESULT_RUNTIME_ERROR) {
|
||||||
|
fprintf(stderr, "Wren exited with runtime error\n");
|
||||||
|
exit_code = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wrenFreeVM(vm);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user