diff options
author | cos <cos> | 2019-12-09 21:16:35 +0100 |
---|---|---|
committer | cos <cos> | 2019-12-09 21:22:43 +0100 |
commit | 4c6c41b055d857f7dc2599262720a83da8d215be (patch) | |
tree | 6ebf781da98bf4f1cffa6045651e184468a771b4 /2019 | |
parent | 7c464db6ffb3872f46a422f7ee0345f46bffbeae (diff) | |
download | adventofcode-4c6c41b055d857f7dc2599262720a83da8d215be.zip |
Add day09, 2019
Diffstat (limited to '2019')
45 files changed, 1035 insertions, 0 deletions
diff --git a/2019/rust/Cargo.toml b/2019/rust/Cargo.toml index 91b5060..420d5ab 100644 --- a/2019/rust/Cargo.toml +++ b/2019/rust/Cargo.toml @@ -8,4 +8,5 @@ members = [ "day06", "day07", "day08", + "day09", ] diff --git a/2019/rust/day09/Cargo.toml b/2019/rust/day09/Cargo.toml new file mode 100644 index 0000000..88218ce --- /dev/null +++ b/2019/rust/day09/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day09" +version = "0.1.0" +authors = ["cos <cos>"] +edition = "2018" + +[dependencies] +getopts = "0.2" diff --git a/2019/rust/day09/both_parts.sh b/2019/rust/day09/both_parts.sh new file mode 100755 index 0000000..fb654a1 --- /dev/null +++ b/2019/rust/day09/both_parts.sh @@ -0,0 +1,3 @@ +echo 1|../target/release/day09 --mode stdio --program input +echo 2|../target/release/day09 --mode stdio --program input + diff --git a/2019/rust/day09/programs/template b/2019/rust/day09/programs/template new file mode 100644 index 0000000..b417129 --- /dev/null +++ b/2019/rust/day09/programs/template @@ -0,0 +1,21 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# Halt +99 diff --git a/2019/rust/day09/programs/test-add_immediate_immediate_position.iac b/2019/rust/day09/programs/test-add_immediate_immediate_position.iac new file mode 100644 index 0000000..a9b7495 --- /dev/null +++ b/2019/rust/day09/programs/test-add_immediate_immediate_position.iac @@ -0,0 +1,29 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# Add +1101,8,14,7 + +4,7 + +# Halt +99 + +# Result +0 diff --git a/2019/rust/day09/programs/test-add_immediate_immediate_position.out b/2019/rust/day09/programs/test-add_immediate_immediate_position.out new file mode 100644 index 0000000..2bd5a0a --- /dev/null +++ b/2019/rust/day09/programs/test-add_immediate_immediate_position.out @@ -0,0 +1 @@ +22 diff --git a/2019/rust/day09/programs/test-add_immediate_position_position.iac b/2019/rust/day09/programs/test-add_immediate_position_position.iac new file mode 100644 index 0000000..20188cf --- /dev/null +++ b/2019/rust/day09/programs/test-add_immediate_position_position.iac @@ -0,0 +1,29 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# Add +101,14,8,7 + +4,7 + +# Halt +99 + +# Result +0, 13 diff --git a/2019/rust/day09/programs/test-add_immediate_position_position.out b/2019/rust/day09/programs/test-add_immediate_position_position.out new file mode 100644 index 0000000..f64f5d8 --- /dev/null +++ b/2019/rust/day09/programs/test-add_immediate_position_position.out @@ -0,0 +1 @@ +27 diff --git a/2019/rust/day09/programs/test-add_position_immediate_position.iac b/2019/rust/day09/programs/test-add_position_immediate_position.iac new file mode 100644 index 0000000..b5894d8 --- /dev/null +++ b/2019/rust/day09/programs/test-add_position_immediate_position.iac @@ -0,0 +1,32 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# Add +1001,8,9,7 + +4,7 + +# Halt +99 + +# Result +0, 21 + +# Halt +99 diff --git a/2019/rust/day09/programs/test-add_position_immediate_position.out b/2019/rust/day09/programs/test-add_position_immediate_position.out new file mode 100644 index 0000000..64bb6b7 --- /dev/null +++ b/2019/rust/day09/programs/test-add_position_immediate_position.out @@ -0,0 +1 @@ +30 diff --git a/2019/rust/day09/programs/test-add_position_position_position.iac b/2019/rust/day09/programs/test-add_position_position_position.iac new file mode 100644 index 0000000..c68d932 --- /dev/null +++ b/2019/rust/day09/programs/test-add_position_position_position.iac @@ -0,0 +1,32 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# Add +1,8,9,7 + +4,7 + +# Halt +99 + +# Result +0, 11, 81 + +# Halt +99 diff --git a/2019/rust/day09/programs/test-add_position_position_position.out b/2019/rust/day09/programs/test-add_position_position_position.out new file mode 100644 index 0000000..cd5b025 --- /dev/null +++ b/2019/rust/day09/programs/test-add_position_position_position.out @@ -0,0 +1 @@ +92 diff --git a/2019/rust/day09/programs/test-eq_immediate_immediate_position.iac b/2019/rust/day09/programs/test-eq_immediate_immediate_position.iac new file mode 100644 index 0000000..4bdf1d1 --- /dev/null +++ b/2019/rust/day09/programs/test-eq_immediate_immediate_position.iac @@ -0,0 +1,30 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# Add +1108,5,5,7 + +# Out +4,7 + +# Halt +99 + +# Result +0 diff --git a/2019/rust/day09/programs/test-eq_immediate_immediate_position.out b/2019/rust/day09/programs/test-eq_immediate_immediate_position.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-eq_immediate_immediate_position.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-eq_immediate_position_position.iac b/2019/rust/day09/programs/test-eq_immediate_position_position.iac new file mode 100644 index 0000000..caaeee9 --- /dev/null +++ b/2019/rust/day09/programs/test-eq_immediate_position_position.iac @@ -0,0 +1,30 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# Add +108,99,6,7 + +# Out +4,7 + +# Halt +99 + +# Result +0 diff --git a/2019/rust/day09/programs/test-eq_immediate_position_position.out b/2019/rust/day09/programs/test-eq_immediate_position_position.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-eq_immediate_position_position.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-eq_position_immediate_position.iac b/2019/rust/day09/programs/test-eq_position_immediate_position.iac new file mode 100644 index 0000000..51f2129 --- /dev/null +++ b/2019/rust/day09/programs/test-eq_position_immediate_position.iac @@ -0,0 +1,30 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# Equals +1008,6,99,7 + +# Out +4,7 + +# Halt +99 + +# Result +0 diff --git a/2019/rust/day09/programs/test-eq_position_immediate_position.out b/2019/rust/day09/programs/test-eq_position_immediate_position.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-eq_position_immediate_position.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-eq_position_position_position.iac b/2019/rust/day09/programs/test-eq_position_position_position.iac new file mode 100644 index 0000000..de2bc1f --- /dev/null +++ b/2019/rust/day09/programs/test-eq_position_position_position.iac @@ -0,0 +1,30 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# Equals +8,6,6,7 + +# Out +4,7 + +# Halt +99 + +# Result +0 diff --git a/2019/rust/day09/programs/test-eq_position_position_position.out b/2019/rust/day09/programs/test-eq_position_position_position.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-eq_position_position_position.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-halt.iac b/2019/rust/day09/programs/test-halt.iac new file mode 100644 index 0000000..b417129 --- /dev/null +++ b/2019/rust/day09/programs/test-halt.iac @@ -0,0 +1,21 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# Halt +99 diff --git a/2019/rust/day09/programs/test-halt.out b/2019/rust/day09/programs/test-halt.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/2019/rust/day09/programs/test-halt.out diff --git a/2019/rust/day09/programs/test-in_position_out_position.iac b/2019/rust/day09/programs/test-in_position_out_position.iac new file mode 100644 index 0000000..1892ecf --- /dev/null +++ b/2019/rust/day09/programs/test-in_position_out_position.iac @@ -0,0 +1,28 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# In +3,5 +# Out +4,5 +# Halt +99 + +# Output value +0 diff --git a/2019/rust/day09/programs/test-in_position_out_position.in b/2019/rust/day09/programs/test-in_position_out_position.in new file mode 100644 index 0000000..425151f --- /dev/null +++ b/2019/rust/day09/programs/test-in_position_out_position.in @@ -0,0 +1 @@ +40 diff --git a/2019/rust/day09/programs/test-in_position_out_position.out b/2019/rust/day09/programs/test-in_position_out_position.out new file mode 100644 index 0000000..425151f --- /dev/null +++ b/2019/rust/day09/programs/test-in_position_out_position.out @@ -0,0 +1 @@ +40 diff --git a/2019/rust/day09/programs/test-jmpfalse_immediate_immediate.iac b/2019/rust/day09/programs/test-jmpfalse_immediate_immediate.iac new file mode 100644 index 0000000..e926e3e --- /dev/null +++ b/2019/rust/day09/programs/test-jmpfalse_immediate_immediate.iac @@ -0,0 +1,28 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# JmpFalse +1106,0,5 + +# Out +104,-1 +104,1 + +# Halt +99 diff --git a/2019/rust/day09/programs/test-jmpfalse_immediate_immediate.out b/2019/rust/day09/programs/test-jmpfalse_immediate_immediate.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-jmpfalse_immediate_immediate.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-jmpfalse_immediate_position.iac b/2019/rust/day09/programs/test-jmpfalse_immediate_position.iac new file mode 100644 index 0000000..7048632 --- /dev/null +++ b/2019/rust/day09/programs/test-jmpfalse_immediate_position.iac @@ -0,0 +1,31 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# JmpFalse +106,0,8 + +# Out +104,-1 +104,1 + +# Halt +99 + +# Jump target +5 diff --git a/2019/rust/day09/programs/test-jmpfalse_immediate_position.out b/2019/rust/day09/programs/test-jmpfalse_immediate_position.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-jmpfalse_immediate_position.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-jmpfalse_position_immediate.iac b/2019/rust/day09/programs/test-jmpfalse_position_immediate.iac new file mode 100644 index 0000000..4b00314 --- /dev/null +++ b/2019/rust/day09/programs/test-jmpfalse_position_immediate.iac @@ -0,0 +1,31 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# JmpFalse +1006,8,5 + +# Out +104,-1 +104,1 + +# Halt +99 + +# Value +0 diff --git a/2019/rust/day09/programs/test-jmpfalse_position_immediate.out b/2019/rust/day09/programs/test-jmpfalse_position_immediate.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-jmpfalse_position_immediate.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-jmpfalse_position_position.iac b/2019/rust/day09/programs/test-jmpfalse_position_position.iac new file mode 100644 index 0000000..ea536f7 --- /dev/null +++ b/2019/rust/day09/programs/test-jmpfalse_position_position.iac @@ -0,0 +1,34 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# JmpFalse +6,9,8 + +# Out +104,-1 +104,1 + +# Halt +99 + +# Target addr +5 + +# Value +0 diff --git a/2019/rust/day09/programs/test-jmpfalse_position_position.out b/2019/rust/day09/programs/test-jmpfalse_position_position.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-jmpfalse_position_position.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-jmptrue_immediate_immediate.iac b/2019/rust/day09/programs/test-jmptrue_immediate_immediate.iac new file mode 100644 index 0000000..cc4d669 --- /dev/null +++ b/2019/rust/day09/programs/test-jmptrue_immediate_immediate.iac @@ -0,0 +1,29 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# JmpTrue +1105,1,5 + +# Out +104,-1 +104,1 + +# Halt +99 + diff --git a/2019/rust/day09/programs/test-jmptrue_immediate_immediate.out b/2019/rust/day09/programs/test-jmptrue_immediate_immediate.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-jmptrue_immediate_immediate.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-jmptrue_immediate_position.iac b/2019/rust/day09/programs/test-jmptrue_immediate_position.iac new file mode 100644 index 0000000..a25b903 --- /dev/null +++ b/2019/rust/day09/programs/test-jmptrue_immediate_position.iac @@ -0,0 +1,31 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# JmpTrue +105,1,8 + +# Out +104,-1 +104,1 + +# Halt +99 + +# Jump target +5 diff --git a/2019/rust/day09/programs/test-jmptrue_immediate_position.out b/2019/rust/day09/programs/test-jmptrue_immediate_position.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-jmptrue_immediate_position.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-jmptrue_position_immediate.iac b/2019/rust/day09/programs/test-jmptrue_position_immediate.iac new file mode 100644 index 0000000..a4f4245 --- /dev/null +++ b/2019/rust/day09/programs/test-jmptrue_position_immediate.iac @@ -0,0 +1,28 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# JmpTrue +1005,0,5 + +# Out +104,-1 +104,1 + +# Halt +99 diff --git a/2019/rust/day09/programs/test-jmptrue_position_immediate.out b/2019/rust/day09/programs/test-jmptrue_position_immediate.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-jmptrue_position_immediate.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-jmptrue_position_position.iac b/2019/rust/day09/programs/test-jmptrue_position_position.iac new file mode 100644 index 0000000..ed68de5 --- /dev/null +++ b/2019/rust/day09/programs/test-jmptrue_position_position.iac @@ -0,0 +1,31 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, +# +# 1 (3) Add +# 2 (3) Mul +# 7 (3) LessThan +# 8 (3) Equals +# 3 (1) In +# 4 (1) Out +# 5 (2) JmpTrue +# 6 (2) JmpFalse +# 9 (1) BaseMod +# 99 (0) Halt + +# JmpTrue +5,0,8 + +# Out +104,-1 +104,1 + +# Halt +99 + +# Addr +5 diff --git a/2019/rust/day09/programs/test-jmptrue_position_position.out b/2019/rust/day09/programs/test-jmptrue_position_position.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/2019/rust/day09/programs/test-jmptrue_position_position.out @@ -0,0 +1 @@ +1 diff --git a/2019/rust/day09/programs/test-out_immediate.iac b/2019/rust/day09/programs/test-out_immediate.iac new file mode 100644 index 0000000..4aa8ccf --- /dev/null +++ b/2019/rust/day09/programs/test-out_immediate.iac @@ -0,0 +1,11 @@ +# ABCDE +# 210xx +# +# DE - two-digit opcode, xx == opcode x +# C - mode of 1st parameter, 0 == position mode +# B - mode of 2nd parameter, 1 == immediate mode +# A - mode of 3rd parameter, 0 == relative mode, + +# Out immediate +104,123 +99 diff --git a/2019/rust/day09/programs/test-out_immediate.out b/2019/rust/day09/programs/test-out_immediate.out new file mode 100644 index 0000000..190a180 --- /dev/null +++ b/2019/rust/day09/programs/test-out_immediate.out @@ -0,0 +1 @@ +123 diff --git a/2019/rust/day09/src/main.rs b/2019/rust/day09/src/main.rs new file mode 100644 index 0000000..ce7e236 --- /dev/null +++ b/2019/rust/day09/src/main.rs @@ -0,0 +1,353 @@ +use std::env; +use std::io::{self, BufRead, BufReader}; +use std::fs::File; + +type BusWidth = i128; +type IOType = i128; +type IOData = Vec<IOType>; + +fn read_program(filename: &str) -> Vec<BusWidth> { + let f = File::open(filename).expect(filename); + let f = BufReader::new(f); + + f.lines() + .filter(|line| match line { + Ok(s) => { + let b = s.as_bytes(); + if b.len() == 0 || b.len() > 0 && b[0] == b'#' { false } else { true } + }, + _ => true, + }) + .map(|line| match line { + Ok(line) => { + let data:Vec<BusWidth> = line.split(',').map(|e| { e.trim_start().trim_end() }) + .filter(|v| match v.parse::<BusWidth>() { Ok(_) => true, _ => { + eprintln!("Could not parse: {:?}", v); + false + }, + }) + .map(|r| r.parse().unwrap()) + .collect(); + + data + }, + Err(_) => panic!("Could not parse {}.", filename), + }).flatten().collect() +} + +#[derive(Clone, Debug)] +struct Memory { + mem: Vec<BusWidth>, +} + +impl Memory { + fn new() -> Memory { + Memory { mem: Vec::new(), } + } + + fn init(&mut self, mem:Vec<BusWidth>) { + self.mem = mem; + } + + fn read(&self, address: usize) -> BusWidth { + match self.mem.get(address) { + Some(value) => *value, + None => 0, + } + } + + fn write(&mut self, address: usize, value: BusWidth) { + if self.len() < address { + self.mem.resize(address*2, 0); + } + self.mem[address] = value; + } + + fn len(&self) -> usize { + self.mem.len() + } +} + +#[derive(Debug)] +struct Registers { + ip: usize, + base: usize, +} + +#[derive(Debug)] +enum Arithm { + Add, + Mul, + LessThan, + Equals, +} + +#[derive(Debug)] +enum IO { + In, + Out, +} + +#[derive(Debug)] +enum Jmp { + JmpTrue, + JmpFalse, +} + +#[derive(Debug)] +enum RegOp { + BaseMod, +} + +#[derive(Debug, PartialEq)] +enum ParameterMode { + Position, + Immediate, + Relative, +} + +#[derive(Debug, PartialEq)] +enum DataDirection { + Read, + Write, +} + +#[derive(PartialEq)] +enum IOMethod { + StdIO, + Variables, +} + +struct Intcode { + r: Registers, + io_method: IOMethod, + input: IOData, + output: IOData, +} + +impl Intcode { + fn new() -> Intcode { + Intcode { + r: Registers { ip: 0, base: 0, }, + io_method: IOMethod::Variables, + input: vec![], + output: vec![], + } + } + + fn param_to_argument(&self, mode: &ParameterMode, mem: &Memory, offset: usize, + dir: &DataDirection) -> usize + { + match mode { + ParameterMode::Position => { + if mem.read(offset) < 0 { + panic!("Attempt to address negative memory at IP: {}"); + } + mem.read(offset) as usize + }, + ParameterMode::Immediate => { + if *dir == DataDirection::Write { + panic!("Immediate parameter mode at IP: {}", self.r.ip); + } + offset + }, + ParameterMode::Relative => { + if (mem.read(offset) + self.r.base as BusWidth) < 0 { + panic!("Attempt to address negative memory at IP: {}"); + } + (mem.read(offset) + self.r.base as BusWidth) as usize + }, + } + } + + fn arithm(&self, op: Arithm, modes: Vec<ParameterMode>, memory: &mut Memory) { + let parameter_directions = + [DataDirection::Read, DataDirection::Read, DataDirection::Write]; + let params:Vec<usize> = (0..parameter_directions.len()) + .zip(parameter_directions.iter()) + .map(|(p, d)| { + self.param_to_argument(&modes[p], memory, self.r.ip + 1 + p, d) + }).collect(); + let left = params[0]; + let right = params[1]; + let result = params[2]; + + match op { + Arithm::Add => memory.write(result, memory.read(left) + memory.read(right)), + Arithm::Mul => memory.write(result, memory.read(left) * memory.read(right)), + Arithm::LessThan => memory.write(result, if memory.read(left) < memory.read(right) { + 1 } else { 0 }), + Arithm::Equals => memory.write(result, if memory.read(left) == memory.read(right) { + 1 } else { 0 }), + } + } + + fn jmp(&mut self, op: Jmp, modes: Vec<ParameterMode>, memory: &mut Memory) + { + let parameter_directions = [DataDirection::Read, DataDirection::Read]; + let params:Vec<usize> = (0..parameter_directions.len()) + .zip(parameter_directions.iter()) + .map(|(p, d)| { + self.param_to_argument(&modes[p], memory, self.r.ip + 1 + p, d) + }).collect(); + let value = params[0]; + let address = params[1]; + + self.r.ip = match op { + Jmp::JmpTrue => (if memory.read(value) != 0 { + memory.read(address) as usize } else { self.r.ip + 3 }), + Jmp::JmpFalse => (if memory.read(value) == 0 { + memory.read(address) as usize } else { self.r.ip + 3 }), + }; + + } + + fn regop(&mut self, op: RegOp, modes: Vec<ParameterMode>, memory: &mut Memory) + { + let parameter_directions = [DataDirection::Read]; + let params:Vec<usize> = (0..parameter_directions.len()) + .zip(parameter_directions.iter()) + .map(|(p, d)| { + self.param_to_argument(&modes[p], memory, self.r.ip + 1 + p, d) + }).collect(); + let value = memory.read(params[0]); + + match op { + RegOp::BaseMod => { + if value < 0 { + self.r.base -= (-1 * value) as usize; + } else { + self.r.base += value as usize; + } + }, + }; + } + + fn io_in(&mut self, _op: IO, modes: Vec<ParameterMode>, memory:&mut Memory) + { + let parameter_directions = [DataDirection::Write]; + let params:Vec<usize> = (0..parameter_directions.len()) + .zip(parameter_directions.iter()) + .map(|(p, d)| { + self.param_to_argument(&modes[p], memory, self.r.ip + 1 + p, d) + }).collect(); + let address = params[0]; + let stdin = io::stdin(); + + match &self.io_method { + IOMethod::StdIO => { + let mut value: Option<BusWidth> = None; + while { + stdin.lock().lines().next().map(|s| { + match s { + Ok(v) => { + let parsed_string = v.trim_end().trim_start().parse::<BusWidth>(); + match parsed_string { + Ok(v) => { value = Some(v); value }, + _ => None, + }; + value + }, + _ => { None }, + } + }); + if value == None { + eprintln!("Could not parse input, please retry."); + true + } else { + false + } + } {} + match value { + Some(v) => memory.write(address, v), + _ => {}, + }; + }, + IOMethod::Variables => { + memory.write(address, self.input.remove(0) as BusWidth); + }, + } + } + + fn io_out(&mut self, _op: IO, modes: Vec<ParameterMode>, memory:&mut Memory ) + { + let parameter_directions = [DataDirection::Read]; + let params:Vec<usize> = (0..parameter_directions.len()) + .zip(parameter_directions.iter()) + .map(|(p, d)| { + self.param_to_argument(&modes[p], memory, self.r.ip + 1 + p, d) + }).collect(); + let address = params[0]; + + let o = memory.read(address); + println!("{}", o); + match &self.io_method { + IOMethod::Variables => self.output.push(o as IOType), + _ => {}, + } + } + + fn intcode(&mut self, mut memory:Memory) + { + while self.r.ip < memory.len() { + let op = memory.read(self.r.ip) % 100; + let modes:Vec<ParameterMode> = (2..=4) + .map(|e| memory.read(self.r.ip) / 10i32.pow(e) as BusWidth % 10) + .map(|n| match n { + 0 => ParameterMode::Position, + 1 => ParameterMode::Immediate, + 2 => ParameterMode::Relative, + p => panic!("Invalid parameter mode {} at IP: {}", p, self.r.ip), + }).collect(); + + match op { + 1 => { self.arithm(Arithm::Add, modes, &mut memory); self.r.ip += 4 }, + 2 => { self.arithm(Arithm::Mul, modes, &mut memory); self.r.ip += 4 }, + 7 => { self.arithm(Arithm::LessThan, modes, &mut memory); self.r.ip += 4 }, + 8 => { self.arithm(Arithm::Equals, modes, &mut memory); self.r.ip += 4 }, + 3 => { self.io_in( IO::In, modes, &mut memory); self.r.ip += 2 }, + 4 => { self.io_out(IO::Out, modes, &mut memory); self.r.ip += 2 }, + 5 => { self.jmp( Jmp::JmpTrue, modes, &mut memory); }, + 6 => { self.jmp( Jmp::JmpFalse, modes, &mut memory); }, + 9 => { self.regop(RegOp::BaseMod, modes, &mut memory); self.r.ip += 2}, + 99 => break, + op => panic!("Invalid operation {} at IP: {}", op, self.r.ip), + } + } + } +} + +fn main() { + let args: Vec<String> = env::args().collect(); + + let mut opts = getopts::Options::new(); + opts.reqopt("m", "mode", "Mode of IO operations", "[arg|stdio]"); + opts.reqopt("p", "program", "File to load program from", "FILE"); + let matches = match opts.parse(&args[1..]) { + Ok(m) => { m } + Err(f) => { panic!(f.to_string()) } + }; + let program:String = matches.opt_str("program").unwrap(); + let mode = matches.opt_str("mode").unwrap(); + let mut memory = Memory::new(); + memory.init(read_program(&program)); + let mut cpu = Intcode::new(); + + if mode == "arg" { + cpu.io_method = IOMethod::Variables; + let input:IOData = matches.free[0].split(",").map(|v| { + let i = v.trim_end().parse().unwrap(); + i + }).collect(); + cpu.input = input; + while cpu.input.len() > 1 { + cpu.intcode(memory.clone()); + } + } else if mode == "stdio" { + cpu.io_method = IOMethod::StdIO; + + cpu.intcode(memory.clone()); + } else { + panic!("Unknown mode: {}", mode); + } +} diff --git a/2019/rust/day09/test_ops.sh b/2019/rust/day09/test_ops.sh new file mode 100755 index 0000000..4e78122 --- /dev/null +++ b/2019/rust/day09/test_ops.sh @@ -0,0 +1,85 @@ +#!/bin/sh -e + +E="../target/debug/day09" + +### https://adventofcode.com/2019/day/2 + +# Opcode 1 adds together numbers read from two positions and stores the result +# in a third position. The three integers immediately after the opcode tell you +# these three positions - the first two indicate the positions from which you +# should read the input values, and the third indicates the position at which +# the output should be stored. + +# Opcode 2 works exactly like opcode 1, except it multiplies the two inputs +# instead of adding them. Again, the three integers after the opcode indicate +# where the inputs and outputs are, not their values. + +### https://adventofcode.com/2019/day/5 + +# Opcode 3 takes a single integer as input and saves it to the position given +# by its only parameter. For example, the instruction 3,50 would take an input +# value and store it at address 50. + +# Opcode 4 outputs the value of its only parameter. For example, the +# instruction 4,50 would output the value at address 50. + +# Each parameter of an instruction is handled based on its parameter mode. +# Right now, your ship computer already understands parameter mode 0, position +# mode, which causes the parameter to be interpreted as a position - if the +# parameter is 50, its value is the value stored at address 50 in memory. Until +# now, all parameters have been in position mode. + +# Now, your ship computer will also need to handle parameters in mode 1, +# immediate mode. In immediate mode, a parameter is interpreted as a value - if +# the parameter is 50, its value is simply 50. + +# Opcode 5 is jump-if-true: if the first parameter is non-zero, it sets the +# instruction pointer to the value from the second parameter. Otherwise, it +# does nothing. + +# Opcode 6 is jump-if-false: if the first parameter is zero, it sets the +# instruction pointer to the value from the second parameter. Otherwise, it +# does nothing. + +# Opcode 7 is less than: if the first parameter is less than the second +# parameter, it stores 1 in the position given by the third parameter. +# Otherwise, it stores 0. + +# Opcode 8 is equals: if the first parameter is equal to the second parameter, +# it stores 1 in the position given by the third parameter. Otherwise, it +# stores 0. + +### https://adventofcode.com/2019/day/9 + +# Opcode 9 adjusts the relative base by the value of its only parameter. The +# relative base increases (or decreases, if the value is negative) by the value +# of the parameter. + +PROGRAMS=${@:-programs/test-*.iac} +for PROGRAM in ${PROGRAMS} +do + echo "Starting ${PROGRAM}" + if [ -e ${PROGRAM%.iac}.in ]; then + INPUT=`cat ${PROGRAM%.iac}.in` + else + INPUT="0" + fi + + if [ -e ${PROGRAM%.iac}.out ]; then + EXPECTED="`cat ${PROGRAM%.iac}.out`" + else + EXPECTED="" + fi + + OUTPUT=`echo "${INPUT}" | RUST_BACKTRACE=1 \ + "${E}" --program "${PROGRAM}" --mode stdio '0' | tee /dev/stderr` + echo "${PROGRAM} finished" + if [ "${EXPECTED}" = "${OUTPUT}" ]; then + echo "Expected output recieved: ${OUTPUT}" + else + echo "Incorrect output!" + echo "Expected |${EXPECTED}| != Actual |${OUTPUT}|" + exit 1 + fi + echo "" +done |