Compare commits

..

5 Commits

Author SHA1 Message Date
codinget e416a50231 day 10, wren 2022-12-10 18:57:16 +00:00
codinget 8b771666f3 day 9, wren 2022-12-09 21:15:51 +00:00
codinget 4a0846a625 day 8, wren 2022-12-08 14:36:45 +00:00
codinget 5fe6870069 cleanup 2022-12-07 22:30:10 +00:00
codinget 1ca80ba6d2 day 7 2022-12-07 19:06:55 +00:00
7 changed files with 427 additions and 10 deletions
+53
View File
@@ -0,0 +1,53 @@
import "aoc" for AoC
class CPU {
construct new() {
_cycle = 0
_x = 1
_every20 = 0
_str = ""
}
every20 { _every20 }
str { _str }
tick() {
_cycle = _cycle + 1
if(_cycle % 40 == 20) {
_every20 = _every20 + _x * _cycle
}
var px = _cycle % 40
if(px == _x || px == _x + 1 || px == _x + 2) {
_str = _str + "#"
} else {
_str = _str + "."
}
if(_cycle % 40 == 0) {
_str = _str + "\n"
}
}
noop() {
tick()
}
addx(x) {
tick()
tick()
_x = _x + x
}
}
var cpu = CPU.new()
for(line in AoC.input.split("\n").where {|l| l != ""}) {
if(line == "noop") {
cpu.noop()
} else {
cpu.addx(Num.fromString(line.split(" ")[1]))
}
}
System.print(cpu.every20)
System.print(cpu.str)
+1 -10
View File
@@ -13,7 +13,6 @@ class Entry {
size { _size }
files { _files }
parent { _parent }
type { _files == null ? "file" : "dir" }
total_size {
if(_size) {
@@ -23,14 +22,6 @@ class Entry {
}
}
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)
@@ -80,4 +71,4 @@ root.iter_dirs {|dir|
}
System.print(sum_p1)
System.print(smallest_p2)
System.print(smallest_p2)
Generated
+7
View File
@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "d7"
version = "0.1.0"
+8
View File
@@ -0,0 +1,8 @@
[package]
name = "d7"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+127
View File
@@ -0,0 +1,127 @@
use std::{cell::RefCell, collections::HashMap, fs::read_to_string, io::Result, rc::Rc};
#[derive(Debug)]
enum Entry {
Dir(Option<RME>, HashMap<String, RME>),
File(usize),
}
type RME = Rc<RefCell<Entry>>;
impl Entry {
pub fn new_dir<S: AsRef<str>>(parent: &Option<RME>, name: S) -> RME {
let this = Rc::new(RefCell::new(Entry::Dir(parent.clone(), HashMap::new())));
let this_clone = this.clone();
match parent {
Some(parent) => match &mut *parent.borrow_mut() {
Entry::Dir(_, ref mut children) => {
children.insert(name.as_ref().to_owned(), this_clone);
}
_ => panic!("Attaching a child to a file"),
},
None => (),
}
this
}
pub fn new_file<S: AsRef<str>>(parent: RME, name: S, size: usize) -> RME {
let this = Rc::new(RefCell::new(Entry::File(size)));
let this_clone = this.clone();
match &mut *parent.borrow_mut() {
Entry::Dir(_, ref mut children) => {
children.insert(name.as_ref().to_owned(), this_clone);
}
_ => panic!("Attaching a child to a file"),
}
this
}
pub fn size(&self) -> usize {
match self {
Entry::File(size) => *size,
Entry::Dir(_, ref children) => children.values().map(|f| f.borrow().size()).sum(),
}
}
pub fn parent(&self) -> RME {
match self {
Entry::Dir(parent, _) => parent.as_ref().unwrap().clone(),
_ => panic!("Get parent for file"),
}
}
pub fn file<S: AsRef<str>>(&self, name: S) -> RME {
match self {
Entry::Dir(_, ref children) => children.get(name.as_ref()).unwrap().clone(),
_ => panic!("Get file for file"),
}
}
pub fn iter_dirs<F: FnMut(&Self)>(&self, f: &mut F) {
match self {
Entry::Dir(_, ref children) => {
f(self);
for child in children.values() {
child.borrow().iter_dirs(f);
}
}
_ => (),
}
}
}
fn main() -> Result<()> {
let none = None;
let root = Entry::new_dir(&none, "/");
let mut current = root.clone();
for line in read_to_string("input.txt")?
.split("\n")
.filter(|x| !x.is_empty())
{
if line.starts_with("$ cd ") {
let path = line.split_at(5).1;
if path == "/" {
current = root.clone();
} else if path == ".." {
let next = current.borrow().parent();
current = next;
} else {
let next = current.borrow().file(path);
current = next;
}
} else if line == "$ ls" {
// ignore
} else if line.starts_with("dir ") {
let path = line.split_at(4).1;
Entry::new_dir(&Some(current.clone()), path);
} else {
let split = line.split(" ").collect::<Vec<_>>();
let size = split[0].parse::<usize>().unwrap();
let path = split[1];
Entry::new_file(current.clone(), path, size);
}
}
let mut sum_p1 = 0;
let mut smallest_p2 = usize::MAX;
let to_free = 30000000usize - (70000000usize - root.borrow().size());
root.borrow().iter_dirs(&mut |dir| {
let size = dir.size();
if size <= 100000 {
sum_p1 += size
}
if size >= to_free && size <= smallest_p2 {
smallest_p2 = size
}
});
println!("Part 1: {}", sum_p1);
println!("Part 2: {}", smallest_p2);
Ok(())
}
+136
View File
@@ -0,0 +1,136 @@
import "aoc" for AoC
class Forest {
construct new(w, h) {
_w = w
_h = h
_trees = List.filled(w*h, 0)
}
w { _w }
h { _h }
get(x, y) { _trees[x+_w*y] }
set(x, y, t) { _trees[x+_w*y] = t }
visible_cardinal(x, y) {
if(x == 0 || y == 0 || x == w-1 || y == h-1) {
return true
}
var t = get(x, y)
var vis = true
for(xi in 0...x) {
if(get(xi, y) >= t) {
vis = false
break
}
}
if(vis) return true
vis = true
for(yi in 0...y) {
if(get(x, yi) >= t) {
vis = false
break
}
}
if(vis) return true
vis = true
for(xi in (x+1)...w) {
if(get(xi, y) >= t) {
vis = false
break
}
}
if(vis) return true
vis = true
for(yi in (y+1)...h) {
if(get(x, yi) >= t) {
vis = false
break
}
}
if(vis) return true
return false
}
score(x, y) {
if(x == 0 || y == 0 || x == w-1 || y == h-1) {
return 0
}
var t = get(x, y)
var score_left = 0
for(xi in (x-1)..0) {
score_left = score_left + 1
if(get(xi, y) >= t) {
break
}
}
var score_up = 0
for(yi in (y-1)..0) {
score_up = score_up + 1
if(get(x, yi) >= t) {
break
}
}
var score_right = 0
for(xi in (x+1)...(_w)) {
score_right = score_right + 1
if(get(xi, y) >= t) {
break
}
}
var score_down = 0
for(yi in (y+1)...(_h)) {
score_down = score_down + 1
if(get(x, yi) >= t) {
break
}
}
return score_left * score_up * score_right * score_down
}
}
var input = AoC.input
var row_count = input.where {|x| x == "\n"}.count
var lines = input.split("\n").where {|x| x != ""}
var forest = null
var x = 0
for(line in lines) {
if(!forest) forest = Forest.new(line.count, row_count)
var y = 0
for(tree in line) {
forest.set(x, y, Num.fromString(tree))
y = y + 1
}
x = x + 1
}
var total_visible = 0
var best_score = 0
for(x in 0...forest.w) {
for(y in 0...forest.h) {
if(forest.visible_cardinal(x, y)) {
total_visible = total_visible + 1
}
var score = forest.score(x, y)
if(score > best_score) {
best_score = score
}
}
}
System.print(total_visible)
System.print(best_score)
+95
View File
@@ -0,0 +1,95 @@
import "aoc" for AoC
class Pos {
construct new() {
_x = 0
_y = 0
}
x { _x }
y { _y }
touches(other) {
var dx = (_x - other.x).abs
var dy = (_y - other.y).abs
return dx <= 1 && dy <= 1
}
static movement(h, t) {
if(h.touches(t)) {
return ""
}
var dx = h.x - t.x
var dy = h.y - t.y
if(dx < 0 && dy < 0) {
return "LD"
}
if(dx < 0 && dy > 0) {
return "LU"
}
if(dx > 0 && dy < 0) {
return "RD"
}
if(dx > 0 && dy > 0) {
return "RU"
}
if(dx < 0 ) {
return "L"
}
if(dx > 0 ) {
return "R"
}
if(dy < 0 ) {
return "D"
}
if(dy > 0 ) {
return "U"
}
}
u() { _y = _y + 1 }
d() { _y = _y - 1 }
l() { _x = _x - 1 }
r() { _x = _x + 1 }
move(direction) {
for(c in direction) {
if(c == "U") this.u()
if(c == "D") this.d()
if(c == "L") this.l()
if(c == "R") this.r()
}
}
xy { _x.toString + "," + _y.toString }
}
var h = Pos.new()
var t = Pos.new()
var rope = []
for(i in 0...10) { rope.add(Pos.new()) }
var seen_p1 = {}
var seen_p2 = {}
for(line in AoC.input.split("\n").where {|l| l != ""}) {
var split = line.split(" ")
var direction = split[0]
var count = Num.fromString(split[1])
for(i in 0...count) {
h.move(direction)
t.move(Pos.movement(h, t))
seen_p1[t.xy] = true
rope[0].move(direction)
for(i in 1...10) { rope[i].move(Pos.movement(rope[i-1], rope[i])) }
seen_p2[rope[9].xy] = true
}
}
System.print(seen_p1.count)
System.print(seen_p2.count)