carlosjai.me

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:

  1. Engadir ‘‘ ao principio de cada liña:
    1. Acceder á sección substituír (reemplazar) en Notepad++ (Cntrl+H ou pulsar en Search -> Replace).
    2. Seleccionar a opción Regular Expression ao fondo da ventana.
    3. Escribir ^ no cadro de texto Find what.
    4. Escribir no cacro de texto Replace with.
    5. Colocar o cursor ao principio da primeira liña, para asegurar que todas as liñas serán cambiadas.
    6. Pulsar na opción Replace All.
  2. Engadir ‘“,‘ ao final de cada liña:
    1. Acceder á sección substituír (reemplazar) en Notepad++ (Cntrl+H ou pulsar en Search -> Replace).
    2. Seleccionar a opción Regular Expression ao fondo da ventana.
    3. Escribir $ no cadro de texto Find what.
    4. Escribir no cacro de texto Replace with.
    5. Colocar o cursor ao principio da primeira liña, para asegurar que todas as liñas serán cambiadas.
    6. Pulsar na opción Replace All.
    7. 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″
  1. Acceder á sección substituír (reemplazar) en Notepad++ (Cntrl+H ou pulsar en Search -> Replace).
  2. Seleccionar a opción Regular Expression ao fondo da ventana.
  3. Escribir \R no cadro de texto Find what.
  4. Deixar baleiro o cadro de texto Replace with.
  5. Colocar o cursor ao principio da primeira liña, para asegurar que todas as liñas serán cambiadas.
  6. 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 10002000, and 3000 Calories, a total of 6000 Calories.

– The second Elf is carrying one food item with 4000 Calories.

– The third Elf is carrying food with 5000 and 6000 Calories, a total of 11000 Calories.

– The fourth Elf is carrying food with 70008000, and 9000 Calories, a total of 24000 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:

  1. Adding ‘‘at the beginning of each line:
    1. Go to Replace in Notepad++ (Ctrl+H or in menu bar, click Search -> Replace).
    2. Choose the Regular Expression option at the bottom of the dialog.
    3. Type ^ in the Find what textbox.
    4. Type in the Replace with textbox.
    5. Place cursor in the first line of the file to ensure all lines are affected.
    6. Click Replace All button.
  2. Add “,‘ at the end of each line:
    1. Go to Replace in Notepad++ (Ctrl+H or in menu bar, click Search -> Replace).
    2. Choose the Regular Expression option at the bottom of the dialog.
    3. Type $ in the Find what textbox.
    4. Type “, in the Replace with textbox.
    5. Place cursor in the first line of the file to ensure all lines are affected.
    6. Click Replace All button.
    7. 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″
  1. Go to Replace in Notepad++ (Ctrl+H or in menu bar, click Search -> Replace).
  2. Choose the Regular Expression option at the bottom of the dialog.
  3. Type \R in the Find what textbox.
  4. Leave empty the Replace with textbox.
  5. Place cursor in the first line of the file to ensure all lines are affected.
  6. 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 (with 11000 Calories), then the fifth Elf (with 10000 Calories). The sum of the Calories carried by these three elves is 45000.

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 🙂

Return to Advent of Code 2022 main page.

3 Comments

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.