Compare commits

...

2 Commits

Author SHA1 Message Date
Codinget 52dfdcc4bb day 7, wren 2 years ago
Codinget 64040259cb wren wrapper 2 years ago
  1. 83
      d7-wren/main.wren
  2. 5
      wren/.gitignore
  3. 24
      wren/Build.moon
  4. 3
      wren/aoc.wren
  5. 117
      wren/main.c

@ -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)

5
wren/.gitignore vendored

@ -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
}

@ -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;
}
Loading…
Cancel
Save