Day 9: Mirage Maintenance
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- Code block support is not fully rolled out yet but likely will be in the middle of the event. Try to share solutions as both code blocks and using something such as https://topaz.github.io/paste/ , pastebin, or github (code blocks to future proof it for when 0.19 comes out and since code blocks currently function in some apps and some instances as well if they are running a 0.19 beta)
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
🔒 Thread is locked until there’s at least 100 2 star entries on the global leaderboard
🔓 Unlocked after 5 mins
Algol 68
So this felt like an old-school programming challenge. Like the type of thing you’d give to a CS student back in the good old days. So I decided to code in the granddaddy of modern languages. I did this in Algol-68!
In fact, Algol 68’s event driven input handler was quite nice for this task as was its easy ability to detect the ends of lines. of course, its lack of built-in data structures meant that I had to whip up my own dynamic array, but that’s pretty easy too. If you read today’s code, you’ll see familiar threads that influenced C and most of the languages that followed it.
Algol 68 is meant to be a language for publication. It is really tough to write a compiler for this language, but it is easy to write self-documenting code. In fact, a lot of textbooks publish algorithms in pseudocode that is almost correct Algol 68 code! So I tried to write today’s solutions with readability in mind. Of course, this venerable language is not without its flaws, but I do enjoy coding in it from time to time.
https://github.com/pngwen/advent-2023/blob/main/day-9a.a68
COMMENT File: day-9a.a68 Purpose: Solution to the first problem of day 9 of the advent of code written in the venerable Algol 68 Programming language. https://adventofcode.com/2023/day/9 Date: 9 December 2023 COMMENT #--------------------------------------------------------------------# # Array List Definition # #--------------------------------------------------------------------# # A handy data structure to manage dynamic growth # MODE ARRAYLIST = STRUCT (FLEX [0] INT data, INT capacity, INT size); # Create an array list with an initial capacity of 128 integers. # PROC init array list = (REF ARRAYLIST list) VOID: BEGIN [128] INT data; data OF list := data; capacity OF list := 128; size OF list := 0 END; # Double the capacity of the list. # PROC grow array list = (REF ARRAYLIST list) VOID: BEGIN INT ubound := 1 UPB data OF list; INT capacity := ubound *2; [capacity] INT new; FOR i FROM 1 TO ubound DO new[i] := (data OF list)[i] OD; data OF list := new; capacity OF list := capacity END; # Add an item to the end of the array list # PROC append to array list = (REF ARRAYLIST list, INT item) VOID: BEGIN size OF list +:= 1; IF size OF list > capacity OF list THEN grow array list(list) FI; (data OF list)[size OF list] := item END; # Print an array list. # PROC print array list = (REF ARRAYLIST list) VOID: BEGIN FOR i FROM 1 TO size OF list DO print ((data OF list)[i]) OD; print(new line) END; #--------------------------------------------------------------------# # Set up the Input Handlers # BOOL is eof := FALSE; on logical file end(stand in, (REF FILE f) BOOL: ( is eof := TRUE; TRUE )); # Read a line of integers to get the array list # PROC read history = ARRAYLIST: BEGIN ARRAYLIST result; INT num; init array list(result); DO get(stand in, num); IF NOT is eof THEN append to array list(result, num) FI UNTIL end of line(stand in) OR is eof OD; result END; # compute the first differential of the list # PROC differentiate = (ARRAYLIST list) ARRAYLIST: BEGIN ARRAYLIST result; init array list(result); FOR i FROM 1 TO size OF list - 1 DO append to array list(result, (data OF list)[i+1]-(data OF list)[i]) OD; result END; # Extrapolate the next value # PROC extrapolate = (ARRAYLIST list) INT: BEGIN INT result; IF size OF list = 0 THEN result := 0 ELIF size OF list = 1 THEN result := (data OF list)[1] ELSE result := extrapolate(differentiate(list)) + (data OF list)[size OF list] FI; result END; ARRAYLIST line; INT sum := 0; WHILE NOT is eof DO line := read history; IF size OF line /= 0 THEN sum +:= extrapolate(line) FI UNTIL is eof OD; print((sum, new line))
https://github.com/pngwen/advent-2023/blob/main/day-9b.a68
COMMENT File: day-9b.a68 Purpose: Solution to the second problem of day 9 of the advent of code written in the venerable Algol 68 Programming language. https://adventofcode.com/2023/day/9 Date: 9 December 2023 COMMENT #--------------------------------------------------------------------# # Array List Definition # #--------------------------------------------------------------------# # A handy data structure to manage dynamic growth # MODE ARRAYLIST = STRUCT (FLEX [0] INT data, INT capacity, INT size); # Create an array list with an initial capacity of 128 integers. # PROC init array list = (REF ARRAYLIST list) VOID: BEGIN [128] INT data; data OF list := data; capacity OF list := 128; size OF list := 0 END; # Double the capacity of the list. # PROC grow array list = (REF ARRAYLIST list) VOID: BEGIN INT ubound := 1 UPB data OF list; INT capacity := ubound *2; [capacity] INT new; FOR i FROM 1 TO ubound DO new[i] := (data OF list)[i] OD; data OF list := new; capacity OF list := capacity END; # Add an item to the end of the array list # PROC append to array list = (REF ARRAYLIST list, INT item) VOID: BEGIN size OF list +:= 1; IF size OF list > capacity OF list THEN grow array list(list) FI; (data OF list)[size OF list] := item END; # Print an array list. # PROC print array list = (REF ARRAYLIST list) VOID: BEGIN FOR i FROM 1 TO size OF list DO print ((data OF list)[i]) OD; print(new line) END; #--------------------------------------------------------------------# # Set up the Input Handlers # BOOL is eof := FALSE; on logical file end(stand in, (REF FILE f) BOOL: ( is eof := TRUE; TRUE )); # Read a line of integers to get the array list # PROC read history = ARRAYLIST: BEGIN ARRAYLIST result; INT num; init array list(result); DO get(stand in, num); IF NOT is eof THEN append to array list(result, num) FI UNTIL end of line(stand in) OR is eof OD; result END; # compute the first differential of the list # PROC differentiate = (ARRAYLIST list) ARRAYLIST: BEGIN ARRAYLIST result; init array list(result); FOR i FROM 1 TO size OF list - 1 DO append to array list(result, (data OF list)[i+1]-(data OF list)[i]) OD; result END; # Extrapolate the next value # PROC extrapolate = (ARRAYLIST list) INT: BEGIN INT result; IF size OF list = 0 THEN result := 0 ELIF size OF list = 1 THEN result := (data OF list)[1] ELSE result := (data OF list)[1] - extrapolate(differentiate(list)) FI; result END; ARRAYLIST line; INT sum := 0; WHILE NOT is eof DO line := read history; IF size OF line /= 0 THEN sum +:= extrapolate(line) FI UNTIL is eof OD; print((sum, new line))