10 C
Without further ado let’s get started.
Part I Assignment
#include <stdio.h> // needed for fgets below
#include <stdlib.h> // needed for atoi below
// update sum of signals
int upd_sum(int cycle, int sum, int reg) {
// update only for some cycles
switch (cycle) {
case 20:
case 60:
case 100:
case 140:
case 180:
case 220:
return sum + cycle*reg;
default:
break;
}
return sum;
}
// main function which is run when executed
int main() {
const int MAXL = 100; // max line length, auxiliary variable
FILE* fp; // file descriptor
char line[MAXL]; // line string
int sum = 0; // cummulative signal at selected cycles
int signal = 0; // signal from the instruction
int reg = 1; // register value
int cycle = 0; // clock
// open file but do not check if it fails
fp = fopen("10.input", "r");
// read input file until the EOF (end of file)
while ((fgets(line, MAXL, fp)) != NULL) {
// noop instruction, do nothing
if (line[0] == 'n') {
cycle += 1;
sum = upd_sum(cycle, sum, reg);
}
// addx instruction, 2 cycles
else {
signal = atoi(&line[5]); // convert from position 5 to int
cycle += 1;
sum = upd_sum(cycle, sum, reg);
cycle += 1;
sum = upd_sum(cycle, sum, reg);
reg += signal;
}
}
printf("Sum of signals %d\n", sum);
fclose(fp); // better close the file
return 0; // we are fine!
}
Part II
#include <stdio.h>
#include <stdlib.h>
const int MAXL = 100;
const int CRTW = 40; // width of CRT
// init CRT screen line with '.'
void init_crt(char *crt_row) {
for (int i=0; i<CRTW; i++) {
crt_row[i] = '.';
}
// end of the string
crt_row[CRTW] = '\0';
}
// draw pixel if sprint is at the right position
void draw_px(int cycle, int sprite, char *crt_row) {
// get the right position from the cycle
int c = (cycle-1) % CRTW;
if (c == sprite || c+1 == sprite || c-1 == sprite) {
crt_row[c] = '#';
}
}
void upd_crt(int cycle, int sprite, char *crt_row) {
switch (cycle) {
// now the cycles are shifted
case 40:
case 80:
case 120:
case 160:
case 200:
case 240:
draw_px(cycle, sprite, crt_row);
// print CRT screen line
printf("%s\n", crt_row);
init_crt(crt_row);
break;
default:
draw_px(cycle, sprite, crt_row);
break;
}
}
int main() {
FILE* fp;
char line[MAXL];
int sprite = 1; // position of sprint on CRT
int cycle = 0; // cycle number
char crt_row[CRTW+1]; // CRT screen line
fp = fopen("10.input", "r");
init_crt(crt_row); // initialize with
while ((fgets(line, MAXL, fp)) != NULL) {
if (line[0] == 'n') {
cycle += 1;
upd_crt(cycle, sprite, crt_row);
}
else {
cycle += 1;
upd_crt(cycle, sprite, crt_row);
cycle += 1;
upd_crt(cycle, sprite, crt_row);
sprite += atoi(&line[5]);
}
}
fclose(fp);
return 0;
What I learned
- What is sprite.
I actually started with Assembly. Ahem…
Assembly
The general-purpose x86 assembler is installed with
$ sudo apt install nasm
on Ubuntu.
Once the assembly code is written, it must be compiled and linked to an executable. On Linux, the process is this:
nasm -f elf 10.asm # compiles
ld -m elf_i386 -s -o hello 10.o # links into hello executable
./hello # runs
According to the nasm help,
elf
is for ELF32 (i386) format.
(Source)
Part I Assignment
global start
section .text
start:
mov sum, 10
section .data
fn: db "10.input"
sum: dq 0
Part II
What I learned
- An assembly program is divided into three sections: data, bss and text for declaring constants, variables and the code itself, respectively.
- Three types of statements
- executable instructions
- opeartion code (opcode)
- assembler directives (pseudo-ops)
- macros
- executable instructions
published: 2022-12-10
last modified: 2023-01-21
https://vit.baisa.cz/notes/code/advent-of-code-2022/10/
last modified: 2023-01-21
https://vit.baisa.cz/notes/code/advent-of-code-2022/10/