init 2019 day 7 with day 5 source, typo in day 6

This commit is contained in:
2022-09-30 16:28:22 +02:00
parent 8ed39e52b7
commit 626bd1df41
9 changed files with 516 additions and 5 deletions

View File

@@ -46,10 +46,10 @@
* | |---------| |
* +-------------------+---->| child |<---------+-----------------+
* | | |---------| | |
* | | | sibling | | |
* | | +---------+ | |
* | | | |
* | +---------+ | | +---------+ |
* | | +-->| sibling |<--+ | |
* | | | +---------+ | | |
* | | | | | |
* | +---------+ | +-----------------+ | +---------+ |
* | | N1 |<---+-----+ | | N2 | |
* | |---------| | | | |---------| |
* | | parent |----+ | +--| parent | |
@@ -121,7 +121,8 @@ static pool_t *pool_tries, *pool_objects;
static trie_t *trie_get(trie_t *parent, char *name, int pos)
{
trie_t *trie;
static int total = 0;
total ++;
if ((trie = pool_get(pool_tries))) {
for (int i = 0; i < TRIESIZE; ++i)
trie->child[i] = NULL;
@@ -129,6 +130,7 @@ static trie_t *trie_get(trie_t *parent, char *name, int pos)
if (parent)
parent->child[c2index(name[pos])] = trie;
}
printf ("tot=%d\n", total);
return trie;
}
@@ -146,12 +148,15 @@ static trie_t *trie_find(trie_t *root, char *name)
static object_t *object_find(trie_t *root, char *name)
{
trie_t *trie = trie_find(root, name);
static int total = 0;
if (!trie->object) {
total ++;
trie->object = pool_get(pool_objects);
trie->object->parent = NULL;
strcpy(trie->object->name, name);
INIT_LIST_HEAD(&trie->object->child);
INIT_LIST_HEAD(&trie->object->sibling);
printf ("tot2=%d\n", total);
}
return trie->object;
}

1
2019/day07/EXAMPLE.txt Normal file
View File

@@ -0,0 +1 @@
3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0

1
2019/day07/EXAMPLE1.txt Normal file
View File

@@ -0,0 +1 @@
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

1
2019/day07/EXAMPLE2.txt Normal file
View File

@@ -0,0 +1 @@
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

1
2019/day07/INPUT.txt Normal file
View File

@@ -0,0 +1 @@
3,225,1,225,6,6,1100,1,238,225,104,0,1101,86,8,225,1101,82,69,225,101,36,65,224,1001,224,-106,224,4,224,1002,223,8,223,1001,224,5,224,1,223,224,223,102,52,148,224,101,-1144,224,224,4,224,1002,223,8,223,101,1,224,224,1,224,223,223,1102,70,45,225,1002,143,48,224,1001,224,-1344,224,4,224,102,8,223,223,101,7,224,224,1,223,224,223,1101,69,75,225,1001,18,85,224,1001,224,-154,224,4,224,102,8,223,223,101,2,224,224,1,224,223,223,1101,15,59,225,1102,67,42,224,101,-2814,224,224,4,224,1002,223,8,223,101,3,224,224,1,223,224,223,1101,28,63,225,1101,45,22,225,1101,90,16,225,2,152,92,224,1001,224,-1200,224,4,224,102,8,223,223,101,7,224,224,1,223,224,223,1101,45,28,224,1001,224,-73,224,4,224,1002,223,8,223,101,7,224,224,1,224,223,223,1,14,118,224,101,-67,224,224,4,224,1002,223,8,223,1001,224,2,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,7,677,677,224,102,2,223,223,1005,224,329,1001,223,1,223,1008,226,226,224,1002,223,2,223,1005,224,344,1001,223,1,223,1107,677,226,224,1002,223,2,223,1006,224,359,1001,223,1,223,107,677,677,224,102,2,223,223,1005,224,374,101,1,223,223,1108,677,226,224,102,2,223,223,1005,224,389,1001,223,1,223,1007,677,677,224,1002,223,2,223,1005,224,404,101,1,223,223,1008,677,226,224,102,2,223,223,1005,224,419,101,1,223,223,1108,226,677,224,102,2,223,223,1006,224,434,1001,223,1,223,8,677,226,224,1002,223,2,223,1005,224,449,101,1,223,223,1008,677,677,224,1002,223,2,223,1006,224,464,1001,223,1,223,1108,226,226,224,1002,223,2,223,1005,224,479,1001,223,1,223,1007,226,677,224,102,2,223,223,1005,224,494,1001,223,1,223,1007,226,226,224,102,2,223,223,1005,224,509,101,1,223,223,107,677,226,224,1002,223,2,223,1006,224,524,1001,223,1,223,108,677,677,224,102,2,223,223,1006,224,539,101,1,223,223,7,677,226,224,102,2,223,223,1006,224,554,1001,223,1,223,1107,226,677,224,102,2,223,223,1005,224,569,101,1,223,223,108,677,226,224,1002,223,2,223,1006,224,584,101,1,223,223,108,226,226,224,102,2,223,223,1006,224,599,1001,223,1,223,1107,226,226,224,102,2,223,223,1006,224,614,1001,223,1,223,8,226,677,224,102,2,223,223,1006,224,629,1001,223,1,223,107,226,226,224,102,2,223,223,1005,224,644,101,1,223,223,8,226,226,224,102,2,223,223,1006,224,659,101,1,223,223,7,226,677,224,102,2,223,223,1005,224,674,101,1,223,223,4,223,99,226

