

This isn’t Lua code, Lua requires commas as separators for table items.
EDIT: Retracted, it seems like Lua allows this madness
Software developer and artist.


This isn’t Lua code, Lua requires commas as separators for table items.
EDIT: Retracted, it seems like Lua allows this madness


I hope it’s going to be used instead of machine learning. Seems much more correct, secure and efficient to me.

Slowly first, then all at once.
Nice and easy.
-- 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?
-- 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)
// 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:
-- 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)
// 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:
-- 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:
// 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);
};


I’m going to use https://harelang.org to get more comfortable in it, and maybe my own languages, Otomescript and Hase.


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”

and fuck people selling technology as a solution instead of system change.

It’s also called depression. (I think, don’t quote me on that.)


Any time I see graphs or statistics which cut of at 2020 to 2021 I get the feeling that the trend is being misrepresented, maybe deliberately.

But that would still put Earth on track to heat up roughly 2.5 to 2.9 degrees Celsius over preindustrial levels by the century’s end, the report found
Doesn’t that still mean extinction of nearly all life on earth? What’s with the headline saying “safe levels”?

I think we have underestimated how much progress has been made on killing the planet.


It was always self defense. Just not as justified as it is now.


Same here. Sounds pretty sustainable to me!
I doubt TCP/UDP or basic HTTP requests will change much, but I guess it depends on how high-level the API is.


Of course the most productive comment is the least upvoted one. EDIT: After thinking about it, maybe it’s best to add an explanation to bare links.


Are you beginning to see things more clearly now?
Wow. Seems like I will never stop learning new things about Lua.