[-] pngwen 2 points 9 months ago

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))
[-] pngwen 2 points 9 months ago* (last edited 9 months ago)

C++

Yesterday, I decided to code in Tcl. That program is still running, i will go back to the day 5 post once it finishes :)

Today was super simple. My first attempt worked in both cases, where the hardest part was really switching my ints to long longs. Part 1 worked on first compile and part 2 I had to compile twice after I realized the data type needs. Still, that change was made by search and replace.

I guess today was meant to be a real time race to get first answer? This is like day 1 stuff! Still, I have kids and a job so I did not get to stay up until the problem was posted.

I used C++ because I thought something intense may be coming on the part 2 problem, and I was burned yesterday. It looks like I spent another fast language on nothing! I think I'll keep zig in the hole for the next number cruncher.

Oh, and yes my TCL program is still running...

My solutions can be found here:

// File: day-6a.cpp
// Purpose: Solution to part of day 6 of advent of code in C++
//          https://adventofcode.com/2023/day/6
// Author: Robert Lowe
// Date: 6 December 2023
#include <iostream>
#include <vector>
#include <string>
#include <sstream>

std::vector<int> parse_line()
{
    std::string line;
    std::size_t index;
    int num;
    std::vector<int> result;
    
    // set up the stream
    std::getline(std::cin, line);
    index = line.find(':');
    std::istringstream is(line.substr(index+1));

    while(is>>num) {
        result.push_back(num);
    }

    return result;
}

int count_wins(int t, int d) 
{
    int count=0;
    for(int i=1; i<t; i++) {
        if(t*i-i*i > d) {
            count++;
        }
    }
    return count;
}

int main()
{
    std::vector<int> time;
    std::vector<int> dist;
    int product=1;

    // get the times and distances
    time = parse_line();
    dist = parse_line();

    // count the total number of wins
    for(auto titr=time.begin(), ditr=dist.begin(); titr!=time.end(); titr++, ditr++) {
        product *= count_wins(*titr, *ditr);
    }

    std::cout << product << std::endl;
}
// File: day-6b.cpp
// Purpose: Solution to part 2 of day 6 of advent of code in C++
//          https://adventofcode.com/2023/day/6
// Author: Robert Lowe
// Date: 6 December 2023
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <cctype>

std::vector<long long> parse_line()
{
    std::string line;
    std::size_t index;
    long long num;
    std::vector<long long> result;
    
    // set up the stream
    std::getline(std::cin, line);
    line.erase(std::remove_if(line.begin(), line.end(), isspace), line.end());
    index = line.find(':');
    std::istringstream is(line.substr(index+1));

    while(is>>num) {
        result.push_back(num);
    }

    return result;
}

long long count_wins(long long t, long long d) 
{
    long long count=0;
    for(long long i=1; i<t; i++) {
        if(t*i-i*i > d) {
            count++;
        }
    }
    return count;
}

int main()
{
    std::vector<long long> time;
    std::vector<long long> dist;
    long long product=1;

    // get the times and distances
    time = parse_line();
    dist = parse_line();

    // count the total number of wins
    for(auto titr=time.begin(), ditr=dist.begin(); titr!=time.end(); titr++, ditr++) {
        product *= count_wins(*titr, *ditr);
    }

    std::cout << product << std::endl;
}
[-] pngwen 2 points 9 months ago

That's some elegant code! Then again, I suppose that's the beauty of nim.

[-] pngwen 2 points 9 months ago* (last edited 9 months ago)

PHP

Today was the easiest day so far IMHO. Today, I coded in PHP, a horrible language that produces even worse code. (Ok, full confession, I fed my family for about half a decade on PHP. I seemed to have gotten stuck with it, and so I earned a PhD to escape it.)

Anyway, the only trouble I had was I forgot about the explode function's capacity to return empty strings. Once I filtered those I had the correct answer on the first one, and then 10 minutes later I had the second part. I wrote my code true to raw php's awful idioms, though I didn't make it web based. I read from stdin.

My code is linked on github:

[-] pngwen 5 points 9 months ago* (last edited 9 months ago)

I wrote today's program in Python. (I am going to do a different language each day.) The only thing that gave me a little trouble was I was counting "\n" as a part label. Once I realized that I was able to get both problems done very quickly.

My code for the two parts is on github:-

[-] pngwen 2 points 1 year ago* (last edited 1 year ago)

Honestly, I had never heard of neovim until I read your post. I think I will take it for a spinas lua extensibility appeals to me quite a bit. Thank you for mentioning it!

pngwen

joined 1 year ago