~~This isn't Lua code, Lua requires commas as separators for table items.~~
EDIT: Retracted, it seems like Lua allows this madness
~~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.
::: 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?
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)!;
};
Mostly an input parsing problem this time, but it was fun to use Hares tokenizer functions:
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)
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:
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:
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.)
Wow. Seems like I will never stop learning new things about Lua.