this post was submitted on 03 Dec 2023
20 points (95.5% liked)

Advent Of Code

736 readers
1 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2023

Solution Threads

M T W T F S S
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 1 year ago
MODERATORS
 

Day 3: Gear Ratios


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/ or pastebin (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


🔒This post will be unlocked when there is a decent amount of submissions on the leaderboard to avoid cheating for top spots

🔓 Edit: Post has been unlocked after 11 minutes

you are viewing a single comment's thread
view the rest of the comments
[–] Jummit@lemmy.one 2 points 9 months ago* (last edited 9 months ago)

Input parsing AGAIN?

Lua

-- SPDX-FileCopyrightText: 2023 Jummit
--
-- SPDX-License-Identifier: GPL-3.0-or-later

local lines = {}
for line in io.open("3.input"):lines() do
	table.insert(lines, "."..line..".")
end
local width = #lines[1]
local height = #lines
local function at(x, y, w)
	if y < 1 or y > height then return nil end
	return lines[y]:sub(x, x + w - 1)
end
local sum = 0
local gears = {}
for y, line in ipairs(lines) do
	local start = 1
	local outLine = line
	while true do
		local newStart, numEnd = line:find("%d+", start)
		if not newStart then break end
		local symbol = false
		local num = tonumber(line:sub(newStart, numEnd))
		for y = y - 1, y + 1 do
			local surrounding = at(newStart - 1, y, numEnd - newStart + 3)
			if surrounding then
				if surrounding and surrounding:match("[^.%d]") then
					symbol = true
				end
				for i = 1, #surrounding do
					local gear = surrounding:sub(i, i) == "*"
					if gear then
						if not gears[y] then
							gears[y] = {}
						end
						local x = i + newStart - 2
						if not gears[y][x] then
							gears[y][i + newStart - 2] = {}
						end
						table.insert(gears[y][x], num)
					end
				end
			end
		end
		if symbol then
			sum = sum + num
		end
		start = numEnd + 1
	end
end
print(sum)
local ratio = 0
for _, line in pairs(gears) do
	for _, gears in pairs(line) do
		if #gears == 2 then
			ratio = ratio + gears[1] * gears[2]
		end
	end
end
print(ratio)

Hare (Part one only)

// SPDX-FileCopyrightText: 2023 Jummit
//
// SPDX-License-Identifier: GPL-3.0-or-later

use strings;
use regex;
use fmt;
use os;
use bufio;
use io;
use strconv;
use types;

fn star_in(lines: []str, x: uint, y: uint, w: uint) bool = {
	let start = y;
	if (start > 0) start -= 1;
	let end = y + 1;
	if (end >= len(lines)) end -= 1;
	const re = regex::compile(`[^.0-9]`)!;
	for (let h = start; h <= end; h += 1) {
		fmt::println(strings::sub(lines[h], x, x + w))!;
		if (regex::test(&re, strings::sub(lines[h], x, x + w))) {
			fmt::println("")!;
			return true;
		};
	};
	fmt::println("")!;
	return false;
};

export fn main() void = {
	const file = os::open("3.input")!;
	defer io::close(file)!;
	const buf = bufio::newscanner(file, types::SIZE_MAX);
	let lines: []str = [];
	defer strings::freeall(lines);
	for (true) {
		match (bufio::scan_line(&buf)!) {
		case io::EOF =>
			break;
		case let line: const str =>
			append(lines, strings::dup(line));
		};
	};
	const height = len(lines);
	const width = len(lines[0]);
	let sum: uint = 0;
	let gears: [](uint, uint) = [];
	const num_re = regex::compile(`[0-9]+`)!;
	for (let y = 0u; y < len(lines); y += 1) {
		let nums = regex::findall(&num_re, lines[y]);
		defer regex::result_freeall(nums);
		for (let i = 0z; i < len(nums); i += 1) {
			for (let j = 0z; j < len(nums[i]); j += 1) {
				const find = nums[i][j];
				const num = strconv::stou(find.content)!;
				let start = find.start: uint;
				let w = len(find.content): uint + 2;
				if (start > 0) {
					start -= 1;
				} else {
					w -= 1;
				};
				if (star_in(lines, start, y, w)) {
					sum += num;
				};
			};
		};
	};
	fmt::printfln("{}", sum)!;
};