Merge remote-tracking branch '2019/main'
This commit is contained in:
commit
c27c60ce9a
|
@ -0,0 +1,4 @@
|
|||
bin/
|
||||
zig-out/
|
||||
zig-cache/
|
||||
target/
|
|
@ -0,0 +1,13 @@
|
|||
.PHONY: bench-build bench-rebuild bench
|
||||
|
||||
bench-build:
|
||||
hyperfine -p 'rm -f bin/main' -c 'rm -f bin/main' 'rustc --out-dir bin/ main.rs'
|
||||
hyperfine -p 'rm -rf zig-out/ zig-cache/' -c 'rm -rf zig-out/ zig-cache/' '~/src/misc/zig/build/zig build'
|
||||
|
||||
bench-rebuild:
|
||||
hyperfine 'rustc --out-dir bin/ main.rs'
|
||||
hyperfine '~/src/misc/zig/build/zig build'
|
||||
|
||||
bench:
|
||||
hyperfine -p 'rustc --out-dir bin/ main.rs' ./bin/main
|
||||
hyperfine -p '~/src/misc/zig/build/zig build' ./zig-out/bin/day1
|
|
@ -0,0 +1,27 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.build.Builder) void {
|
||||
// Standard target options allows the person running `zig build` to choose
|
||||
// what target to build for. Here we do not override the defaults, which
|
||||
// means any target is allowed, and the default is native. Other options
|
||||
// for restricting supported target set are available.
|
||||
const target = b.standardTargetOptions(.{});
|
||||
|
||||
// Standard release options allow the person running `zig build` to select
|
||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
||||
const mode = b.standardReleaseOptions();
|
||||
|
||||
const exe = b.addExecutable("day1", "src/main.zig");
|
||||
exe.setTarget(target);
|
||||
exe.setBuildMode(mode);
|
||||
exe.install();
|
||||
|
||||
const run_cmd = exe.run();
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
if (b.args) |args| {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
|
||||
const run_step = b.step("run", "Run the app");
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
85644
|
||||
52584
|
||||
72349
|
||||
83834
|
||||
56593
|
||||
108492
|
||||
94585
|
||||
97733
|
||||
62732
|
||||
103113
|
||||
133259
|
||||
132647
|
||||
52460
|
||||
51299
|
||||
115749
|
||||
121047
|
||||
69451
|
||||
54737
|
||||
62738
|
||||
116686
|
||||
57293
|
||||
97273
|
||||
128287
|
||||
139440
|
||||
97583
|
||||
130263
|
||||
79307
|
||||
118198
|
||||
82514
|
||||
70679
|
||||
64485
|
||||
119346
|
||||
136281
|
||||
114724
|
||||
73580
|
||||
76314
|
||||
126198
|
||||
97635
|
||||
114655
|
||||
104195
|
||||
99469
|
||||
70251
|
||||
82815
|
||||
79531
|
||||
58135
|
||||
80625
|
||||
73106
|
||||
139806
|
||||
138478
|
||||
136605
|
||||
111472
|
||||
149915
|
||||
95928
|
||||
126905
|
||||
70496
|
||||
147999
|
||||
148501
|
||||
114025
|
||||
75716
|
||||
113473
|
||||
95390
|
||||
104466
|
||||
138715
|
||||
53053
|
||||
79502
|
||||
98601
|
||||
115139
|
||||
122315
|
||||
88402
|
||||
124332
|
||||
140107
|
||||
50912
|
||||
104885
|
||||
142005
|
||||
145938
|
||||
118556
|
||||
101858
|
||||
51142
|
||||
94100
|
||||
99421
|
||||
84544
|
||||
137234
|
||||
126374
|
||||
107333
|
||||
82439
|
||||
125373
|
||||
51212
|
||||
99358
|
||||
82821
|
||||
89913
|
||||
67513
|
||||
136907
|
||||
133707
|
||||
139988
|
||||
96914
|
||||
130672
|
||||
66474
|
||||
120729
|
||||
50131
|
||||
67475
|
|
@ -0,0 +1,29 @@
|
|||
fn main() {
|
||||
let contents = std::fs::read_to_string("input")
|
||||
.expect("Failed to read file 'input'");
|
||||
let it = contents.split("\n");
|
||||
let mut sum: u64 = 0;
|
||||
let mut sum2: u64 = 0;
|
||||
for val in it {
|
||||
if val == "" {
|
||||
continue;
|
||||
}
|
||||
let mut x = val.parse::<u64>().unwrap();
|
||||
x /= 3;
|
||||
x -= 2;
|
||||
sum += x;
|
||||
sum2 += x;
|
||||
while x > 0 {
|
||||
x /= 3;
|
||||
if x < 2 {
|
||||
x = 0;
|
||||
}
|
||||
else {
|
||||
x -= 2;
|
||||
}
|
||||
sum2 += x;
|
||||
}
|
||||
}
|
||||
println!("[Part 1] The sum is {}", sum);
|
||||
println!("[Part 2] The sum is {}", sum2);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
defer arena.deinit();
|
||||
const alloc = &arena.allocator;
|
||||
|
||||
// Read our input
|
||||
var f = try std.fs.cwd().openFile("input", .{});
|
||||
defer f.close();
|
||||
var contents = try f.readToEndAlloc(alloc, std.math.maxInt(u32));
|
||||
defer alloc.free(contents);
|
||||
|
||||
var it = std.mem.tokenize(contents, "\n");
|
||||
var sum: u64 = 0;
|
||||
var sum2: u64 = 0;
|
||||
while (it.next()) |v| {
|
||||
var val: u64 = try std.fmt.parseInt(u64, v, 10);
|
||||
val /= 3;
|
||||
val -= 2;
|
||||
sum += val;
|
||||
sum2 += val;
|
||||
while (val > 0) {
|
||||
val /= 3;
|
||||
if (val < 2) {
|
||||
val = 0;
|
||||
}
|
||||
else {
|
||||
val -= 2;
|
||||
}
|
||||
sum2 += val;
|
||||
}
|
||||
}
|
||||
std.log.info("[Part 1] Sum: {}", .{sum});
|
||||
std.log.info("[Part 2] Sum: {}", .{sum2});
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day2"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "day2"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1 @@
|
|||
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,10,19,1,9,19,23,1,13,23,27,1,5,27,31,2,31,6,35,1,35,5,39,1,9,39,43,1,43,5,47,1,47,5,51,2,10,51,55,1,5,55,59,1,59,5,63,2,63,9,67,1,67,5,71,2,9,71,75,1,75,5,79,1,10,79,83,1,83,10,87,1,10,87,91,1,6,91,95,2,95,6,99,2,99,9,103,1,103,6,107,1,13,107,111,1,13,111,115,2,115,9,119,1,119,6,123,2,9,123,127,1,127,5,131,1,131,5,135,1,135,5,139,2,10,139,143,2,143,10,147,1,147,5,151,1,151,2,155,1,155,13,0,99,2,14,0,0
|
|
@ -0,0 +1,105 @@
|
|||
fn main() {
|
||||
let contents = std::fs::read_to_string("input")
|
||||
.expect("Failed to read file 'input'");
|
||||
let it = contents.split(",");
|
||||
let mut program = Vec::new();
|
||||
for val in it {
|
||||
if val.ends_with('\n') {
|
||||
let mut s = String::from(val);
|
||||
s.pop();
|
||||
program.push(s.parse::<i32>().unwrap());
|
||||
}
|
||||
else {
|
||||
program.push(val.parse::<i32>().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
// Create a copy of the memory to refresh from
|
||||
let backup = program.clone();
|
||||
|
||||
// Modify state for part 1
|
||||
program[1] = 12;
|
||||
program[2] = 2;
|
||||
simulate(&mut program);
|
||||
println!("[Part 1] The value at position 0 is: {}", program[0]);
|
||||
|
||||
let mut noun = 0;
|
||||
while noun < 100 {
|
||||
let mut verb = 0;
|
||||
while verb < 100 {
|
||||
program = backup.clone();
|
||||
program[1] = noun;
|
||||
program[2] = verb;
|
||||
simulate(&mut program);
|
||||
//println!("Noun {}, verb {}: {}", noun, verb, program[0]);
|
||||
if program[0] == 19690720 {
|
||||
println!("[Part 2] noun {}, verb {}, sum {}", noun, verb, 100*noun+verb);
|
||||
break;
|
||||
}
|
||||
verb += 1;
|
||||
}
|
||||
noun += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn simulate(v: &mut Vec<i32>) {
|
||||
let mut pos = 0;
|
||||
loop {
|
||||
let code = v[pos];
|
||||
if code == 1 {
|
||||
let i1 = v[pos+1] as usize;
|
||||
let i2 = v[pos+2] as usize;
|
||||
let idest = v[pos+3] as usize;
|
||||
v[idest] = v[i1] + v[i2];
|
||||
pos += 4;
|
||||
continue;
|
||||
}
|
||||
else if code == 2 {
|
||||
let i1 = v[pos+1] as usize;
|
||||
let i2 = v[pos+2] as usize;
|
||||
let idest = v[pos+3] as usize;
|
||||
v[idest] = v[i1] * v[i2];
|
||||
pos += 4;
|
||||
continue;
|
||||
}
|
||||
else if code == 99 {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
panic!("Unknown opcode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn test_op_1() {
|
||||
let mut program = vec![1, 0, 0, 0, 99];
|
||||
simulate(&mut program);
|
||||
assert_eq!(program[0], 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_op_2() {
|
||||
let mut program = vec![2, 3, 0, 3, 99];
|
||||
simulate(&mut program);
|
||||
assert_eq!(program[3], 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_case_3() {
|
||||
let mut program = vec![2,4,4,5,99,0];
|
||||
simulate(&mut program);
|
||||
assert_eq!(program[program.len() - 1], 9801);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_case_4() {
|
||||
let mut program = vec![1,1,1,4,99,5,6,0,99];
|
||||
simulate(&mut program);
|
||||
assert_eq!(program[0], 30);
|
||||
assert_eq!(program[4], 2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day3"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "day3"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,2 @@
|
|||
R990,U944,L921,U993,L64,U29,R899,D406,R841,U716,L32,U658,L830,D481,L441,U491,L687,D847,L459,U920,R165,U224,L896,D868,L191,U877,L909,U467,R798,U132,R234,U49,R484,U911,R108,D308,R867,U350,L404,U107,L84,U668,R850,U470,L182,U93,R284,U999,L664,U110,R650,D189,R540,D112,R794,U999,R871,D829,L549,U988,R654,D411,R323,D774,R529,U275,L909,U936,R122,D922,L331,U813,L748,U770,R511,D892,L770,U318,R661,U823,R210,D393,L694,U929,L76,D619,R395,U651,R526,U145,R851,U112,R73,D89,R17,U929,R807,U87,R764,D158,L820,U803,L785,D205,L828,D271,L839,D482,L797,U338,R322,D633,L292,U16,R627,U19,R548,U516,L384,U83,R256,U937,R404,U322,R671,D543,L412,U446,R238,U246,L794,D750,L34,U317,L994,U874,L247,D20,R491,U834,L498,D987,R2,U175,R452,U168,R495,D183,R201,U532,L192,U984,L566,D471,L704,D2,L776,U5,R911,U308,R763,D555,R458,D439,L968,D78,R549,D583,R289,D355,L503,D871,L881,U516,L507,D551,R711,U702,L308,D905,L408,U932,L884,U218,L158,D562,L200,D114,R673,U448,R887,U181,R247,U329,L965,U495,L329,D162,L265,D389,R419,U435,R258,U146,R208,D184,R730,D19,L78,D886,R472,D350,R484,U392,L542,U601,L202,U974,L310,U52,L537,U597,L163,D655,R928,U269,L926,D790,L513,U441,L90,U581,L211,U871,R603,D130,L220,U459,L933,U648,R721,U642,R301,U537,L858,D777,R823,U14,R820,D218,L96,D318,L206,U280,R887,D241,L752,U828,R354,U864,R844,D872,L728,D298,L234,U695,R434,D94,R905,D592,L32,D860,R680,D197,R886,U760,L232,U916,L452,U248,R715,D773,R867,U77,R751,D36,R565,U897,R782,U931,R546,U261,R920,D296,R451,U258,L394,U965,R912,D593,L990
|
||||
L994,U515,R163,U863,L343,U162,L875,D92,L483,D601,R79,D761,L389,U167,L145,U145,L247,U886,R61,U820,L584,D239,R402,U805,R956,U126,R615,D322,R431,D460,R397,D511,R805,D177,L778,U296,R599,U759,R40,U1,L422,U751,R94,U401,R504,U940,L564,U24,R595,U944,R815,U672,R787,D854,R579,D604,L62,U670,L516,U199,L639,D919,L485,U655,R391,U669,R772,D34,R868,D12,L108,U295,R701,D603,R493,U927,R29,D34,R499,U111,L87,U190,R884,D658,R474,D166,R921,U698,R592,U25,R710,D398,L26,U696,L432,D887,R469,U656,L428,D188,L543,D150,R160,U543,R743,U692,R618,D148,R956,U753,L175,D789,R897,U305,L137,D914,R330,D780,R744,D473,L754,U482,L975,D413,L698,U656,L177,U419,R13,D827,L67,D800,R369,U97,L34,D588,L41,D760,L164,U224,L921,D311,R489,U956,R277,U180,R724,U748,R785,U826,L426,D957,R303,U16,L729,U224,L712,U43,L280,D648,R987,D941,R154,D581,R876,U615,L480,D103,R636,D276,R948,U89,R434,D212,R837,D295,R532,D390,R374,D926,R911,D110,R258,U83,L955,U747,L925,D366,R571,U241,R628,D344,R919,U117,R337,D683,L720,U261,L124,D545,R979,D601,L906,D324,R441,U678,L978,U744,L472,D217,R799,U740,L77,U964,L278,U497,R441,U21,L37,U319,L24,D211,L44,U459,R35,D609,R900,D538,R397,D776,R629,D860,R519,D340,R168,U603,R46,U889,R897,D442,R997,U705,L82,D963,R941,U701,L347,D824,R269,U891,L569,D558,L867,U145,R121,D369,R542,U227,L198,U863,L755,U273,L734,D233,R578,U67,L821,U600,L203,D234,R695,U819,L639,D700,R295,D129,L612,U157,R212,U536,L968,U562,L999,D391,L231,U262,R334,D967,R463,U748,R842,D500,R860,U856,R263,D633,R460,D337,L880,U146,R910
|
|
@ -0,0 +1,178 @@
|
|||
use std::collections::HashSet;
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn main() {
|
||||
let mut contents = std::fs::read_to_string("input")
|
||||
.expect("Failed to read file 'input'");
|
||||
let mut it = contents.split("\n");
|
||||
let mut line_a: HashSet<Point> = HashSet::new();
|
||||
let mut line_b: HashSet<Point> = HashSet::new();
|
||||
match it.next() {
|
||||
Some(v) => get_line_points_from_str(&mut line_a, &v),
|
||||
None => panic!(),
|
||||
}
|
||||
match it.next() {
|
||||
Some(v) => {
|
||||
let s = String::from(v);
|
||||
get_line_points_from_str(&mut line_b, &s);
|
||||
},
|
||||
None => panic!(),
|
||||
}
|
||||
|
||||
// Some possible approaches
|
||||
// my first thought was to do the following
|
||||
// 1) collect all points for line_a and line_b
|
||||
// 2) create a pool of intersecting points
|
||||
// 3) for all the intersecting points, which is
|
||||
// closest to the origin in manhattan distance
|
||||
//
|
||||
// this is pretty easy, but seems like it would be
|
||||
// memory hungry and doesn't scale to large lines
|
||||
// bonus: rust HashSets (wrappers around HashMap)
|
||||
// a union method to facilitate this task.
|
||||
//
|
||||
// another thought I had was to find and use some
|
||||
// sort of math things to compare to pair of line
|
||||
// segments to see if they intersect, and if so - where.
|
||||
|
||||
let mut closest_point: Point = Point {x: 0, y: 0};
|
||||
let mut closest_distance = i32::MAX;
|
||||
let mut intersects: HashSet<Point> = HashSet::new();
|
||||
for p in line_a.intersection(&line_b) {
|
||||
if p.x == 0 && p.y == 0 {
|
||||
continue;
|
||||
}
|
||||
intersects.insert(Point {x: p.x, y: p.y});
|
||||
let distance = p.x.abs() + p.y.abs();
|
||||
//println!("Intersection: {},{} distance {}",
|
||||
// p.x, p.y, distance);
|
||||
if distance < closest_distance {
|
||||
closest_point = Point {x: p.x, y: p.y};
|
||||
closest_distance = distance;
|
||||
}
|
||||
}
|
||||
println!("[Part 1] Closest intersection {} away at {},{}",
|
||||
closest_distance, closest_point.x, closest_point.y);
|
||||
|
||||
// We replay the get_line_poionts_from_str, but instead
|
||||
// when we reach one of the intersections we can add
|
||||
// Point, steps into a result set.
|
||||
let mut line_a_steps_to_intersect: HashMap<Point, u64> = HashMap::new();
|
||||
let mut line_b_steps_to_intersect: HashMap<Point, u64> = HashMap::new();
|
||||
contents = std::fs::read_to_string("input")
|
||||
.expect("Failed to read file 'input'");
|
||||
it = contents.split("\n");
|
||||
match it.next() {
|
||||
Some(v) => get_steps_to_intersections(&intersects, v,
|
||||
&mut line_a_steps_to_intersect),
|
||||
None => panic!(),
|
||||
}
|
||||
match it.next() {
|
||||
Some(v) => get_steps_to_intersections(&intersects, v,
|
||||
&mut line_b_steps_to_intersect),
|
||||
None => panic!(),
|
||||
}
|
||||
let mut step_sum = u64::MAX;
|
||||
let iit = intersects.iter();
|
||||
for p in iit {
|
||||
let new_sum = line_a_steps_to_intersect.get(&p).unwrap()
|
||||
+ line_b_steps_to_intersect.get(&p).unwrap();
|
||||
if new_sum < step_sum {
|
||||
step_sum = new_sum;
|
||||
closest_point = Point {x: p.x, y: p.y};
|
||||
}
|
||||
}
|
||||
println!("[Part 2] Intersection {},{} is {} steps away",
|
||||
closest_point.x, closest_point.y, step_sum);
|
||||
}
|
||||
|
||||
fn get_steps_to_intersections(points: &HashSet<Point>, source: &str, map: &mut HashMap<Point, u64>) {
|
||||
let mut x = 0;
|
||||
let mut y = 0;
|
||||
let mut total_steps = 0;
|
||||
let lit = source.split(",");
|
||||
for val in lit {
|
||||
let dir = val.chars().nth(0).unwrap();
|
||||
let mut dx = 0;
|
||||
let mut dy = 0;
|
||||
let v = val[1..].parse::<i32>().unwrap();
|
||||
match dir {
|
||||
'U' => dy = 1,
|
||||
'D' => dy = -1,
|
||||
'L' => dx = -1,
|
||||
'R' => dx = 1,
|
||||
_ => panic!(),
|
||||
}
|
||||
let mut needed_steps = 0;
|
||||
if dx != 0 {
|
||||
needed_steps = v;
|
||||
needed_steps = needed_steps.abs();
|
||||
}
|
||||
if dy != 0 {
|
||||
needed_steps = v;
|
||||
needed_steps = needed_steps.abs();
|
||||
}
|
||||
let mut step = 0;
|
||||
while step < needed_steps {
|
||||
x += dx;
|
||||
y += dy;
|
||||
total_steps += 1;
|
||||
let p = Point {x: x, y: y};
|
||||
if points.contains(&p) {
|
||||
//println!("Inserting intersection {},{} at {} steps",
|
||||
//p.x, p.y, total_steps);
|
||||
map.insert(p, total_steps);
|
||||
}
|
||||
step += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_line_points_from_str(points: &mut HashSet<Point>, source: &str) {
|
||||
let mut x = 0;
|
||||
let mut y = 0;
|
||||
points.insert(Point { x: x, y: y });
|
||||
let lit = source.split(",");
|
||||
for val in lit {
|
||||
let dir = val.chars().nth(0).unwrap();
|
||||
let mut dx = 0;
|
||||
let mut dy = 0;
|
||||
let v = val[1..].parse::<i32>().unwrap();
|
||||
match dir {
|
||||
'U' => dy = 1,
|
||||
'D' => dy = -1,
|
||||
'L' => dx = -1,
|
||||
'R' => dx = 1,
|
||||
_ => panic!(),
|
||||
}
|
||||
let mut needed_steps = 0;
|
||||
if dx != 0 {
|
||||
needed_steps = v;
|
||||
needed_steps = needed_steps.abs();
|
||||
}
|
||||
if dy != 0 {
|
||||
needed_steps = v;
|
||||
needed_steps = needed_steps.abs();
|
||||
}
|
||||
//println!("Walking from {},{} {}{} (step {},{} {} times)",
|
||||
//x, y, dir, v, dx, dy, needed_steps);
|
||||
let mut step = 0;
|
||||
while step < needed_steps {
|
||||
x += dx;
|
||||
y += dy;
|
||||
//println!("Adding {},{}", x, y);
|
||||
points.insert(Point {x: x, y: y});
|
||||
step += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
R8,U5,L5,D3
|
||||
U7,R6,D4,L4
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day4"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "day4"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,101 @@
|
|||
fn main() {
|
||||
let min = [1, 9, 3, 6, 5, 1];
|
||||
let max = [6, 4, 9, 7, 2, 9];
|
||||
|
||||
let mut matches = 0;
|
||||
let mut i = min.clone();
|
||||
loop {
|
||||
// Check for a adjacents
|
||||
if i[0] == i[1] ||
|
||||
i[1] == i[2] ||
|
||||
i[2] == i[3] ||
|
||||
i[3] == i[4] ||
|
||||
i[4] == i[5]
|
||||
{
|
||||
// Check for incrementing
|
||||
if i[0] <= i[1] &&
|
||||
i[1] <= i[2] &&
|
||||
i[2] <= i[3] &&
|
||||
i[3] <= i[4] &&
|
||||
i[4] <= i[5]
|
||||
{
|
||||
//println!("{:?} matches", i);
|
||||
matches += 1;
|
||||
}
|
||||
}
|
||||
let mut x = 5;
|
||||
loop {
|
||||
i[x] += 1;
|
||||
if i[x] >= 10 {
|
||||
i[x] -= 10;
|
||||
x -= 1;
|
||||
continue
|
||||
}
|
||||
break;
|
||||
}
|
||||
if i[0] >= max[0] &&
|
||||
i[1] >= max[1] &&
|
||||
i[2] >= max[2] &&
|
||||
i[3] >= max[3] &&
|
||||
i[4] >= max[4] &&
|
||||
i[5] >= max[5] {
|
||||
break;
|
||||
}
|
||||
}
|
||||
println!("[Part 1] There are {} potential matches", matches);
|
||||
|
||||
i = min.clone();
|
||||
matches = 0;
|
||||
loop {
|
||||
// Check for incrementing
|
||||
if i[0] <= i[1] &&
|
||||
i[1] <= i[2] &&
|
||||
i[2] <= i[3] &&
|
||||
i[3] <= i[4] &&
|
||||
i[4] <= i[5]
|
||||
{
|
||||
// Check for groups
|
||||
let mut idx = 0;
|
||||
let mut has_two_chain = false;
|
||||
let mut chain_size = 1;
|
||||
while idx < 5 {
|
||||
if i[idx] == i[idx+1] {
|
||||
chain_size += 1;
|
||||
idx += 1;
|
||||
}
|
||||
else {
|
||||
if chain_size == 2 {
|
||||
has_two_chain = true;
|
||||
}
|
||||
chain_size = 1;
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
if chain_size == 2 {
|
||||
has_two_chain = true;
|
||||
}
|
||||
if has_two_chain {
|
||||
matches += 1;
|
||||
}
|
||||
}
|
||||
let mut x = 5;
|
||||
loop {
|
||||
i[x] += 1;
|
||||
if i[x] >= 10 {
|
||||
i[x] -= 10;
|
||||
x -= 1;
|
||||
continue
|
||||
}
|
||||
break;
|
||||
}
|
||||
if i[0] >= max[0] &&
|
||||
i[1] >= max[1] &&
|
||||
i[2] >= max[2] &&
|
||||
i[3] >= max[3] &&
|
||||
i[4] >= max[4] &&
|
||||
i[5] >= max[5] {
|
||||
break;
|
||||
}
|
||||
}
|
||||
println!("[Part 2] There are {} potential matches", matches);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day5"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"icc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icc"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "day5"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
icc = { path = "../icc", version = "0.1.0"}
|
|
@ -0,0 +1 @@
|
|||
3,225,1,225,6,6,1100,1,238,225,104,0,1102,72,20,224,1001,224,-1440,224,4,224,102,8,223,223,1001,224,5,224,1,224,223,223,1002,147,33,224,101,-3036,224,224,4,224,102,8,223,223,1001,224,5,224,1,224,223,223,1102,32,90,225,101,65,87,224,101,-85,224,224,4,224,1002,223,8,223,101,4,224,224,1,223,224,223,1102,33,92,225,1102,20,52,225,1101,76,89,225,1,117,122,224,101,-78,224,224,4,224,102,8,223,223,101,1,224,224,1,223,224,223,1102,54,22,225,1102,5,24,225,102,50,84,224,101,-4600,224,224,4,224,1002,223,8,223,101,3,224,224,1,223,224,223,1102,92,64,225,1101,42,83,224,101,-125,224,224,4,224,102,8,223,223,101,5,224,224,1,224,223,223,2,58,195,224,1001,224,-6840,224,4,224,102,8,223,223,101,1,224,224,1,223,224,223,1101,76,48,225,1001,92,65,224,1001,224,-154,224,4,224,1002,223,8,223,101,5,224,224,1,223,224,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1107,677,226,224,1002,223,2,223,1005,224,329,101,1,223,223,7,677,226,224,102,2,223,223,1005,224,344,1001,223,1,223,1107,226,226,224,1002,223,2,223,1006,224,359,1001,223,1,223,8,226,226,224,1002,223,2,223,1006,224,374,101,1,223,223,108,226,226,224,102,2,223,223,1005,224,389,1001,223,1,223,1008,226,226,224,1002,223,2,223,1005,224,404,101,1,223,223,1107,226,677,224,1002,223,2,223,1006,224,419,101,1,223,223,1008,226,677,224,1002,223,2,223,1006,224,434,101,1,223,223,108,677,677,224,1002,223,2,223,1006,224,449,101,1,223,223,1108,677,226,224,102,2,223,223,1006,224,464,1001,223,1,223,107,677,677,224,102,2,223,223,1005,224,479,101,1,223,223,7,226,677,224,1002,223,2,223,1006,224,494,1001,223,1,223,7,677,677,224,102,2,223,223,1006,224,509,101,1,223,223,107,226,677,224,1002,223,2,223,1006,224,524,1001,223,1,223,1007,226,226,224,102,2,223,223,1006,224,539,1001,223,1,223,108,677,226,224,102,2,223,223,1005,224,554,101,1,223,223,1007,677,677,224,102,2,223,223,1006,224,569,101,1,223,223,8,677,226,224,102,2,223,223,1006,224,584,1001,223,1,223,1008,677,677,224,1002,223,2,223,1006,224,599,1001,223,1,223,1007,677,226,224,1002,223,2,223,1005,224,614,101,1,223,223,1108,226,677,224,1002,223,2,223,1005,224,629,101,1,223,223,1108,677,677,224,1002,223,2,223,1005,224,644,1001,223,1,223,8,226,677,224,1002,223,2,223,1006,224,659,101,1,223,223,107,226,226,224,102,2,223,223,1005,224,674,101,1,223,223,4,223,99,226
|
|
@ -0,0 +1,29 @@
|
|||
use icc;
|
||||
|
||||
fn main() {
|
||||
let contents = std::fs::read_to_string("input")
|
||||
.expect("Failed to read file 'input'");
|
||||
let it = contents.split(",");
|
||||
let mut program = Vec::new();
|
||||
for val in it {
|
||||
if val.ends_with('\n') {
|
||||
let mut s = String::from(val);
|
||||
s.pop();
|
||||
program.push(s.parse::<i32>().unwrap());
|
||||
}
|
||||
else {
|
||||
program.push(val.parse::<i32>().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
// Create a copy of the memory to refresh from
|
||||
let backup = program.clone();
|
||||
|
||||
let mut output: i32 = 0;
|
||||
println!("Start part 1");
|
||||
icc::simulate(&mut program, 1, &mut output);
|
||||
|
||||
program = backup.clone();
|
||||
println!("\nStart part 2");
|
||||
icc::simulate(&mut program, 5, &mut output);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day6"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "day6"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,169 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
fn copy_to_array(a: &mut [char; 3], b: &str) {
|
||||
assert_eq!(b.len(), 3);
|
||||
let mut x = 0;
|
||||
for c in b.chars() {
|
||||
a[x] = c;
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
{
|
||||
let test_map = get_map_from_file("test");
|
||||
assert_eq!(test_map.get("COM").unwrap().distance_to_com(&test_map), 0);
|
||||
assert_eq!(test_map.get("B").unwrap().distance_to_com(&test_map), 1);
|
||||
assert_eq!(test_map.get("D").unwrap().distance_to_com(&test_map), 3);
|
||||
assert_eq!(test_map.get("L").unwrap().distance_to_com(&test_map), 7);
|
||||
let f_parents = test_map.get("F").unwrap().parents(&test_map);
|
||||
assert_eq!(f_parents, vec!["E", "D", "C", "B", "COM"]);
|
||||
let l_parents = test_map.get("L").unwrap().parents(&test_map);
|
||||
assert_eq!(l_parents, vec!["K", "J", "E", "D", "C", "B", "COM"]);
|
||||
assert_eq!(first_common(f_parents, l_parents), "E");
|
||||
let mut x: i32 = 0;
|
||||
for val in test_map.values() {
|
||||
x += val.distance_to_com(&test_map);
|
||||
}
|
||||
assert_eq!(x, 42);
|
||||
}
|
||||
|
||||
{
|
||||
let test_map2 = get_map_from_file("test2");
|
||||
let you = test_map2.get("YOU").unwrap();
|
||||
let san = test_map2.get("SAN").unwrap();
|
||||
println!("{:?}", you);
|
||||
println!("{:?}", san);
|
||||
println!("{:?}", you.parents(&test_map2));
|
||||
println!("{:?}", san.parents(&test_map2));
|
||||
let parent = first_common(you.parents(&test_map2), san.parents(&test_map2));
|
||||
println!("First common parent of YOU and SAN: '{}'", parent);
|
||||
println!("Distance from YOU to {}: {}", parent, you.distance_to(&parent, &test_map2));
|
||||
println!("Distance from SAN to {}: {}", parent, san.distance_to(&parent, &test_map2));
|
||||
|
||||
println!("[Test2] Transfers required to go from YOU to SAN: {}",
|
||||
you.distance_to(&parent, &test_map2) + san.distance_to(&parent, &test_map2) - 2);
|
||||
}
|
||||
|
||||
let map = get_map_from_file("input");
|
||||
let mut x: i32 = 0;
|
||||
for val in map.values() {
|
||||
x += val.distance_to_com(&map);
|
||||
}
|
||||
println!("[Part 1] Total indirect and direct orbits: {}", x);
|
||||
|
||||
let you = map.get("YOU").unwrap();
|
||||
let you_parents = you.parents(&map);
|
||||
let san = map.get("SAN").unwrap();
|
||||
let san_parents = san.parents(&map);
|
||||
let common_parent = first_common(you_parents, san_parents);
|
||||
println!("First common parent of YOU and SAN: '{}'", common_parent);
|
||||
println!("Distance from YOU to {}: {}", common_parent, you.distance_to(&common_parent, &map));
|
||||
println!("Distance from SAN to {}: {}", common_parent, san.distance_to(&common_parent, &map));
|
||||
println!("[Part 2] Transfers required to go from YOU to SAN: {}",
|
||||
you.distance_to(&common_parent, &map) + san.distance_to(&common_parent, &map) - 2);
|
||||
}
|
||||
|
||||
fn first_common(a: Vec<String>, b: Vec<String>) -> String {
|
||||
let mut x: Option<usize> = None;
|
||||
for v_a in a.iter() {
|
||||
let mut iter: usize = 0;
|
||||
for v_b in b.iter() {
|
||||
if v_a == v_b {
|
||||
x = Some(iter);
|
||||
break;
|
||||
}
|
||||
iter += 1;
|
||||
}
|
||||
if x.is_some() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return b[x.unwrap()].clone();
|
||||
}
|
||||
|
||||
fn get_map_from_file(file: &str) -> HashMap<String, Node> {
|
||||
let contents = std::fs::read_to_string(file)
|
||||
.expect("Failed to read file 'input'");
|
||||
let it = contents.split("\n");
|
||||
let mut map: HashMap<String, Node> = HashMap::new();
|
||||
for line in it {
|
||||
let s = String::from(line);
|
||||
s.trim();
|
||||
if s.is_empty() {
|
||||
break;
|
||||
}
|
||||
{
|
||||
let values: Vec<&str> = s.split(")").collect();
|
||||
//println!("Line: {}", line);
|
||||
assert_eq!(values.len(), 2);
|
||||
//assert_eq!(values[0].len(), 3);
|
||||
//assert_eq!(values[1].len(), 3);
|
||||
for v in values {
|
||||
if !map.contains_key(v) {
|
||||
let n = Node {
|
||||
id: v.to_string(),
|
||||
parent: None,
|
||||
children: Vec::new(),
|
||||
};
|
||||
map.insert(v.to_string(), n);
|
||||
}
|
||||
}
|
||||
}
|
||||
let values: Vec<&str> = s.split(")").collect();
|
||||
{
|
||||
let mut node = map.get_mut(values[1]).unwrap();
|
||||
if !node.parent.is_some() {
|
||||
node.parent = Some(values[0].to_string());
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut node = map.get_mut(values[0]).unwrap();
|
||||
if !node.children.contains(&values[1].to_string()) {
|
||||
node.children.push(values[1].to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Node {
|
||||
parent: Option<String>,
|
||||
id: String,
|
||||
children: Vec<String>,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
|
||||
fn distance_to(&self, to: &str, map: &HashMap<String, Node>) -> i32 {
|
||||
if self.id == to {
|
||||
return 0;
|
||||
}
|
||||
let parent = self.parent.as_ref().unwrap().clone();
|
||||
return map.get(&parent).unwrap().distance_to(to, map) + 1;
|
||||
}
|
||||
|
||||
fn distance_to_com(&self, map: &HashMap<String, Node>) -> i32 {
|
||||
return self.distance_to("COM", map);
|
||||
}
|
||||
|
||||
fn parents(&self, map: &HashMap<String, Node>) -> Vec<String> {
|
||||
let mut parents: Vec<String> = Vec::new();
|
||||
if self.parent.is_some() {
|
||||
parents.push(self.parent.as_ref().unwrap().clone());
|
||||
let parent = map.get(&self.parent.as_ref().unwrap().clone()).unwrap();
|
||||
for v in parent.parents(map) {
|
||||
parents.push(v);
|
||||
}
|
||||
}
|
||||
return parents;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl PartialEq for Node {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
COM)B
|
||||
B)C
|
||||
C)D
|
||||
D)E
|
||||
E)F
|
||||
B)G
|
||||
G)H
|
||||
D)I
|
||||
E)J
|
||||
J)K
|
||||
K)L
|
||||
K)YOU
|
||||
I)SAN
|
|
@ -0,0 +1,30 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day7"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"icc",
|
||||
"itertools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "icc"
|
||||
version = "1.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day7"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
icc = { path = "../icc", version = "1.0.0"}
|
||||
itertools = "0.10.3"
|
|
@ -0,0 +1,132 @@
|
|||
use std::collections::VecDeque;
|
||||
use itertools::Itertools;
|
||||
|
||||
fn main() {
|
||||
let program = vec![3,8,1001,8,10,8,105,1,0,0,21,38,63,88,97,118,199,280,361,442,99999,3,9,1002,9,3,9,101,2,9,9,1002,9,4,9,4,9,99,3,9,101,3,9,9,102,5,9,9,101,3,9,9,1002,9,3,9,101,3,9,9,4,9,99,3,9,1002,9,2,9,1001,9,3,9,102,3,9,9,101,2,9,9,1002,9,4,9,4,9,99,3,9,102,2,9,9,4,9,99,3,9,102,4,9,9,101,5,9,9,102,2,9,9,101,5,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,99];
|
||||
|
||||
let mut max_storage = 0;
|
||||
let mut max_settings: Vec<i32> = Vec::new();
|
||||
|
||||
{
|
||||
let settings = vec![0, 1, 2, 3, 4];
|
||||
// Cheese.
|
||||
for permutation in settings.into_iter().permutations(5) {
|
||||
//println!("{:?}", permutation);
|
||||
let storage = run_amplifiers(&program, permutation.clone());
|
||||
if storage > max_storage {
|
||||
max_storage = storage;
|
||||
max_settings = permutation.clone();
|
||||
}
|
||||
}
|
||||
println!("[Part 1] Settings {:?} produced a value of {}", max_settings, max_storage);
|
||||
}
|
||||
|
||||
{
|
||||
let settings = vec![5, 6, 7, 8, 9];
|
||||
for permutation in settings.into_iter().permutations(5) {
|
||||
let storage = run_feedback_amplifiers(&program, permutation.clone());
|
||||
if storage > max_storage {
|
||||
max_storage = storage;
|
||||
max_settings = permutation.clone();
|
||||
}
|
||||
}
|
||||
println!("[Part 2] Settings {:?} produced a value of {}", max_settings, max_storage);
|
||||
}
|
||||
}
|
||||
|
||||
fn run_amplifiers(program: &Vec<i32>, settings: Vec<i32>) -> i32 {
|
||||
let mut storage: i32 = 0;
|
||||
for setting in settings {
|
||||
let mut input = VecDeque::from([setting, storage]);
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
icc::simulate(&mut program.clone(), &mut input, &mut output, 0);
|
||||
storage = output[0];
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
|
||||
fn run_feedback_amplifiers(program: &Vec<i32>, settings: Vec<i32>) -> i32 {
|
||||
let amplifiers = [
|
||||
// program, input signal, entrypoint, setting
|
||||
(&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running),
|
||||
(&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running),
|
||||
(&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running),
|
||||
(&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running),
|
||||
(&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running),
|
||||
];
|
||||
let mut iter: i32 = 0;
|
||||
loop {
|
||||
for (index, setting) in settings.iter().enumerate() {
|
||||
match amplifiers[index].3 {
|
||||
icc::Status::Finished => {
|
||||
if index == 4 {
|
||||
// the output of amplifier 4 is stored on the input of amplifier 0
|
||||
return *amplifiers[0].1;
|
||||
}
|
||||
continue;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
println!("[Iter {}] Running amplifier {} from instruction {}", iter, index, *amplifiers[index].2);
|
||||
let mut input = if iter == 0 {
|
||||
VecDeque::from([*setting, *amplifiers[index].1])
|
||||
} else {
|
||||
VecDeque::from([*amplifiers[index].1])
|
||||
};
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
let result = icc::simulate(amplifiers[index].0, &mut input, &mut output, *amplifiers[index].2);
|
||||
match result.status {
|
||||
icc::Status::WaitingForInput => {
|
||||
println!("[Iter {}] Amplifier {} is waiting for input", iter, index);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
let amp_index = (index+1) % settings.len();
|
||||
*amplifiers[amp_index].1 = output[0];
|
||||
println!("[Iter {}] Amplifier {}->{}: {}", iter, index, amp_index, output[0]);
|
||||
*amplifiers[index].2 = result.instruction;
|
||||
*amplifiers[index].3 = result.status;
|
||||
}
|
||||
iter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
let program = vec![3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0];
|
||||
let settings = vec![4, 3, 2, 1, 0];
|
||||
assert_eq!(run_amplifiers(&program, settings), 43210);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_2() {
|
||||
let program = vec![3,23,3,24,1002,24,10,24,1002,23,-1,23,101,5,23,23,1,24,23,23,4,23,99,0,0];
|
||||
let settings = vec![0,1,2,3,4];
|
||||
assert_eq!(run_amplifiers(&program, settings), 54321);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_3() {
|
||||
let program = vec![3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0];
|
||||
let settings = vec![1,0,4,3,2];
|
||||
assert_eq!(run_amplifiers(&program, settings), 65210);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_example_1() {
|
||||
let program = vec![3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5];
|
||||
let settings = vec![9,8,7,6,5];
|
||||
assert_eq!(run_feedback_amplifiers(&program, settings), 139629729);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_example_2() {
|
||||
let program = vec![3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10];
|
||||
let settings = vec![9,7,8,5,6];
|
||||
assert_eq!(run_feedback_amplifiers(&program, settings), 18216);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
kienan@monolith.244424:1652264161
|
|
@ -0,0 +1,132 @@
|
|||
use std::collections::VecDeque;
|
||||
use itertools::Itertools;
|
||||
|
||||
fn main() {
|
||||
let program = vec![3,8,1001,8,10,8,105,1,0,0,21,38,63,88,97,118,199,280,361,442,99999,3,9,1002,9,3,9,101,2,9,9,1002,9,4,9,4,9,99,3,9,101,3,9,9,102,5,9,9,101,3,9,9,1002,9,3,9,101,3,9,9,4,9,99,3,9,1002,9,2,9,1001,9,3,9,102,3,9,9,101,2,9,9,1002,9,4,9,4,9,99,3,9,102,2,9,9,4,9,99,3,9,102,4,9,9,101,5,9,9,102,2,9,9,101,5,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,99];
|
||||
|
||||
let mut max_storage = 0;
|
||||
let mut max_settings: Vec<i32> = Vec::new();
|
||||
|
||||
{
|
||||
let settings = vec![0, 1, 2, 3, 4];
|
||||
// Cheese.
|
||||
for permutation in settings.into_iter().permutations(5) {
|
||||
//println!("{:?}", permutation);
|
||||
let storage = run_amplifiers(&program, permutation.clone());
|
||||
if storage > max_storage {
|
||||
max_storage = storage;
|
||||
max_settings = permutation.clone();
|
||||
}
|
||||
}
|
||||
println!("[Part 1] Settings {:?} produced a value of {}", max_settings, max_storage);
|
||||
}
|
||||
|
||||
{
|
||||
let settings = vec![5, 6, 7, 8, 9];
|
||||
for permutation in settings.into_iter().permutations(5) {
|
||||
let storage = run_feedback_amplifiers(&program, permutation.clone());
|
||||
if storage > max_storage {
|
||||
max_storage = storage;
|
||||
max_settings = permutation.clone();
|
||||
}
|
||||
}
|
||||
println!("[Part 2] Settings {:?} produced a value of {}", max_settings, max_storage);
|
||||
}
|
||||
}
|
||||
|
||||
fn run_amplifiers(program: &Vec<i32>, settings: Vec<i32>) -> i32 {
|
||||
let mut storage: i32 = 0;
|
||||
for setting in settings {
|
||||
let mut input = VecDeque::from([setting, storage]);
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
icc::simulate(&mut program.clone(), &mut input, &mut output, 0);
|
||||
storage = output[0];
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
|
||||
fn run_feedback_amplifiers(program: &Vec<i32>, settings: Vec<i32>) -> i32 {
|
||||
let amplifiers = [
|
||||
// program, input signal, entrypoint, setting
|
||||
(&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running),
|
||||
(&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running),
|
||||
(&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running),
|
||||
(&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running),
|
||||
(&mut program.clone(), &mut 0, &mut 0usize, &mut icc::Status::Running),
|
||||
];
|
||||
let mut iter: i32 = 0;
|
||||
loop {
|
||||
for (index, setting) in settings.iter().enumerate() {
|
||||
match amplifiers[index].3 {
|
||||
icc::Status::Finished => {
|
||||
if index == 4 {
|
||||
// the output of amplifier 4 is stored on the input of amplifier 0
|
||||
return *amplifiers[0].1;
|
||||
}
|
||||
continue;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
println!("[Iter {}] Running amplifier {} from instruction {}", iter, index, *amplifiers[index].2);
|
||||
let mut input = if iter == 0 {
|
||||
VecDeque::from([*setting, *amplifiers[index].1])
|
||||
} else {
|
||||
VecDeque::from([*amplifiers[index].1])
|
||||
};
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
let result = icc::simulate(amplifiers[index].0, &mut input, &mut output, *amplifiers[index].2);
|
||||
match result.status {
|
||||
icc::Status::WaitingForInput => {
|
||||
println!("[Iter {}] Amplifier {} is waiting for input", iter, index);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
let amp_index = (index+1) % settings.len();
|
||||
*amplifiers[amp_index].1 = output[0];
|
||||
println!("[Iter {}] Amplifier {}->{}: {}", iter, index, amp_index, output[0]);
|
||||
*amplifiers[index].2 = result.instruction;
|
||||
*amplifiers[index].3 = result.status;
|
||||
}
|
||||
iter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
let program = vec![3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0];
|
||||
let settings = vec![4, 3, 2, 1, 0];
|
||||
assert_eq!(run_amplifiers(&program, settings), 43210);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_2() {
|
||||
let program = vec![3,23,3,24,1002,24,10,24,1002,23,-1,23,101,5,23,23,1,24,23,23,4,23,99,0,0];
|
||||
let settings = vec![0,1,2,3,4];
|
||||
assert_eq!(run_amplifiers(&program, settings), 54321);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example_3() {
|
||||
let program = vec![3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0];
|
||||
let settings = vec![1,0,4,3,2];
|
||||
assert_eq!(run_amplifiers(&program, settings), 65210);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_example_1() {
|
||||
let program = vec![3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5];
|
||||
let settings = vec![9,8,7,6,5];
|
||||
assert_eq!(run_feedback_amplifiers(&program, settings), 139629729);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_example_2() {
|
||||
let program = vec![3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10];
|
||||
let settings = vec![9,7,8,5,6];
|
||||
assert_eq!(run_feedback_amplifiers(&program, settings), 18216);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day8"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "day8"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,122 @@
|
|||
struct Image {
|
||||
width: usize,
|
||||
height: usize,
|
||||
layers: Vec<Vec<u32>>,
|
||||
}
|
||||
|
||||
impl Image {
|
||||
fn from_str(width: usize, height: usize, data: &str) -> Image {
|
||||
assert_eq!(data.len() % (width * height), 0);
|
||||
let mut image = Image {
|
||||
width: width,
|
||||
height: height,
|
||||
layers: Vec::new(),
|
||||
};
|
||||
let mut layer: usize = 0;
|
||||
image.layers.push(Vec::new());
|
||||
let mut index: usize = 0;
|
||||
for c in data.chars() {
|
||||
if index >= (width*height) {
|
||||
layer += 1;
|
||||
image.layers.push(Vec::new());
|
||||
index = 0;
|
||||
}
|
||||
image.layers[layer].push(c.to_digit(10).expect("Could not convert character to digit"));
|
||||
index += 1;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
fn layer_n_digits(&self, layer_index: usize, value: u32) -> usize {
|
||||
let mut count: usize = 0;
|
||||
for v in self.layers[layer_index].iter() {
|
||||
if *v == value {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
fn layer_merge(&self) -> Vec<u32> {
|
||||
let mut result: Vec<u32> = Vec::new();
|
||||
result.resize(self.width * self.height, 2);
|
||||
for pixel_index in 0..(self.width*self.height) {
|
||||
for layer_index in 0..self.layers.len() {
|
||||
// 2 is transparent
|
||||
let value = self.layers[layer_index][pixel_index];
|
||||
if value != 2 {
|
||||
result[pixel_index] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let data = std::fs::read_to_string("input")
|
||||
.expect("Failed to read 'input'");
|
||||
let image = Image::from_str(25, 6, &data);
|
||||
println!("Image contains {} layers", image.layers.len());
|
||||
let mut layer_fewest_zeroes: usize = 0;
|
||||
let mut least_zeroes: usize = 200;
|
||||
for index in 0..image.layers.len() {
|
||||
let n_zeroes = image.layer_n_digits(index, 0);
|
||||
if n_zeroes < least_zeroes {
|
||||
layer_fewest_zeroes = index;
|
||||
least_zeroes = n_zeroes;
|
||||
}
|
||||
}
|
||||
println!("Layer {} has {} zeroes", layer_fewest_zeroes, least_zeroes);
|
||||
println!("[Part 1] {}", image.layer_n_digits(layer_fewest_zeroes, 1) * image.layer_n_digits(layer_fewest_zeroes, 2));
|
||||
|
||||
let merged = image.layer_merge();
|
||||
let mut n: u32 = 0;
|
||||
for i in merged.iter() {
|
||||
let c = if *i == 0 {
|
||||
'⬛'
|
||||
} else if *i == 1 {
|
||||
'⬜'
|
||||
}
|
||||
else if *i == 2 {
|
||||
' '
|
||||
}
|
||||
else {
|
||||
'?'
|
||||
};
|
||||
print!("{}", c);
|
||||
n += 1;
|
||||
if n % 25 == 0 {
|
||||
print!("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn create_image() {
|
||||
let data = "123456789012";
|
||||
let image = Image::from_str(3, 2, data);
|
||||
assert_eq!(image.layers.len(), 2);
|
||||
let layer_0 = vec![1, 2, 3, 4, 5, 6];
|
||||
let layer_1 = vec![7, 8, 9, 0, 1, 2];
|
||||
assert_eq!(image.layers[0], layer_0);
|
||||
assert_eq!(image.layers[1], layer_1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn layer_merge() {
|
||||
let data = "0222112222120000";
|
||||
let image = Image::from_str(2, 2, data);
|
||||
let merged = image.layer_merge();
|
||||
assert_eq!(merged[0], 0);
|
||||
assert_eq!(merged[1], 1);
|
||||
assert_eq!(merged[2], 1);
|
||||
assert_eq!(merged[3], 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day9"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"icc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icc"
|
||||
version = "1.1.2"
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "day9"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
icc = { path = "../icc", version = "1.1.1"}
|
|
@ -0,0 +1 @@
|
|||
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,0,3,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,1,432,1027,1101,439,0,1026,1101,0,36,1010,1101,0,34,1018,1102,278,1,1029,1101,0,24,1002,1102,1,20,1016,1102,1,31,1011,1102,319,1,1024,1102,21,1,1012,1102,1,763,1022,1102,1,25,1007,1101,0,287,1028,1102,32,1,1008,1101,0,22,1013,1102,38,1,1001,1101,0,314,1025,1102,35,1,1009,1102,1,23,1015,1102,39,1,1019,1102,27,1,1000,1102,1,37,1003,1102,1,28,1017,1101,0,0,1020,1101,0,29,1004,1102,1,30,1006,1102,1,756,1023,1102,1,33,1005,1101,0,1,1021,1102,26,1,1014,109,13,2108,28,-7,63,1005,63,201,1001,64,1,64,1105,1,203,4,187,1002,64,2,64,109,8,21107,40,41,-3,1005,1018,225,4,209,1001,64,1,64,1105,1,225,1002,64,2,64,109,-3,1206,2,239,4,231,1105,1,243,1001,64,1,64,1002,64,2,64,109,-21,1201,6,0,63,1008,63,35,63,1005,63,267,1001,64,1,64,1105,1,269,4,249,1002,64,2,64,109,35,2106,0,-4,4,275,1001,64,1,64,1105,1,287,1002,64,2,64,109,-11,1205,-1,303,1001,64,1,64,1105,1,305,4,293,1002,64,2,64,109,8,2105,1,-5,4,311,1106,0,323,1001,64,1,64,1002,64,2,64,109,-7,21108,41,38,-6,1005,1016,339,1106,0,345,4,329,1001,64,1,64,1002,64,2,64,109,2,21102,42,1,-8,1008,1016,45,63,1005,63,369,1001,64,1,64,1105,1,371,4,351,1002,64,2,64,109,-14,21101,43,0,1,1008,1011,43,63,1005,63,397,4,377,1001,64,1,64,1106,0,397,1002,64,2,64,109,-8,21101,44,0,8,1008,1010,47,63,1005,63,417,1105,1,423,4,403,1001,64,1,64,1002,64,2,64,109,25,2106,0,0,1001,64,1,64,1105,1,441,4,429,1002,64,2,64,109,-20,2107,37,-6,63,1005,63,463,4,447,1001,64,1,64,1106,0,463,1002,64,2,64,109,8,2108,25,-8,63,1005,63,485,4,469,1001,64,1,64,1106,0,485,1002,64,2,64,109,-1,21107,45,44,-1,1005,1013,505,1001,64,1,64,1106,0,507,4,491,1002,64,2,64,109,-11,1207,-1,25,63,1005,63,529,4,513,1001,64,1,64,1106,0,529,1002,64,2,64,109,23,1206,-5,545,1001,64,1,64,1106,0,547,4,535,1002,64,2,64,109,-31,2102,1,5,63,1008,63,27,63,1005,63,569,4,553,1106,0,573,1001,64,1,64,1002,64,2,64,109,27,21102,46,1,-9,1008,1013,46,63,1005,63,595,4,579,1105,1,599,1001,64,1,64,1002,64,2,64,109,-26,2101,0,6,63,1008,63,24,63,1005,63,625,4,605,1001,64,1,64,1106,0,625,1002,64,2,64,109,5,1208,0,37,63,1005,63,645,1001,64,1,64,1105,1,647,4,631,1002,64,2,64,109,7,2102,1,-3,63,1008,63,31,63,1005,63,671,1001,64,1,64,1105,1,673,4,653,1002,64,2,64,109,2,1202,-5,1,63,1008,63,33,63,1005,63,699,4,679,1001,64,1,64,1105,1,699,1002,64,2,64,109,-4,2101,0,-3,63,1008,63,35,63,1005,63,719,1105,1,725,4,705,1001,64,1,64,1002,64,2,64,109,-5,1207,4,32,63,1005,63,741,1106,0,747,4,731,1001,64,1,64,1002,64,2,64,109,29,2105,1,-7,1001,64,1,64,1106,0,765,4,753,1002,64,2,64,109,-26,2107,36,5,63,1005,63,781,1105,1,787,4,771,1001,64,1,64,1002,64,2,64,109,10,1201,-6,0,63,1008,63,32,63,1005,63,809,4,793,1106,0,813,1001,64,1,64,1002,64,2,64,109,3,21108,47,47,-5,1005,1012,835,4,819,1001,64,1,64,1106,0,835,1002,64,2,64,109,-24,1202,9,1,63,1008,63,25,63,1005,63,859,1001,64,1,64,1106,0,861,4,841,1002,64,2,64,109,19,1205,9,875,4,867,1106,0,879,1001,64,1,64,1002,64,2,64,109,-3,1208,-1,32,63,1005,63,897,4,885,1106,0,901,1001,64,1,64,4,64,99,21102,27,1,1,21101,915,0,0,1105,1,922,21201,1,60043,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21102,1,942,0,1106,0,922,21202,1,1,-1,21201,-2,-3,1,21101,957,0,0,1106,0,922,22201,1,-1,-2,1105,1,968,22102,1,-2,-2,109,-3,2105,1,0
|
|
@ -0,0 +1,26 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
fn main() {
|
||||
let data = std::fs::read_to_string("input")
|
||||
.expect("Failed to read 'input'");
|
||||
let mut program: Vec<i64> = Vec::new();
|
||||
for v in data.split(",") {
|
||||
program.push(i64::from_str(v).unwrap());
|
||||
}
|
||||
|
||||
{
|
||||
let mut c = icc::Computer::initialize(program.clone(), vec![1]);
|
||||
c.run();
|
||||
if c.output.len() > 1 {
|
||||
println!("Some op-codes report failures");
|
||||
println!("Test output: {:?}", c.output);
|
||||
return;
|
||||
}
|
||||
println!("[Part 1] {}", c.output[0]);
|
||||
}
|
||||
{
|
||||
let mut c = icc::Computer::initialize(program.clone(), vec![2]);
|
||||
c.run();
|
||||
println!("[Part 2] {}", c.output[0]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "icc"
|
||||
version = "1.1.2"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "icc"
|
||||
version = "1.1.2"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,500 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(PartialEq)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Status {
|
||||
Running,
|
||||
Finished,
|
||||
WaitingForInput,
|
||||
}
|
||||
|
||||
pub struct Result {
|
||||
pub status: Status,
|
||||
pub instruction: usize,
|
||||
}
|
||||
|
||||
pub struct Computer {
|
||||
memory: HashMap<usize, i64>,
|
||||
position: usize,
|
||||
relative_base: i64,
|
||||
input: VecDeque<i64>,
|
||||
pub output: Vec<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Copy, Clone)]
|
||||
enum Operation {
|
||||
Add,
|
||||
Mul,
|
||||
Input,
|
||||
Output,
|
||||
JumpIfTrue,
|
||||
JumpIfFalse,
|
||||
LessThan,
|
||||
Equals,
|
||||
AdjustRelativeBase,
|
||||
End, // 99
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Copy, Clone)]
|
||||
enum ParameterMode {
|
||||
Position, // 0
|
||||
Immediate, // 1
|
||||
Relative, // 2
|
||||
}
|
||||
|
||||
impl ParameterMode {
|
||||
pub fn from_int(i: i64) -> ParameterMode {
|
||||
if i == 0 {
|
||||
ParameterMode::Position
|
||||
}
|
||||
else if i == 1 {
|
||||
ParameterMode::Immediate
|
||||
}
|
||||
else if i == 2 {
|
||||
ParameterMode::Relative
|
||||
}
|
||||
else {
|
||||
panic!("Unknown parameter mode integer value: {}", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Computer {
|
||||
pub fn initialize(program: Vec<i64>, input: Vec<i64>) -> Self {
|
||||
let mut computer = Computer {
|
||||
memory: HashMap::new(),
|
||||
position: 0,
|
||||
relative_base: 0,
|
||||
input: VecDeque::from(input),
|
||||
output: Vec::new(),
|
||||
};
|
||||
for i in 0..program.len() {
|
||||
computer.mem_put(i, program[i]);
|
||||
}
|
||||
return computer;
|
||||
}
|
||||
|
||||
fn mem_put(&mut self, address: usize, value: i64) {
|
||||
self.memory.insert(address, value);
|
||||
}
|
||||
|
||||
fn mem_get(&mut self, address: usize) -> i64 {
|
||||
let value = self.memory.get(&address);
|
||||
if value.is_none() {
|
||||
self.mem_put(address, 0);
|
||||
return 0;
|
||||
}
|
||||
return *value.unwrap();
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> Status {
|
||||
loop {
|
||||
let (op, p1_mode, p2_mode, p3_mode) = Self::decode_instruction(
|
||||
self.mem_get(self.position)
|
||||
);
|
||||
match op {
|
||||
Operation::Add => {
|
||||
let d1 = self.fetch(self.position + 1, p1_mode);
|
||||
let d2 = self.fetch(self.position + 2, p2_mode);
|
||||
let dest = self.absolute_address(self.position + 3, p3_mode);
|
||||
self.mem_put(dest, d1 + d2);
|
||||
self.position += 4;
|
||||
},
|
||||
Operation::Mul => {
|
||||
let d1 = self.fetch(self.position + 1, p1_mode);
|
||||
let d2 = self.fetch(self.position + 2, p2_mode);
|
||||
let dest = self.absolute_address(self.position + 3, p3_mode);
|
||||
self.mem_put(dest, d1 * d2);
|
||||
self.position += 4;
|
||||
},
|
||||
Operation::Input => {
|
||||
if self.input.len() == 0 {
|
||||
return Status::WaitingForInput;
|
||||
}
|
||||
let dest = self.absolute_address(self.position + 1, p1_mode);
|
||||
let input = self.input.pop_front().expect("Input queue empty... weird");
|
||||
self.mem_put(dest, input);
|
||||
println!("Input: {}", input);
|
||||
self.position += 2;
|
||||
},
|
||||
Operation::Output => {
|
||||
let value = self.fetch(self.position + 1, p1_mode);
|
||||
println!("Output: {}", value);
|
||||
self.output.push(value);
|
||||
self.position += 2;
|
||||
},
|
||||
Operation::JumpIfTrue => {
|
||||
let d1 = self.fetch(self.position + 1, p1_mode);
|
||||
let d2 = self.fetch(self.position + 2, p2_mode);
|
||||
if d1 != 0 {
|
||||
self.position = d2 as usize;
|
||||
}
|
||||
else {
|
||||
self.position += 3;
|
||||
}
|
||||
},
|
||||
Operation::JumpIfFalse => {
|
||||
let d1 = self.fetch(self.position + 1, p1_mode);
|
||||
let d2 = self.fetch(self.position + 2, p2_mode);
|
||||
if d1 == 0 {
|
||||
self.position = d2 as usize;
|
||||
}
|
||||
else {
|
||||
self.position += 3;
|
||||
}
|
||||
},
|
||||
Operation::LessThan => {
|
||||
let d1 = self.fetch(self.position + 1, p1_mode);
|
||||
let d2 = self.fetch(self.position + 2, p2_mode);
|
||||
let dest = self.absolute_address(self.position + 3, p3_mode);
|
||||
self.mem_put(dest, if d1 < d2 { 1 } else { 0 });
|
||||
self.position += 4;
|
||||
},
|
||||
Operation::Equals => {
|
||||
let d1 = self.fetch(self.position + 1, p1_mode);
|
||||
let d2 = self.fetch(self.position + 2, p2_mode);
|
||||
let dest = self.absolute_address(self.position + 3, p3_mode);
|
||||
self.mem_put(dest, if d1 == d2 { 1 } else { 0 });
|
||||
self.position += 4;
|
||||
},
|
||||
Operation::AdjustRelativeBase => {
|
||||
self.relative_base += self.fetch(self.position + 1, p1_mode);
|
||||
//println!("[RB: {}]", self.relative_base);
|
||||
self.position += 2;
|
||||
},
|
||||
Operation::End => {
|
||||
break;
|
||||
},
|
||||
other => {
|
||||
panic!("'{:?}' not implemented", other);
|
||||
},
|
||||
};
|
||||
}
|
||||
return Status::Finished;
|
||||
}
|
||||
|
||||
fn fetch(&mut self, pos: usize, mode: ParameterMode) -> i64 {
|
||||
let addr = self.absolute_address(pos, mode);
|
||||
return self.mem_get(addr);
|
||||
}
|
||||
|
||||
fn absolute_address(&mut self, pos: usize, mode: ParameterMode) -> usize {
|
||||
match mode {
|
||||
ParameterMode::Position => {
|
||||
self.mem_get(
|
||||
pos
|
||||
) as usize
|
||||
},
|
||||
ParameterMode::Immediate => {
|
||||
pos
|
||||
},
|
||||
ParameterMode::Relative => {
|
||||
let p = self.mem_get(pos) as i64 + self.relative_base;
|
||||
if p < 0 {
|
||||
panic!("Attempting to resolve illegale address: {}", p);
|
||||
}
|
||||
return p as usize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_instruction(code: i64) -> (Operation, ParameterMode, ParameterMode, ParameterMode) {
|
||||
// Opcodes are ABCDE, where the op is DE
|
||||
// the modes for params 1, 2, and 3 as C, B, A
|
||||
// respectively.
|
||||
let mut c = code;
|
||||
let op_int = code % 100;
|
||||
let op = if op_int == 1 {
|
||||
Operation::Add
|
||||
} else if op_int == 2 {
|
||||
Operation::Mul
|
||||
} else if op_int == 3 {
|
||||
Operation::Input
|
||||
} else if op_int == 4 {
|
||||
Operation::Output
|
||||
} else if op_int == 5 {
|
||||
Operation::JumpIfTrue
|
||||
} else if op_int == 6 {
|
||||
Operation::JumpIfFalse
|
||||
} else if op_int == 7 {
|
||||
Operation::LessThan
|
||||
} else if op_int == 8 {
|
||||
Operation::Equals
|
||||
} else if op_int == 9 {
|
||||
Operation::AdjustRelativeBase
|
||||
}else if op_int == 99 {
|
||||
Operation::End
|
||||
} else {
|
||||
panic!("Unknown opcode: {}", op_int);
|
||||
};
|
||||
|
||||
let param_3_mode_int = c / 10000;
|
||||
c -= param_3_mode_int * 10000;
|
||||
let param_2_mode_int = c / 1000;
|
||||
c -= param_2_mode_int * 1000;
|
||||
let param_1_mode_int = c / 100;
|
||||
return (
|
||||
op,
|
||||
ParameterMode::from_int(param_1_mode_int),
|
||||
ParameterMode::from_int(param_2_mode_int),
|
||||
ParameterMode::from_int(param_3_mode_int),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn simulate(v: &mut Vec<i32>, input: &mut VecDeque<i32>, output: &mut Vec<i32>, start: usize) -> Result {
|
||||
let mut program: Vec<i64> = Vec::new();
|
||||
for i in 0..v.len() {
|
||||
program.push(i64::from(v[i]));
|
||||
}
|
||||
let mut ip: VecDeque<i64> = VecDeque::new();
|
||||
for i in 0..input.len() {
|
||||
ip.push_front(i64::from(input[i]));
|
||||
}
|
||||
let mut computer = Computer::initialize(program, vec![]);
|
||||
computer.input = ip;
|
||||
computer.position = start;
|
||||
let r = computer.run();
|
||||
for i in 0..computer.output.len() {
|
||||
if computer.output[i] <= i64::from(i32::MAX) && computer.output[i] >= i64::from(i32::MIN) {
|
||||
output.push(computer.output[i] as i32);
|
||||
}
|
||||
else {
|
||||
panic!("Output value '{}' out of range for legacy i32 int-code computer", computer.output[i]);
|
||||
}
|
||||
}
|
||||
for i in 0..v.len() {
|
||||
v[i] = computer.mem_get(i) as i32;
|
||||
}
|
||||
return Result {
|
||||
status: r,
|
||||
instruction: computer.position,
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn test_op_1() {
|
||||
let mut program = vec![1, 0, 0, 0, 99];
|
||||
let mut input: VecDeque<i32> = VecDeque::new();
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
simulate(&mut program, &mut input, &mut output, 0);
|
||||
assert_eq!(program[0], 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_op_2() {
|
||||
let mut program = vec![2, 3, 0, 3, 99];
|
||||
let mut input: VecDeque<i32> = VecDeque::new();
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
simulate(&mut program, &mut input, &mut output, 0);
|
||||
assert_eq!(program[3], 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_case_3() {
|
||||
let mut program = vec![2,4,4,5,99,0];
|
||||
let mut input: VecDeque<i32> = VecDeque::new();
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
simulate(&mut program, &mut input, &mut output, 0);
|
||||
assert_eq!(program[program.len() - 1], 9801);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_case_4() {
|
||||
let mut program = vec![1,1,1,4,99,5,6,0,99];
|
||||
let mut input: VecDeque<i32> = VecDeque::new();
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
simulate(&mut program, &mut input, &mut output, 0);
|
||||
assert_eq!(program[0], 30);
|
||||
assert_eq!(program[4], 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn immediate_mode_multiply() {
|
||||
let mut program = vec![1002,4,3,4,33];
|
||||
let mut input: VecDeque<i32> = VecDeque::new();
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
simulate(&mut program, &mut input, &mut output, 0);
|
||||
assert_eq!(program[4], 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn negative_integers() {
|
||||
let mut program = vec![1101,100,-1,4,0];
|
||||
let mut input: VecDeque<i32> = VecDeque::new();
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
simulate(&mut program, &mut input, &mut output, 0);
|
||||
assert_eq!(program[4], 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn position_mode_input_equal_to_8() {
|
||||
let mut program = vec![3,9,8,9,10,9,4,9,99,-1,8];
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
let backup = program.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([8]), &mut output, 0);
|
||||
assert_eq!(output[0], 1);
|
||||
output.clear();
|
||||
program = backup.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([7]), &mut output, 0);
|
||||
assert_eq!(output[0], 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn position_mode_input_less_than_8() {
|
||||
let mut program = vec![3,9,7,9,10,9,4,9,99,-1,8];
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
let backup = program.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([8]), &mut output, 0);
|
||||
assert_eq!(output[0], 0);
|
||||
output.clear();
|
||||
program = backup.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([7]), &mut output, 0);
|
||||
assert_eq!(output[0], 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn immediate_mode_input_equal_to_8() {
|
||||
let mut program = vec![3,3,1108,-1,8,3,4,3,99];
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
let backup = program.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([8]), &mut output, 0);
|
||||
assert_eq!(output[0], 1);
|
||||
output.clear();
|
||||
program = backup.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([7]), &mut output, 0);
|
||||
assert_eq!(output[0], 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn immediate_mode_input_less_than_8() {
|
||||
let mut program = vec![3,3,1107,-1,8,3,4,3,99];
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
let backup = program.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([8]), &mut output, 0);
|
||||
assert_eq!(output[0], 0);
|
||||
output.clear();
|
||||
program = backup.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([7]), &mut output, 0);
|
||||
assert_eq!(output[0], 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn position_mode_input_is_non_zero() {
|
||||
let mut program = vec![3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9];
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
let backup = program.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([8]), &mut output, 0);
|
||||
assert_eq!(output[0], 1);
|
||||
output.clear();
|
||||
program = backup.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([0]), &mut output, 0);
|
||||
assert_eq!(output[0], 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn immediate_mode_input_is_non_zero() {
|
||||
let mut program = vec![3,3,1105,-1,9,1101,0,0,12,4,12,99,1];
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
let backup = program.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([9]), &mut output, 0);
|
||||
assert_eq!(output[0], 1);
|
||||
output.clear();
|
||||
program = backup.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([0]), &mut output, 0);
|
||||
assert_eq!(output[0], 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_jump() {
|
||||
let mut program = vec![3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31,1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104,999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99];
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
let backup = program.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([7]), &mut output, 0);
|
||||
assert_eq!(output[0], 999);
|
||||
output.clear();
|
||||
program = backup.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([8]), &mut output, 0);
|
||||
assert_eq!(output[0], 1000);
|
||||
output.clear();
|
||||
program = backup.clone();
|
||||
simulate(&mut program, &mut VecDeque::from([9]), &mut output, 0);
|
||||
assert_eq!(output[0], 1001);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blocks_on_input() {
|
||||
let mut program = vec![3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5];
|
||||
let mut output: Vec<i32> = Vec::new();
|
||||
let result = simulate(&mut program, &mut VecDeque::from([9, 0]), &mut output, 0);
|
||||
assert_eq!(result.status, Status::WaitingForInput);
|
||||
assert_eq!(result.instruction, 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn relative_base_adjust() {
|
||||
let mut c = Computer::initialize(vec![109, 1, 99], vec![]);
|
||||
c.run();
|
||||
assert_eq!(c.relative_base, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn negative_memory_access() {
|
||||
let mut c = Computer::initialize(vec![109, -5000, 204, 0, 99], vec![]);
|
||||
c.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn relative_example_1() {
|
||||
// The program produces an output of itself
|
||||
let program = vec![109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99];
|
||||
let mut c = Computer::initialize(program.clone(), vec![]);
|
||||
c.run();
|
||||
for i in 0..program.len() {
|
||||
assert_eq!(program[i], c.output[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn relative_example_2() {
|
||||
// Outputs a 16 digit numbers
|
||||
let program = vec![1102,34915192,34915192,7,4,7,99,0];
|
||||
let mut c = Computer::initialize(program, vec![]);
|
||||
c.run();
|
||||
assert_eq!(c.output[0].to_string().len(), 16);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn relative_example_3() {
|
||||
// Outputs 1125899906842624
|
||||
let program = vec![104,1125899906842624,99];
|
||||
let mut c = Computer::initialize(program, vec![]);
|
||||
c.run();
|
||||
assert_eq!(c.output[0], 1125899906842624);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn day9_relative_mode_input() {
|
||||
let program = vec![109, -2, 203, 2, 99];
|
||||
let mut c = Computer::initialize(program, vec![1312]);
|
||||
c.run();
|
||||
assert_eq!(c.mem_get(0), 1312);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn day9() {
|
||||
let program = vec![1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,0,3,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,1,432,1027,1101,439,0,1026,1101,0,36,1010,1101,0,34,1018,1102,278,1,1029,1101,0,24,1002,1102,1,20,1016,1102,1,31,1011,1102,319,1,1024,1102,21,1,1012,1102,1,763,1022,1102,1,25,1007,1101,0,287,1028,1102,32,1,1008,1101,0,22,1013,1102,38,1,1001,1101,0,314,1025,1102,35,1,1009,1102,1,23,1015,1102,39,1,1019,1102,27,1,1000,1102,1,37,1003,1102,1,28,1017,1101,0,0,1020,1101,0,29,1004,1102,1,30,1006,1102,1,756,1023,1102,1,33,1005,1101,0,1,1021,1102,26,1,1014,109,13,2108,28,-7,63,1005,63,201,1001,64,1,64,1105,1,203,4,187,1002,64,2,64,109,8,21107,40,41,-3,1005,1018,225,4,209,1001,64,1,64,1105,1,225,1002,64,2,64,109,-3,1206,2,239,4,231,1105,1,243,1001,64,1,64,1002,64,2,64,109,-21,1201,6,0,63,1008,63,35,63,1005,63,267,1001,64,1,64,1105,1,269,4,249,1002,64,2,64,109,35,2106,0,-4,4,275,1001,64,1,64,1105,1,287,1002,64,2,64,109,-11,1205,-1,303,1001,64,1,64,1105,1,305,4,293,1002,64,2,64,109,8,2105,1,-5,4,311,1106,0,323,1001,64,1,64,1002,64,2,64,109,-7,21108,41,38,-6,1005,1016,339,1106,0,345,4,329,1001,64,1,64,1002,64,2,64,109,2,21102,42,1,-8,1008,1016,45,63,1005,63,369,1001,64,1,64,1105,1,371,4,351,1002,64,2,64,109,-14,21101,43,0,1,1008,1011,43,63,1005,63,397,4,377,1001,64,1,64,1106,0,397,1002,64,2,64,109,-8,21101,44,0,8,1008,1010,47,63,1005,63,417,1105,1,423,4,403,1001,64,1,64,1002,64,2,64,109,25,2106,0,0,1001,64,1,64,1105,1,441,4,429,1002,64,2,64,109,-20,2107,37,-6,63,1005,63,463,4,447,1001,64,1,64,1106,0,463,1002,64,2,64,109,8,2108,25,-8,63,1005,63,485,4,469,1001,64,1,64,1106,0,485,1002,64,2,64,109,-1,21107,45,44,-1,1005,1013,505,1001,64,1,64,1106,0,507,4,491,1002,64,2,64,109,-11,1207,-1,25,63,1005,63,529,4,513,1001,64,1,64,1106,0,529,1002,64,2,64,109,23,1206,-5,545,1001,64,1,64,1106,0,547,4,535,1002,64,2,64,109,-31,2102,1,5,63,1008,63,27,63,1005,63,569,4,553,1106,0,573,1001,64,1,64,1002,64,2,64,109,27,21102,46,1,-9,1008,1013,46,63,1005,63,595,4,579,1105,1,599,1001,64,1,64,1002,64,2,64,109,-26,2101,0,6,63,1008,63,24,63,1005,63,625,4,605,1001,64,1,64,1106,0,625,1002,64,2,64,109,5,1208,0,37,63,1005,63,645,1001,64,1,64,1105,1,647,4,631,1002,64,2,64,109,7,2102,1,-3,63,1008,63,31,63,1005,63,671,1001,64,1,64,1105,1,673,4,653,1002,64,2,64,109,2,1202,-5,1,63,1008,63,33,63,1005,63,699,4,679,1001,64,1,64,1105,1,699,1002,64,2,64,109,-4,2101,0,-3,63,1008,63,35,63,1005,63,719,1105,1,725,4,705,1001,64,1,64,1002,64,2,64,109,-5,1207,4,32,63,1005,63,741,1106,0,747,4,731,1001,64,1,64,1002,64,2,64,109,29,2105,1,-7,1001,64,1,64,1106,0,765,4,753,1002,64,2,64,109,-26,2107,36,5,63,1005,63,781,1105,1,787,4,771,1001,64,1,64,1002,64,2,64,109,10,1201,-6,0,63,1008,63,32,63,1005,63,809,4,793,1106,0,813,1001,64,1,64,1002,64,2,64,109,3,21108,47,47,-5,1005,1012,835,4,819,1001,64,1,64,1106,0,835,1002,64,2,64,109,-24,1202,9,1,63,1008,63,25,63,1005,63,859,1001,64,1,64,1106,0,861,4,841,1002,64,2,64,109,19,1205,9,875,4,867,1106,0,879,1001,64,1,64,1002,64,2,64,109,-3,1208,-1,32,63,1005,63,897,4,885,1106,0,901,1001,64,1,64,4,64,99,21102,27,1,1,21101,915,0,0,1105,1,922,21201,1,60043,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21102,1,942,0,1106,0,922,21202,1,1,-1,21201,-2,-3,1,21101,957,0,0,1106,0,922,22201,1,-1,-2,1105,1,968,22102,1,-2,-2,109,-3,2105,1,0];
|
||||
let mut c = Computer::initialize(program, vec![1]);
|
||||
c.run();
|
||||
assert_eq!(c.output.len(), 1);
|
||||
assert_eq!(c.output[0], 3063082071);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue