Day 3

Author

Julia Romanowska

The input

Each line consists of symbols and digits. Digits form numbers, delimited by either . (full stop) or another symbol. A number is part of the engine if it is adjacent to any symbol other than . (even diagonally).

#input_file = open("../../DATA/2023/input_day03.txt", "r");
input_file = open("../../DATA/2023/example_input_day03.txt", "r");
println(peek(input_file, String))
467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..

Part 1

What I need to do is:

  1. find all the numbers and their positions (line number and column number)
  2. find all the symbols that are not . and their positions
  3. check positions of numbers against positions of symbols (a la rolling join)

Find all the numbers and symbols, and their positions

all_numbers_positions = DataFrame(
    cur_number = 0,
    line_no = 0,
    column_start = 0,
    column_end = 0
);

all_symbols_positions = DataFrame(
    cur_symbol = 0,
    line_no = 0,
    column_pos = 0
);
function match_all(pattern::Regex, where_to_match::String)
    all_positions = Int32[];
    all_matches = String[];
    idx = 1;
    while idx < lastindex(where_to_match)
        m = match(pattern, where_to_match, idx);
        if isnothing(m)
            break
        end
        push!(all_positions, m.offset);
        push!(all_matches, m.match);
        idx = m.offset + 1;
    end
    return DataFrame(
        cur_number = all_matches,
        cur_position = all_positions
    )
end
match_all (generic function with 1 method)
line = readline(input_file);
cur_line_no = 1;
while line != ""
    # find digits...
    cur_line_numbers_found = match_all(r"\d", line);
    # and make them into numbers
    #   find difference in position from the previous digit:
    diff_numbers_positions = [2; diff(cur_line_numbers_found.cur_position)];
    # the next will be simpler if I create groups based on the position
    cur_group = 0;
    groups = Int32[];
    for idx in diff_numbers_positions
        if idx != 1
            global cur_group += 1;
        end
        push!(groups, cur_group);
    end
    cur_line_numbers_found[:, :group_no] = groups;
    #   find beginning and end of each number:
    cur_numbers_out = combine(
        groupby(cur_line_numbers_found, :group_no),
        [:cur_number, :cur_position] =>
         ((n, p) -> (cur_number = parse(Int32, string(n...)),
                    column_start = min(p...),
                    column_end = max(p...))) =>
         AsTable
    );
    cur_numbers_out[:, :line_no] = fill(cur_line_no, nrow(cur_numbers_out));
    select!(cur_numbers_out, Not(:group_no));
    #  finally, add to the big table
    append!(all_numbers_positions, cur_numbers_out);

    # find symbols...
    cur_line_symbols_found = match_all(r"[^\d.]", line);
    # and place in the DataFrame
    append!(
        all_symbols_positions,
        DataFrame(
            cur_symbol = cur_line_symbols_found.cur_number,
            line_no = fill(cur_line_no, nrow(cur_line_symbols_found)),
            column_pos = cur_line_symbols_found.cur_position
        )
    )

    # read the next line:
    global line = readline(input_file);
    global cur_line_no =+ 1;
end

close(input_file)
LoadError: syntax: `global cur_group`: cur_group is a local variable in its enclosing scope