Advent of code – Day 1: Calorie Counting
Galician
Introducción.
Comezou o Advent of Code 2022! E ao igual que nas pasadas edicións, teremos que resolver dous puzzles, utilizando uns datos de entrada que nos proporcionarán xunto ao enunciado do problema.
Parte un do problema.
O enunciado.
Vale, o enunciado está en inglés, e é unha matada traducilo. Así que podedes velo, aquí. Nun futuro, se teño tempo, tradúzoo.
Adaptando os datos de entrada.
O enunciado do puzzle, proporciona unha colección única de datos, única por participante. Esta colección de datos (input), é moi longa, no meu caso, está formada por 2251 liñas (incluindo números e liñas baleiras). Pero nesta publicación, non utilizarei o meu input, se non o input de exemplo.
Despois de ler e comprender o enunciado, a forma máis rápida que ocurréuseme para utilizar este input, foi a de convertir cada liña nunha cadea de caracteres (String), e usalas como membros dun vector (array).
Como son moitas liñas, imos ver un truquiño no Notepad++, para facelo dunha forma moi rápida e sinxela.
Vamos, que o obxectivo é convertir esto:
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
a esto
"1000",
"2000",
"3000",
"",
"4000",
"",
"5000",
"6000",
"",
"7000",
"8000",
"9000",
"",
"10000"
E os pasos para conseguilo, son:
- Engadir ‘“‘ ao principio de cada liña:
- Acceder á sección substituír (reemplazar) en Notepad++ (Cntrl+H ou pulsar en Search -> Replace).
- Seleccionar a opción Regular Expression ao fondo da ventana.
- Escribir ^ no cadro de texto Find what.
- Escribir “ no cacro de texto Replace with.
- Colocar o cursor ao principio da primeira liña, para asegurar que todas as liñas serán cambiadas.
- Pulsar na opción Replace All.
- Engadir ‘“,‘ ao final de cada liña:
- Acceder á sección substituír (reemplazar) en Notepad++ (Cntrl+H ou pulsar en Search -> Replace).
- Seleccionar a opción Regular Expression ao fondo da ventana.
- Escribir $ no cadro de texto Find what.
- Escribir “ no cacro de texto Replace with.
- Colocar o cursor ao principio da primeira liña, para asegurar que todas as liñas serán cambiadas.
- Pulsar na opción Replace All.
- Eliminar a coma da última liña.
Como paso opcional, podemos unir todos os resultados nunha sola liña:
“1000”,”2000″,”3000″,””,”4000″,””,”5000″,”6000″,””,”7000″,”8000″,”9000″,””,”10000″ |
- Acceder á sección substituír (reemplazar) en Notepad++ (Cntrl+H ou pulsar en Search -> Replace).
- Seleccionar a opción Regular Expression ao fondo da ventana.
- Escribir \R no cadro de texto Find what.
- Deixar baleiro o cadro de texto Replace with.
- Colocar o cursor ao principio da primeira liña, para asegurar que todas as liñas serán cambiadas.
- Pulsar na opción Replace All.
A solución utilizando os datos adaptados.
Agora, podemos crear un array de Strings có input recén adaptado:
final String[] calories =new String[] {
"1000","2000","3000","","4000","","5000","6000","","7000","8000","9000","","10000"
}
E podémolo iterar para resolver a primeira parte do puzzle;:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AdventCode1 {
public static void main(String[] args) {
final String[] calories = new String[] { INPUT_VALUES_HERE };
long sumCalories = 0;
List<Long> elves = new ArrayList<>();
for (String calory : calories) {
if (!calory.isEmpty()) {
//incrementar a suma de calorias ata que atopamos un espazo baleiro
sumCalories = sumCalories + Long.valueOf(calory);
} else {
//se atopamos o espazo baleiro, engadimos a suma
//e reiniciamos a variable para as sumas seguintes.
elves.add(sumCalories);
sumCalories = 0;
}
}
System.out.println(
"O elfo con máis calorías está a carrexar: " +
Collections.max(elves) + " calorías"
);
}
}
Parte dous do problema.
O enunciado.
O mesmiño que na parte 1, o enunciado está en inglés, e é unha matada traducilo. Así que podedes velo, aquí. Nun futuro, se teño tempo, tradúzoo.
A solución utilizando sort, sublist e stream.
Ok, temos a lista de calorías creada no paso 1. Polo que para atopar o total de calorías carrexado polos 3 elfos que máis calorías están a carrexar, podemos ordear a lista de forma descendente, crear unha sublista cós 3 primeiros elementos, e por último, sumalos usando streams.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AdventCode1 {
public static void main(String[] args) {
//PARTE 1
final String[] calories = new String[] { INPUT_VALUES_HERE };
long sumCalories = 0;
List<Long> elves = new ArrayList<>();
for (String calory : calories) {
if (!calory.isEmpty()) {
//incrementar a suma de calorias ata que atopamos un espazo baleiro
sumCalories = sumCalories + Long.valueOf(calory);
} else {
//se atopamos o espazo baleiro, engadimos a suma
//e reiniciamos a variable para as sumas seguintes.
elves.add(sumCalories);
sumCalories = 0;
}
}
System.out.println(
"O elfo con máis calorías está a carrexar: " +
Collections.max(elves) + " calorías"
);
//PARTE 2
Collections.sort(elves, Collections.reverseOrder()); //Ordear desc
System.out.println(
"Os 3 elfos que carrexan máis calorías, carrexan: " +
elves.subList(0,3)
);
System.out.println(
"E en total están a carrexar: " +
elves.subList(0,3).stream().collect(
Collectors.summingLong(Long::longValue)
)
+ " calorías"
);
}
}
E listo 😉
Regresar á páxina principal do Advent of Code 2022.
English
Introduction
The Advent of code has started! And as in last editions, every day we will have to solve two puzzles, based on an “input” that the program will give us.
Part 1 of the problem.
The statement
First of all, the statement of the first part can be read below:
Santa’s reindeer typically eat regular reindeer food, but they need a lot of magical energy to deliver presents on Christmas. For that, their favorite snack is a special type of star fruit that only grows deep in the jungle. The Elves have brought you on their annual expedition to the grove where the fruit grows.
To supply enough magical energy, the expedition needs to retrieve a minimum of fifty stars by December 25th. Although the Elves assure you that the grove has plenty of fruit, you decide to grab any fruit you see along the way, just in case.
Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck!
The jungle must be too overgrown and difficult to navigate in vehicles or access from the air; the Elves’ expedition traditionally goes on foot. As your boats approach land, the Elves begin taking inventory of their supplies. One important consideration is food – in particular, the number of Calories each Elf is carrying (your puzzle input).
The Elves take turns writing down the number of Calories contained by the various meals, snacks, rations, etc. that they’ve brought with them, one item per line. Each Elf separates their own inventory from the previous Elf’s inventory (if any) by a blank line.
For example, suppose the Elves finish writing their items’ Calories and end up with the following list:
1000 2000 3000 4000 5000 6000 7000 8000 9000 10000
This list represents the Calories of the food carried by five Elves:
* The first Elf is carrying food with
1000
,2000
, and3000
Calories, a total of6000
Calories.– The second Elf is carrying one food item with
4000
Calories.– The third Elf is carrying food with
5000
and6000
Calories, a total of11000
Calories.– The fourth Elf is carrying food with
7000
,8000
, and9000
Calories, a total of24000
Calories.– The fifth Elf is carrying one food item with
10000
Calories.In case the Elves get hungry and need extra snacks, they need to know which Elf to ask: they’d like to know how many Calories are being carried by the Elf carrying the most Calories. In the example above, this is
24000
(carried by the fourth Elf).Find the Elf carrying the most Calories. How many total Calories is that Elf carrying?
Day 1 – Advent of code
Adapting the provided input data
The puzzle’s statement will provide us a longest and unique input, with a group of numbers separated by an empty line. In my case, the input has 2251 lines (including numbers and empty lines). But in this post, I will not use my input, I will use the example input.
So, the quickest way I could think of to use this input (and the empty lines as a separator), was to convert each row to string, and use them as member of an array. But there are many lines, so we can use some tricks in Notepad++ to quickly transform it.
So, the goal, using the example input is to convert from:
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
to
"1000",
"2000",
"3000",
"",
"4000",
"",
"5000",
"6000",
"",
"7000",
"8000",
"9000",
"",
"10000"
And the steps to achieve it, are:
- Adding ‘“‘at the beginning of each line:
- Go to Replace in Notepad++ (Ctrl+H or in menu bar, click Search -> Replace).
- Choose the Regular Expression option at the bottom of the dialog.
- Type ^ in the Find what textbox.
- Type “ in the Replace with textbox.
- Place cursor in the first line of the file to ensure all lines are affected.
- Click Replace All button.
- Add ‘“,‘ at the end of each line:
- Go to Replace in Notepad++ (Ctrl+H or in menu bar, click Search -> Replace).
- Choose the Regular Expression option at the bottom of the dialog.
- Type $ in the Find what textbox.
- Type “, in the Replace with textbox.
- Place cursor in the first line of the file to ensure all lines are affected.
- Click Replace All button.
- Delete last comma in the last line.
As an optional step, we can join all results in one line:
“1000”,”2000″,”3000″,””,”4000″,””,”5000″,”6000″,””,”7000″,”8000″,”9000″,””,”10000″ |
- Go to Replace in Notepad++ (Ctrl+H or in menu bar, click Search -> Replace).
- Choose the Regular Expression option at the bottom of the dialog.
- Type \R in the Find what textbox.
- Leave empty the Replace with textbox.
- Place cursor in the first line of the file to ensure all lines are affected.
- Click Replace All button.
Solution using the adapted input.
So, now in our code we can create an String array with the formatted input:
final String[] calories =new String[] {
"1000","2000","3000","","4000","","5000","6000","","7000","8000","9000","","10000"
}
And now, we can iterate this string to solve the first part of the puzzle:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AdventCode1 {
public static void main(String[] args) {
final String[] calories = new String[] { INPUT_VALUES_HERE };
long sumCalories = 0;
List<Long> elves = new ArrayList<>();
for (String calory : calories) {
if (!calory.isEmpty()) {
//increase the sum of calories until a separator is found
sumCalories = sumCalories + Long.valueOf(calory);
} else {
//if the separator is found, we add the sum of calories,
//and restart the sum.
elves.add(sumCalories);
sumCalories = 0;
}
}
System.out.println(
"The Elf carrying the most calories carries: " +
Collections.max(elves) + " calories"
);
}
}
Part 2 of the problem.
The statement.
So the first part is solved, and we can continue with the second part, that has the following statement:
By the time you calculate the answer to the Elves’ question, they’ve already realized that the Elf carrying the most Calories of food might eventually run out of snacks.
To avoid this unacceptable situation, the Elves would instead like to know the total Calories carried by the top three Elves carrying the most Calories. That way, even if one of those Elves runs out of snacks, they still have two backups.
In the example above, the top three Elves are the fourth Elf (with
24000
Calories), then the third Elf (with11000
Calories), then the fifth Elf (with10000
Calories). The sum of the Calories carried by these three elves is45000
.Find the top three Elves carrying the most Calories. How many Calories are those Elves carrying in total?
Day 1 – Advent of code
Solution using sort, sublist, and streams.
Ok, we have a calories list created in part one. So to find the total calories carried by the top three Elves, we can sort the list (descending), and after that, create a sublist of first 3 elements, and last, sum them using streams.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AdventCode1 {
public static void main(String[] args) {
//PART1
final String[] calories = new String[] { INPUT_VALUES_HERE };
long sumCalories = 0;
List<Long> elves = new ArrayList<>();
for (String calory : calories) {
if (!calory.isEmpty()) {
//increase the sum of calories until a separator is found
sumCalories = sumCalories + Long.valueOf(calory);
} else {
//if the separator is found, we add the sum of calories,
//and restart the sum.
elves.add(sumCalories);
sumCalories = 0;
}
}
System.out.println(
"The Elf carrying the most calories carries: " +
Collections.max(elves) + " calories"
);
//PART 2
Collections.sort(elves, Collections.reverseOrder()); //Order DESC
System.out.println(
"The Elves carrying the most calories are carrying: " +
elves.subList(0,3)
);
System.out.println(
"And in total they are carrying: " +
elves.subList(0,3).stream().collect(
Collectors.summingLong(Long::longValue)
)
+ " calories"
);
}
}
And solved 🙂
3 Comments