93
2019/day07/Makefile Normal file
View File

@@ -0,0 +1,93 @@
# AOC daily Makefile - GNU make only.
#
# Copyright (C) 2021 Bruno Raoult ("br")
# Licensed under the GNU General Public License v3.0 or later.
# Some rights reserved. See COPYING.
#
# You should have received a copy of the GNU General Public License along with this
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
#
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
#
INPUT := INPUT.txt
SHELL := /bin/bash
CC := gcc
LIB := aoc_$(shell uname -m)
INCDIR := ../include
LIBDIR := ../lib
LDFLAGS := -L$(LIBDIR)
#LDLIB := -l$(LIB) -lm
LDLIB := -l$(LIB)
export LD_LIBRARY_PATH = $(LIBDIR)
CFLAGS += -std=gnu11
CFLAGS += -O2
CFLAGS += -g
# for gprof
#CFLAGS += -pg
CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -march=native
# Next one may be useful for valgrind (some invalid instructions)
# CFLAGS += -mno-tbm
CFLAGS += -Wmissing-declarations
CFLAGS += -Wno-unused-result
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
CFLAGS += -DDEBUG_POOL # memory pools management
VALGRIND := valgrind
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
--sigill-diagnostics=yes --quiet --show-error-list=yes
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
export PATH := .:$(PATH)
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 ex1 ex2
all: README.org ex1 ex2
memcheck: memcheck1 memcheck2
memcheck1: aoc-c
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
memcheck2: aoc-c
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
compile: aoc-c
assembly: aoc-c.s
ex1: aoc-c
@$(TIME) aoc-c -p 1 < $(INPUT)
ex2: aoc-c
@$(TIME) aoc-c -p 2 < $(INPUT)
clean:
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html
.c:
@echo compiling $<
@$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $< $(LDLIB) -o $@
# generate pre-processed file (.i) and assembler (.s)
%.i: %.c
@echo generating $@
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
%.s: %.c
@echo generating $@
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
# generate README.org from README.html (must cleanup !)
%.org: %.html
@echo generating $@. Cleanup before commit !
@pandoc $< -o $@

145
2019/day07/README.html Normal file
View File

@@ -0,0 +1,145 @@
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8"/>
<title>Day 7 - Advent of Code 2019</title>
<!--[if lt IE 9]><script src="/static/html5.js"></script><![endif]-->
<link href='//fonts.googleapis.com/css?family=Source+Code+Pro:300&subset=latin,latin-ext' rel='stylesheet' type='text/css'/>
<link rel="stylesheet" type="text/css" href="/static/style.css?28"/>
<link rel="stylesheet alternate" type="text/css" href="/static/highcontrast.css?0" title="High Contrast"/>
<link rel="shortcut icon" href="/favicon.png"/>
<script>window.addEventListener('click', function(e,s,r){if(e.target.nodeName==='CODE'&&e.detail===3){s=window.getSelection();s.removeAllRanges();r=document.createRange();r.selectNodeContents(e.target);s.addRange(r);}});</script>
</head><!--
Oh, hello! Funny seeing you here.
I appreciate your enthusiasm, but you aren't going to find much down here.
There certainly aren't clues to any of the puzzles. The best surprises don't
even appear in the source until you unlock them for real.
Please be careful with automated requests; I'm not a massive company, and I can
only take so much traffic. Please be considerate so that everyone gets to play.
If you're curious about how Advent of Code works, it's running on some custom
Perl code. Other than a few integrations (auth, analytics, social media), I
built the whole thing myself, including the design, animations, prose, and all
of the puzzles.
The puzzles are most of the work; preparing a new calendar and a new set of
puzzles each year takes all of my free time for 4-5 months. A lot of effort
went into building this thing - I hope you're enjoying playing it as much as I
enjoyed making it for you!
If you'd like to hang out, I'm @ericwastl on Twitter.
- Eric Wastl
-->
<body>
<header><div><h1 class="title-global"><a href="/">Advent of Code</a></h1><nav><ul><li><a href="/2019/about">[About]</a></li><li><a href="/2019/events">[Events]</a></li><li><a href="https://teespring.com/stores/advent-of-code" target="_blank">[Shop]</a></li><li><a href="/2019/settings">[Settings]</a></li><li><a href="/2019/auth/logout">[Log Out]</a></li></ul></nav><div class="user">Bruno Raoult <span class="star-count">12*</span></div></div><div><h1 class="title-event">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="title-event-wrap">/^</span><a href="/2019">2019</a><span class="title-event-wrap">$/</span></h1><nav><ul><li><a href="/2019">[Calendar]</a></li><li><a href="/2019/support">[AoC++]</a></li><li><a href="/2019/sponsors">[Sponsors]</a></li><li><a href="/2019/leaderboard">[Leaderboard]</a></li><li><a href="/2019/stats">[Stats]</a></li></ul></nav></div></header>
<div id="sidebar">
<div id="sponsor"><div class="quiet">Our <a href="/2019/sponsors">sponsors</a> help make Advent of Code possible:</div><div class="sponsor"><a href="https://smartystreets.com/aoc" target="_blank" onclick="if(ga)ga('send','event','sponsor','sidebar',this.href);" rel="noopener">SmartyStreets</a> - Ridiculously -- Fast -------- Address ------ Verification --</div></div>
</div><!--/sidebar-->
<main>
<article class="day-desc"><h2>--- Day 7: Amplification Circuit ---</h2><p>Based on the navigational maps, you're going to need to send more power to your ship's thrusters to reach Santa in time. To do this, you'll need to configure a series of <a href="https://en.wikipedia.org/wiki/Amplifier">amplifiers</a> already installed on the ship.</p>
<p>There are five <span title="As you can see, I know exactly how rockets work.">amplifiers connected in series</span>; each one receives an input signal and produces an output signal. They are connected such that the first amplifier's output leads to the second amplifier's input, the second amplifier's output leads to the third amplifier's input, and so on. The first amplifier's input value is <code>0</code>, and the last amplifier's output leads to your ship's thrusters.</p>
<pre><code> O-------O O-------O O-------O O-------O O-------O
0 -&gt;| Amp A |-&gt;| Amp B |-&gt;| Amp C |-&gt;| Amp D |-&gt;| Amp E |-&gt; (to thrusters)
O-------O O-------O O-------O O-------O O-------O
</code></pre>
<p>The Elves have sent you some <em>Amplifier Controller Software</em> (your puzzle input), a program that should run on your <a href="5">existing Intcode computer</a>. Each amplifier will need to run a copy of the program.</p>
<p>When a copy of the program starts running on an amplifier, it will first use an input instruction to ask the amplifier for its current <em>phase setting</em> (an integer from <code>0</code> to <code>4</code>). Each phase setting is used <em>exactly once</em>, but the Elves can't remember which amplifier needs which phase setting.</p>
<p>The program will then call another input instruction to get the amplifier's input signal, compute the correct output signal, and supply it back to the amplifier with an output instruction. (If the amplifier has not yet received an input signal, it waits until one arrives.)</p>
<p>Your job is to <em>find the largest output signal that can be sent to the thrusters</em> by trying every possible combination of phase settings on the amplifiers. Make sure that memory is not shared or reused between copies of the program.</p>
<p>For example, suppose you want to try the phase setting sequence <code>3,1,2,4,0</code>, which would mean setting amplifier <code>A</code> to phase setting <code>3</code>, amplifier <code>B</code> to setting <code>1</code>, <code>C</code> to <code>2</code>, <code>D</code> to <code>4</code>, and <code>E</code> to <code>0</code>. Then, you could determine the output signal that gets sent from amplifier <code>E</code> to the thrusters with the following steps:</p>
<ul>
<li>Start the copy of the amplifier controller software that will run on amplifier <code>A</code>. At its first input instruction, provide it the amplifier's phase setting, <code>3</code>. At its second input instruction, provide it the input signal, <code>0</code>. After some calculations, it will use an output instruction to indicate the amplifier's output signal.</li>
<li>Start the software for amplifier <code>B</code>. Provide it the phase setting (<code>1</code>) and then whatever output signal was produced from amplifier <code>A</code>. It will then produce a new output signal destined for amplifier <code>C</code>.</li>
<li>Start the software for amplifier <code>C</code>, provide the phase setting (<code>2</code>) and the value from amplifier <code>B</code>, then collect its output signal.</li>
<li>Run amplifier <code>D</code>'s software, provide the phase setting (<code>4</code>) and input value, and collect its output signal.</li>
<li>Run amplifier <code>E</code>'s software, provide the phase setting (<code>0</code>) and input value, and collect its output signal.</li>
</ul>
<p>The final output signal from amplifier <code>E</code> would be sent to the thrusters. However, this phase setting sequence may not have been the best one; another sequence might have sent a higher signal to the thrusters.</p>
<p>Here are some example programs:</p>
<ul>
<li><p>Max thruster signal <em><code>43210</code></em> (from phase setting sequence <code>4,3,2,1,0</code>):</p><pre><code>3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0</code></pre></li>
<li><p>Max thruster signal <em><code>54321</code></em> (from phase setting sequence <code>0,1,2,3,4</code>):</p><pre><code>3,23,3,24,1002,24,10,24,1002,23,-1,23,<br/>101,5,23,23,1,24,23,23,4,23,99,0,0</code></pre></li>
<li><p>Max thruster signal <em><code>65210</code></em> (from phase setting sequence <code>1,0,4,3,2</code>):</p><pre><code>3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,<br/>1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0</code></pre></li>
</ul>
<p>Try every combination of phase settings on the amplifiers. <em>What is the highest signal that can be sent to the thrusters?</em></p>
</article>
<p>To begin, <a href="7/input" target="_blank">get your puzzle input</a>.</p>
<form method="post" action="7/answer"><input type="hidden" name="level" value="1"/><p>Answer: <input type="text" name="answer" autocomplete="off"/> <input type="submit" value="[Submit]"/></p></form>
<p>You can also <span class="share">[Share<span class="share-content">on
<a href="https://twitter.com/intent/tweet?text=%22Amplification+Circuit%22+%2D+Day+7+%2D+Advent+of+Code+2019&amp;url=https%3A%2F%2Fadventofcode%2Ecom%2F2019%2Fday%2F7&amp;related=ericwastl&amp;hashtags=AdventOfCode" target="_blank">Twitter</a>
<a href="javascript:void(0);" onclick="var mastodon_instance=prompt('Mastodon Instance / Server Name?'); if(typeof mastodon_instance==='string' && mastodon_instance.length){this.href='https://'+mastodon_instance+'/share?text=%22Amplification+Circuit%22+%2D+Day+7+%2D+Advent+of+Code+2019+%23AdventOfCode+https%3A%2F%2Fadventofcode%2Ecom%2F2019%2Fday%2F7'}else{return false;}" target="_blank">Mastodon</a
></span>]</span> this puzzle.</p>
</main>
<!-- ga -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-69522494-1', 'auto');
ga('set', 'anonymizeIp', true);
ga('send', 'pageview');
</script>
<!-- /ga -->
</body>
</html>

102
2019/day07/README.org Normal file
View File

@@ -0,0 +1,102 @@
** --- Day 7: Amplification Circuit ---
Based on the navigational maps, you're going to need to send more power
to your ship's thrusters to reach Santa in time. To do this, you'll need
to configure a series of
[[https://en.wikipedia.org/wiki/Amplifier][amplifiers]] already
installed on the ship.
There are five amplifiers connected in series; each one receives an
input signal and produces an output signal. They are connected such that
the first amplifier's output leads to the second amplifier's input, the
second amplifier's output leads to the third amplifier's input, and so
on. The first amplifier's input value is =0=, and the last amplifier's
output leads to your ship's thrusters.
#+BEGIN_EXAMPLE
O-------O O-------O O-------O O-------O O-------O
0 ->| Amp A |->| Amp B |->| Amp C |->| Amp D |->| Amp E |-> (to thrusters)
O-------O O-------O O-------O O-------O O-------O
#+END_EXAMPLE
The Elves have sent you some /Amplifier Controller Software/ (your
puzzle input), a program that should run on your [[file:5][existing
Intcode computer]]. Each amplifier will need to run a copy of the
program.
When a copy of the program starts running on an amplifier, it will first
use an input instruction to ask the amplifier for its current /phase
setting/ (an integer from =0= to =4=). Each phase setting is used
/exactly once/, but the Elves can't remember which amplifier needs which
phase setting.
The program will then call another input instruction to get the
amplifier's input signal, compute the correct output signal, and supply
it back to the amplifier with an output instruction. (If the amplifier
has not yet received an input signal, it waits until one arrives.)
Your job is to /find the largest output signal that can be sent to the
thrusters/ by trying every possible combination of phase settings on the
amplifiers. Make sure that memory is not shared or reused between copies
of the program.
For example, suppose you want to try the phase setting sequence
=3,1,2,4,0=, which would mean setting amplifier =A= to phase setting
=3=, amplifier =B= to setting =1=, =C= to =2=, =D= to =4=, and =E= to
=0=. Then, you could determine the output signal that gets sent from
amplifier =E= to the thrusters with the following steps:
- Start the copy of the amplifier controller software that will run on
amplifier =A=. At its first input instruction, provide it the
amplifier's phase setting, =3=. At its second input instruction,
provide it the input signal, =0=. After some calculations, it will use
an output instruction to indicate the amplifier's output signal.
- Start the software for amplifier =B=. Provide it the phase setting
(=1=) and then whatever output signal was produced from amplifier =A=.
It will then produce a new output signal destined for amplifier =C=.
- Start the software for amplifier =C=, provide the phase setting (=2=)
and the value from amplifier =B=, then collect its output signal.
- Run amplifier =D='s software, provide the phase setting (=4=) and
input value, and collect its output signal.
- Run amplifier =E='s software, provide the phase setting (=0=) and
input value, and collect its output signal.
The final output signal from amplifier =E= would be sent to the
thrusters. However, this phase setting sequence may not have been the
best one; another sequence might have sent a higher signal to the
thrusters.
Here are some example programs:
- Max thruster signal /=43210=/ (from phase setting sequence
=4,3,2,1,0=):
#+BEGIN_EXAMPLE
3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0
#+END_EXAMPLE
- Max thruster signal /=54321=/ (from phase setting sequence
=0,1,2,3,4=):
#+BEGIN_EXAMPLE
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
#+END_EXAMPLE
- Max thruster signal /=65210=/ (from phase setting sequence
=1,0,4,3,2=):
#+BEGIN_EXAMPLE
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
#+END_EXAMPLE
Try every combination of phase settings on the amplifiers. /What is the
highest signal that can be sent to the thrusters?/
To begin, [[file:7/input][get your puzzle input]].
Answer:
You can also [Shareon
[[https://twitter.com/intent/tweet?text=%22Amplification+Circuit%22+%2D+Day+7+%2D+Advent+of+Code+2019&url=https%3A%2F%2Fadventofcode%2Ecom%2F2019%2Fday%2F7&related=ericwastl&hashtags=AdventOfCode][Twitter]]
[[javascript:void(0);][Mastodon]]] this puzzle.

162
2019/day07/aoc-c.c Normal file
View File

@@ -0,0 +1,162 @@
/* aoc-c.c: Advent of Code 2019, day 7 parts 1 & 2
*
* Copyright (C) 2021 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "br.h"
#include "bits.h"
#include "debug.h"
typedef enum {
ADD = 1, MUL = 2,
INP = 3, OUT = 4,
JMP_T = 5, JMP_F = 6,
SET_LT = 7, SET_EQ = 8,
HLT = 99
} opcode_t;
/**
* ops - array of op-codes, mnemo, and number of parameters
* @op: An integer, the opcode
* @nargs: Opcode number of parameters (unused)
* @jump: Next instruction (usually @nargs + 1)
* @mnemo: Opcode mnemo (unused, for debug)
*/
typedef struct {
int op;
u8 nargs;
u8 jump;
char *mnemo;
} ops_t;
#define MAXOPS 1024
typedef struct {
int length; /* total program length */
int cur; /* current position */
int mem [MAXOPS]; /* should really be dynamic */
} program_t;
static ops_t ops[] = {
[ADD] = { ADD, 3, 4, __stringify(ADD) },
[MUL] = { MUL, 3, 4, __stringify(MUL) },
[INP] = { INP, 1, 2, __stringify(INP) },
[OUT] = { OUT, 1, 2, __stringify(OUT) },
[JMP_T] = { JMP_T, 2, 3, __stringify(JMP_T) },
[JMP_F] = { JMP_F, 2, 3, __stringify(JMP_F) },
[SET_LT] = { SET_LT, 3, 4, __stringify(SET_LT) },
[SET_EQ] = { SET_EQ, 3, 4, __stringify(SET_EQ) },
[HLT] = { HLT, 0, 1, __stringify(HLT) }
};
static int _flag_pow10[] = {1, 100, 1000, 10000};
#define OP(p, n) ((p->mem[n]) % 100)
#define ISDIRECT(p, n, i) ((((p->mem[n]) / _flag_pow10[i]) % 10))
#define DIRECT(p, i) ((p)->mem[i])
#define INDIRECT(p, i) (DIRECT(p, DIRECT(p, i)))
#define peek(p, n, i) (ISDIRECT(p, n, i)? DIRECT(p, n + i): INDIRECT(p, n + i))
#define poke(p, n, i, val) do { \
INDIRECT(p, n + i) = val; } \
while (0)
static int run(program_t *p, int in)
{
int out = -1;
while (1) {
int op = OP(p, p->cur), cur = p->cur;
if (!(ops[op].op)) {
fprintf(stderr, "PANIC: illegal instruction %d at %d.\n", op, p->cur);
return -1;
}
switch (op) {
case ADD:
poke(p, p->cur, 3, peek(p, p->cur, 1) + peek(p, p->cur, 2));
break;
case MUL:
poke(p, p->cur, 3, peek(p, p->cur, 1) * peek(p, p->cur, 2));
break;
case INP:
poke(p, p->cur, 1, in);
break;
case OUT:
out = peek(p, p->cur, 1);
break;
case JMP_T:
if (peek(p, p->cur, 1))
p->cur = peek(p, p->cur, 2);
break;
case JMP_F:
if (!peek(p, p->cur, 1))
p->cur = peek(p, p->cur, 2);
break;
case SET_LT:
poke(p, p->cur, 3, peek(p, p->cur, 1) < peek(p, p->cur, 2) ? 1: 0);
break;
case SET_EQ:
poke(p, p->cur, 3, peek(p, p->cur, 1) == peek(p, p->cur, 2) ? 1: 0);
break;
case HLT:
return out;
}
if (p->cur == cur)
p->cur += ops[op].jump;
}
}
static void parse(program_t *prog)
{
while (scanf("%d%*c", &prog->mem[prog->length++]) > 0)
;
}
static int usage(char *prg)
{
fprintf(stderr, "Usage: %s [-d debug_level] [-p part] [-i input]\n", prg);
return 1;
}
int main(int ac, char **av)
{
int opt, part = 1, in = -1;
program_t p = { 0 };
while ((opt = getopt(ac, av, "d:p:i:")) != -1) {
switch (opt) {
case 'd':
debug_level_set(atoi(optarg));
break;
case 'i':
in = atoi(optarg);
break;
case 'p': /* 1 or 2 */
part = atoi(optarg);
if (part < 1 || part > 2)
return usage(*av);
break;
default:
return usage(*av);
}
}
if (optind < ac)
return usage(*av);
if (in == -1)
in = part == 1? 1: 5;
parse(&p);
printf("%s : res=%d\n", *av, run(&p, in));
exit (0);
}