Jummit

u/Jummit@lemmy.one
3 posts · 97 comments

Recent posts

Recent comments

Nice and easy.

::: spoiler Lua

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

local function nums(str)
	local res = {}
	for num in str:gmatch("%d+") do
		res[num] = true
	end
	return res
end

local cards = {}
local points = 0
for line in io.open("4.input"):lines() do
	local winning, have = line:match("Card%s*%d+: (.*) | (.*)")
	winning = nums(winning)
	have = nums(have)
	local first = true
	local score = 0
	local matching = 0
	for num in pairs(have) do
		if winning[num] then
			matching = matching + 1
			if first then
				first = false
				score = score + 1
			else
				score = score * 2
			end
		end
	end
	points = points + score
	table.insert(cards, {have=have, wins=matching, count=1})
end
print(points)

local cardSum = 0
for i, card in ipairs(cards) do
	cardSum = cardSum + card.count
	for n = i + 1, i + card.wins do
		cards[n].count = cards[n].count + card.count
	end
end
print(cardSum)

Input parsing AGAIN?

::: spoiler 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)

:::

::: spoiler 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)!;
};

:::

Mostly an input parsing problem this time, but it was fun to use Hares tokenizer functions:

:::spoiler lua

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

local colors = {"blue", "red", "green"}
local available = {red = 12, blue = 14, green = 13}
local possible = 0
local id = 0
local min = 0

for game in io.open("2.input"):lines() do
  id = id + 1
  game = game:gsub("Game %d+: ", "").."; "
  local max = {red = 0, blue = 0, green = 0}
  for show in game:gmatch(".-; ") do
    for _, color in ipairs(colors) do
      local num = tonumber(show:match("(%d+) "..color))
      if num then
        max[color] = math.max(max[color], num)
      end
    end
  end
  min = min + max.red * max.blue * max.green
  local thisPossible = true
  for _, color in ipairs(colors) do
    if max[color] > available[color] then
      thisPossible = false
      break
    end
  end
  if thisPossible then
    possible = possible + id
  end
end

print(possible)
print(min)

:::

:::spoiler hare

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

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

const available: []uint = [12, 13, 14];

fn color_id(color: str) const uint = {
	switch (color) {
	case "red" => return 0;
	case "green" => return 1;
	case "blue" => return 2;
	case => abort();
	};
};

export fn main() void = {
	const file = os::open("2.input")!;
	defer io::close(file)!;
	const scan = bufio::newscanner(file, types::SIZE_MAX);
	let possible: uint = 0;
	let min: uint = 0;

	for (let id = 1u; true; id += 1) {
		const line = match(bufio::scan_line(&scan)!) {
		case io::EOF =>
			break;
		case let line: const str =>
			yield strings::sub(
					line,
					strings::index(line, ": ") as size + 2,
					strings::end);
		};
		let max: []uint = [0, 0, 0];
		let tok = strings::rtokenize(line, "; ");
		for (true) {
			const show = match(strings::next_token(&tok)) {
			case void =>
				break;
			case let show: str =>
				yield show;
			};
			const pairs = strings::tokenize(show, ", ");
			for (true) {
				const pair: (str, str) = match(strings::next_token(&pairs)) {
				case void =>
					break;
				case let pair: str =>
					let tok = strings::tokenize(pair, " ");
					yield (
						strings::next_token(&tok) as str,
						strings::next_token(&tok) as str
					);
				};
				let color = color_id(pair.1);
				let amount = strconv::stou(pair.0)!;
				if (amount > max[color]) max[color] = amount;
			};
		};
		if (max[0] <= available[0] && max[1] <= available[1] && max[2] <= available[2]) {
			fmt::printfln("{}", id)!;
			possible += id;
		};
		min += max[0] * max[1] * max[2];
	};
	
	fmt::printfln("{}", possible)!;
	fmt::printfln("{}", min)!;
};

:::

Trickier than expected! I ran into an issue with Lua patterns, so I had to revert to a more verbose solution, which I then used in Hare as well.

Lua:

::: spoiler lua

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

