I am a professor of computer science at Southeast Missouri State university. I have been coding ever since I wrote my first line of BASIC back in the 1980s. I like reading, retrocomputing, modern computing, artificial intlligence, programming, electronics, and math.

  • 0 Posts
  • 6 Comments
Joined 2 years ago
cake
Cake day: July 9th, 2023

help-circle
  • 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))
    

  • 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;
    }