~~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.
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.
Wow. Seems like I will never stop learning new things about Lua.