local sum = 0
for line in io.open("1.input"):lines() do
  local a, b = line:match("^.-(%d).*(%d).-$")
  if not a then
    a = line:match("%d+")
    b = a
  end
  if a and b then
    sum = sum + tonumber(a..b)
  end
end
print(sum)

local names = {
  ["one"] = 1,
  ["two"] = 2,
  ["three"] = 3,
  ["four"] = 4,
  ["five"] = 5,
  ["six"] = 6,
  ["seven"] = 7,
  ["eight"] = 8,
  ["nine"] = 9,
  ["1"] = 1,
  ["2"] = 2,
  ["3"] = 3,
  ["4"] = 4,
  ["5"] = 5,
  ["6"] = 6,
  ["7"] = 7,
  ["8"] = 8,
  ["9"] = 9,
}
sum = 0
for line in io.open("1.input"):lines() do
  local firstPos = math.huge
  local first
  for name, num in pairs(names) do
    local left = line:find(name)
    if left and left < firstPos then
      firstPos = left
      first = num
    end
  end
  local last
  for i = #line, 1, -1 do
    for name, num in pairs(names) do
      local right = line:find(name, i)
      if right then
        last = num
        goto found
      end
    end
  end
  ::found::
  sum = sum + tonumber(first * 10 + last)
end
print(sum)

:::

Hare:

::: spoiler hare

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

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

const numbers: [](str, int) = [
	("one", 1),
	("two", 2),
	("three", 3),
	("four", 4),
	("five", 5),
	("six", 6),
	("seven", 7),
	("eight", 8),
	("nine", 9),
	("1", 1),
	("2", 2),
	("3", 3),
	("4", 4),
	("5", 5),
	("6", 6),
	("7", 7),
	("8", 8),
	("9", 9),
];

fn solve(start: size) void = {
	const file = os::open("1.input")!;
	defer io::close(file)!;
	const scan = bufio::newscanner(file, types::SIZE_MAX);
	let sum = 0;
	for (let i = 1u; true; i += 1) {
		const line = match (bufio::scan_line(&scan)!) {
		case io::EOF =>
			break;
		case let line: const str =>
			yield line;
		};
		let first: (void | int) = void;
		let last: (void | int) = void;
		for (let i = 0z; i < len(line); i += 1) :found {
			for (let num = start; num < len(numbers); num += 1) {
				const start = strings::sub(line, i, strings::end);
				if (first is void && strings::hasprefix(start, numbers[num].0)) {
					first = numbers[num].1;
				};
				const end = strings::sub(line, len(line) - 1 - i, strings::end);
				if (last is void && strings::hasprefix(end, numbers[num].0)) {
					last = numbers[num].1;
				};
				if (first is int && last is int) {
					break :found;
				};
			};
		};
		sum += first as int * 10 + last as int;
	};
	fmt::printfln("{}", sum)!;
};

export fn main() void = {
	solve(9);
	solve(0);
};

:::

Ich weiß, das kommt hier nicht gut an, aber meiner Meinung nach hat sich schon länger erwiesen dass Wählen allein keine ausreichende Lösung für Probleme die mit Menschenrechten, Umwelt oder Lebensqualität zu tun haben ist. (Ich meine nicht Demokratie oder Wahlen generell, sondern unsere Bundestagswahl). Wir sind zwar besser dran als viele andere, aber ich denke Emma Goldman hatte mehr Recht als man zugeben möchte: "If voting changed anything, they'd make it illegal"

on *Permanently Deleted* · c/programming · 16 pts · 2y

Actually one of the few languages you can learn in its completeness in less than a day, so I wouldn't really say it's "hard to understand". More like hard to read and understands programs written in it.

Interesting viewpoint, but I think the applications aren't at fault: The operating system should ensure that the user has control of the computer at all times. I think you need to do three things to achieve that:

  1. Limit process RAM usage, so the system never has to swap
  2. Limit process CPU usage, so the system never stalls
  3. When drivers / the operating itself crash, revert into a usable state (this one is probably the most complex one)