Coś jest nie tak z globalną produkcją śniegu, i zostałeś wybrany, aby to sprawdzić. Elfy nawet dały ci mapę; na niej użyły gwiazd, aby oznaczyć pięćdziesiąt najpewniejszych lokalizacji, które prawdopodobnie mają problemy.
Próbujesz zapytać, dlaczego nie mogą po prostu użyć maszyny pogodowej ("nie wystarczająco silna") i dokąd cię tak w ogóle wysyłają ("na niebo") i dlaczego twoja mapa wygląda na pustą ("naprawdę zadajesz dużo pytań") i zaczekaj, czy właśnie powiedziałeś niebo ("oczywiście, skąd myślisz, że pochodzi śnieg") kiedy zdajesz sobie sprawę, że Elfy już cię ładują do trebusza ("proszę się trzymać, musimy cię przypiąć").
W trakcie ostatnich poprawek odkrywają, że ich dokument kalibracyjny (twoje dane wejściowe) został zmieniony przez bardzo młodą Elfkę, która była wyraźnie podekscytowana pokazaniem swoich umiejętności artystycznych. W związku z tym Elfy mają problemy z odczytaniem wartości na dokumencie.
Nowo ulepszony dokument kalibracyjny składa się z linii tekstu; każda linia początkowo zawierała określoną wartość kalibracji, które Elfy teraz muszą odzyskać. W każdej linii wartość kalibracji można znaleźć, łącząc pierwszą cyfrę i ostatnią cyfrę (w tej kolejności), aby utworzyć pojedynczą dwucyfrową liczbę.
Na przykład:
1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet
W tym przykładzie wartości kalibracji tych czterech linii to 12
, 38
, 15
i 77
. Ich dodanie daje 142
.
Rozważ cały swój dokument kalibracyjny. Jaka jest suma wszystkich wartości kalibracji?
const solution = (data: string) => {
return (
data
// Split the data into lines
.split("\n")
// For each line, find first and last digit
.map((line) => {
const digits = line.match(/d/g);
const first = digits?.at(0);
const last = digits?.at(-1);
if (first === undefined || last === undefined) {
return null;
}
const parsedFirst = parseInt(first);
const parsedLast = parseInt(last);
if (isNaN(parsedFirst) || isNaN(parsedLast)) {
return null;
}
return [parsedFirst, parsedLast] as [number, number];
})
// Filter out nulls for invalid lines
.filter((x) => x !== null)
// Casting to non-null array because filter does not change the type
.map((x) => x as NonNullable<typeof x>)
// Map two digits into one number
.map(([first, last]) => parseInt(`${first}${last}`))
// Sum all numbers
.reduce((acc, x) => acc + x, 0)
);
};
Zostajesz wystrzelony wysoko w atmosferę! Apogeum twojej trajektorii ledwo dotyka powierzchni dużej wyspy unoszącej się w powietrzu. Delikatnie lądujesz w puszystym stosie liści. Jest dość zimno, ale nie widzisz zbyt dużo śniegu. Elf biegnie, aby cię przywitać.
Elf wyjaśnia, że przybyłeś na Wyspę Śnieżną i przeprasza za brak śniegu. Chętnie wyjaśni sytuację, ale to trochę spaceru, więc masz trochę czasu. Nie ma tu zbyt wielu odwiedzających; chciałbyś zagrać w grę w międzyczasie?
Podczas spaceru Elf pokazuje małą torbę i kilka kostek, które są czerwone, zielone lub niebieskie. Za każdym razem, gdy grasz w tę grę, ukryje on w torbie tajną liczbę kostek każdego koloru, a Twoim celem jest znalezienie informacji o liczbie kostek.
Aby uzyskać informacje, po załadowaniu torby kostkami Elf sięgnie do torby, weźmie garść losowych kostek, pokaże je graczowi, a następnie włoży je z powrotem do torby. Zrobi to kilka razy w ciągu gry.
Grasz w kilka gier i zapisujesz informacje z każdej z nich (dane wejściowe łamigłówki). Każda gra jest wymieniona z jej numerem ID (jak 11
w Game 11: ...
), po którym następuje oddzielona średnikami lista podzbiorów kostek, które zostały ujawnione z worka (jak 3 czerwone, 5 zielonych, 4 niebieskie
).
Na przykład, zapis kilku gier może wyglądać następująco:
Gra 1: 3 niebieskie, 4 czerwone; 1 czerwony, 2 zielone, 6 niebieskich; 2 zielone
Gra 2: 1 niebieski, 2 zielone; 3 zielone, 4 niebieskie, 1 czerwony; 1 zielony, 1 niebieski
Gra 3: 8 zielonych, 6 niebieskich, 20 czerwonych; 5 niebieskich, 4 czerwone, 13 zielonych; 5 zielonych, 1 czerwony
Gra 4: 1 zielony, 3 czerwone, 6 niebieskich; 3 zielone, 6 czerwonych; 3 zielone, 15 niebieskich, 14 czerwonych
Gra 5: 6 czerwonych, 1 niebieski, 3 zielone; 2 niebieskie, 1 czerwony, 2 zielone
W pierwszej grze trzy zestawy kostek są odkrywane z woreczka (a następnie odkładane z powrotem). Pierwszy zestaw to 3 niebieskie kostki i 4 czerwone kostki; drugi zestaw to 1 czerwona kostka, 2 zielone kostki i 6 niebieskich kostek; trzeci zestaw to tylko 2 zielone kostki.
Elf chciałby najpierw wiedzieć, które gry byłyby możliwe, gdyby worek zawierał tylko 12 czerwonych kostek, 13 zielonych kostek i 14 niebieskich kostek?
W powyższym przykładzie gry 1, 2 i 5 byłyby możliwe, gdyby worek był załadowany w takiej konfiguracji. Jednak gra 3 byłaby niemożliwa, ponieważ w pewnym momencie Elf pokazał ci 20 czerwonych kostek naraz; podobnie gra 4 byłaby niemożliwa, ponieważ Elf pokazał ci 15 niebieskich kostek naraz. Jeśli zsumujesz identyfikatory gier, które byłyby możliwe, otrzymasz 8
.
Określ, które gry byłyby możliwe, gdyby worek zawierał tylko 12 czerwonych kostek, 13 zielonych kostek i 14 niebieskich kostek. Jaka jest suma identyfikatorów tych gier?
const solution = (data: string) => {
const maxRedCubes = 12;
const maxGreenCubes = 13;
const maxBlueCubes = 14;
return (
data
// Split the data into lines
.split("\n")
// Validate and parse the input
.map((line) => {
const isLineValid =
/Game\s\d+:((\s\d+\s(blue|red|green)(,|;|$)))+/.test(line);
if (!isLineValid) {
return null;
}
const gameId = line.match(/Game\s\d+/)!.at(0)!; // Non null assertions because we did check the validation
const parsedGameId = parseInt(gameId.replace("Game ", ""));
const rounds = line
.replace(/Game\s\d+:\s/, "")
.split(";")
.map((round) => round.trim());
const parsedRounds = rounds.map((round) => {
const redMatch = round.match(/\d+\sred/) ?? ["0 red"];
const greenMatch = round.match(/\d+\sgreen/) ?? ["0 green"];
const blueMatch = round.match(/\d+\sblue/) ?? ["0 blue"];
const red = parseInt(redMatch.at(0)!.replace(" red", "")); // Non null assertions because we did check the validation
const green = parseInt(greenMatch.at(0)!.replace(" green", "")); // Non null assertions because we did check the validation
const blue = parseInt(blueMatch.at(0)!.replace(" blue", "")); // Non null assertions because we did check the validation
return { red, green, blue };
});
return { game: parsedGameId, rounds: parsedRounds };
})
// Filter out invalid lines
.filter((line) => line !== null)
// Casting to the correct type because filter does not change the type
.map((line) => line as NonNullable<typeof line>)
// Filter out games with invalid rounds
.filter((game) => {
return game.rounds.every((round) => {
return (
round.red <= maxRedCubes &&
round.green <= maxGreenCubes &&
round.blue <= maxBlueCubes
);
});
})
// Sum the gameIds numbers
.reduce((acc, game) => {
return acc + game.game;
}, 0)
);
};
Ty i Elf w końcu docieracie do stacji wyciągu gondolowego; mówi, że wyciąg gondolowy zabierze cię do źródła wody, ale to jest najdalej, jak cię może przyprowadzić. Wchodzisz do środka.
Nie trwa długo, zanim znajdujesz gondole, ale wydaje się, że jest problem: się nie poruszają.
"Aaah!"
Odwracasz się, aby zobaczyć lekko tłustego Elfa z kluczem francuskim i wyrazem zdziwienia. "Przepraszam, nie spodziewałem się nikogo! Wyciąg gondolowy nie działa; minie jeszcze trochę czasu, zanim będę mógł go naprawić." Oferujesz pomoc.
Inżynier wyjaśnia, że część silnika wydaje się brakować w silniku, ale nikt nie może zrozumieć, która to jest. Jeśli możesz dodać wszystkie numery części w schemacie silnika, powinno być łatwo ustalić, która część brakuje.
Schemat silnika (twoje dane wejściowe) składa się z wizualnej reprezentacji silnika. Jest wiele liczb i symboli, których nie rozumiesz, ale każda liczba przylegająca do symbolu, nawet na ukos, jest "numerem części" i powinna być wliczona w sumę. (Kropki (.
) nie są uważane za symbol.)
Oto przykładowy schemat silnika:
467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..
W tym schemacie dwie liczby nie są numerami części, ponieważ nie są przylegające do symbolu: 114
(góra po prawej) i 58
(środek po prawej). Każda inna liczba przylega do symbolu i jest numerem części; ich suma to 4361
.
Oczywiście, rzeczywisty schemat silnika jest znacznie większy. Jaka jest suma wszystkich numerów części w schemacie silnika?
const solution = (data: string) => {
type Coordinates = [number, number];
// Possible signs that we are searching for as neighbours
const listOfPossibleSigns = [
"*",
"#",
"$",
"@",
"%",
"&",
"=",
"+",
"-",
"/",
];
// A matrix of all the values
const matrix = data.split("\n").map((line) => line.split(""));
return (
data
// Split the data into lines
.split("\n")
// Parse the input so it includes the values and its coordinates
.map((line, row) => {
return line.split("").reduce((acc, char, column) => {
if (!/\d/.test(char)) {
return [...acc, { value: "", coordinates: [] }];
}
if (acc.length === 0) {
return [
{ value: char, coordinates: [[row, column] as Coordinates] },
];
}
const copy = structuredClone(acc);
const lastElement = copy.at(-1)!; // Asserting because we know that the array is not empty
lastElement.value += char;
lastElement.coordinates.push([row, column] as Coordinates);
return copy;
}, [] as { value: string; coordinates: Coordinates[] }[]);
})
// Flattening the lines
.flat(1)
// Filtering items with empty value
.filter((item) => item.value !== "")
// Adding the signs neighbours to each item
.map((item) => {
return {
...item,
neighbours: item.coordinates
.map(([row, column]) => {
return [
matrix[row - 1]?.[column - 1],
matrix[row - 1]?.[column],
matrix[row - 1]?.[column + 1],
matrix[row]?.[column - 1],
matrix[row]?.[column + 1],
matrix[row + 1]?.[column - 1],
matrix[row + 1]?.[column],
matrix[row + 1]?.[column + 1],
]
.filter((value) => value !== undefined)
.filter((value) => listOfPossibleSigns.includes(value));
})
.flat(1),
};
})
// Filtering items that have no neighbours
.filter((item) => item.neighbours.length > 0)
// Parsing the items values to numbers
.map((item) => parseInt(item.value))
// Summing the values
.reduce((acc, value) => acc + value, 0)
);
};