commit 1ddf3370da21d565c6d63f7a9e401d0bfea77fae
parent 0ee588a595285446c83fa822f69b2823aa824315
Author: Jake Bauer <jbauer@paritybit.ca>
Date: Thu, 18 May 2023 21:54:59 -0400
Improve on the AoC Day 1 solution
Diffstat:
12 files changed, 222 insertions(+), 98 deletions(-)
diff --git a/aoc-day1/README.md b/aoc-day1/README.md
@@ -0,0 +1,2 @@
+Practicing some simple Java programming by solving the [Day 1
+challenge](https://adventofcode.com/2022/day/1) from Advent of Code 2022.
diff --git a/aoc-day1/better/Elf.java b/aoc-day1/better/Elf.java
@@ -0,0 +1,7 @@
+public class Elf {
+ public int totalCalories;
+
+ public void addCalories (int calories) {
+ this.totalCalories += calories;
+ }
+}
diff --git a/aoc-day1/better/Main.java b/aoc-day1/better/Main.java
@@ -0,0 +1,28 @@
+// Using the Advent of Code 2022 Day 1 challenge as a practical example for
+// reading and writing to a file.
+
+import java.util.Scanner;
+
+public class Main {
+ public static void main(String[] args) {
+ System.out.println("Advent of Code 2022, Day 1");
+
+ Scanner sc = new Scanner(System.in);
+ System.out.print("File containing input data: ");
+ String fileName = sc.nextLine();
+
+ Solver solver = new Solver(fileName);
+
+ int result = solver.solvePartOne();
+ long startTime = System.nanoTime();
+ System.out.println("Part One: " + result);
+ long endTime = System.nanoTime();
+ System.out.println("Took: " + Long.toString((endTime - startTime) / 1000) + " microseconds");
+
+ result = solver.solvePartTwo();
+ startTime = System.nanoTime();
+ System.out.println("Part Two: " + result);
+ endTime = System.nanoTime();
+ System.out.println("Took: " + Long.toString((endTime - startTime) / 1000) + " microseconds");
+ }
+};
diff --git a/aoc-day1/better/README b/aoc-day1/better/README
@@ -0,0 +1,14 @@
+This solution is much more in line with how Java programs are normally
+written. The code looks a lot cleaner and more straightforward. Also, even
+though the program uses more RAM to store all the Elf objects and their
+totalCalories, it runs faster since it does less work overall.
+
+As measured using hyperfine(1):
+
+OLD:
+Time (mean ± σ): 310.9 ms ± 145.8 ms
+Range (min … max): 172.2 ms … 583.5 ms
+
+NEW:
+Time (mean ± σ): 225.2 ms ± 85.5 ms
+Range (min … max): 142.2 ms … 392.6 ms
diff --git a/aoc-day1/better/Solver.java b/aoc-day1/better/Solver.java
@@ -0,0 +1,65 @@
+import java.util.ArrayList;
+import java.util.Scanner;
+import java.util.Collections;
+import java.io.*;
+
+public class Solver {
+ private ArrayList<Elf> elves;
+
+ public Solver(String fn) {
+ elves = new ArrayList<Elf>();
+ parseData(fn);
+ }
+
+ // Fill the list of elves by reading the data in the file
+ // Finally, sort that list (in reverse order) based on Elf.totalCalories
+ private void parseData(String fileName) {
+ try {
+ File file = new File(fileName);
+ Scanner fileReader = new Scanner(file);
+
+ Elf newElf = new Elf();
+ elves.add(newElf);
+
+ while (fileReader.hasNextLine()) {
+ String line = fileReader.nextLine();
+ if (line.isEmpty()) {
+ newElf = new Elf();
+ elves.add(newElf);
+ continue;
+ }
+ newElf.addCalories(Integer.parseInt(line));
+ }
+
+ fileReader.close();
+
+ Collections.sort(elves, (Elf e1, Elf e2) -> {
+ if (e1.totalCalories > e2.totalCalories)
+ return -1;
+ else if (e1.totalCalories == e2.totalCalories)
+ return 0;
+ else
+ return 1;
+ });
+ }
+ catch (FileNotFoundException e) {
+ System.err.println("File " + fileName + " not found!");
+ System.exit(1);
+ }
+ }
+
+ // Find the number of calories carried by the elf carrying the most
+ // calories
+ public int solvePartOne() {
+ return this.elves.get(0).totalCalories;
+ }
+
+ // Return the sum of the number of calories carried by the top three
+ // elves carrying the most calories
+ public int solvePartTwo() {
+ return this.elves.get(0).totalCalories
+ + this.elves.get(1).totalCalories
+ + this.elves.get(2).totalCalories;
+ }
+}
+
diff --git a/file-operations/aoc-day1/input.txt b/aoc-day1/better/input.txt
diff --git a/aoc-day1/worse/Main.java b/aoc-day1/worse/Main.java
@@ -0,0 +1,28 @@
+// Using the Advent of Code 2022 Day 1 challenge as a practical example for
+// reading and writing to a file.
+
+import java.util.Scanner;
+
+public class Main {
+ public static void main(String[] args) {
+ System.out.println("Advent of Code 2022, Day 1");
+
+ Scanner sc = new Scanner(System.in);
+ System.out.print("File containing input data: ");
+ String fileName = sc.nextLine();
+
+ Solver solver = new Solver(fileName);
+
+ int result = solver.solvePartOne();
+ long startTime = System.nanoTime();
+ System.out.println("Part One: " + result);
+ long endTime = System.nanoTime();
+ System.out.println("Took: " + Long.toString((endTime - startTime) / 1000) + " microseconds");
+
+ result = solver.solvePartTwo();
+ startTime = System.nanoTime();
+ System.out.println("Part Two: " + result);
+ endTime = System.nanoTime();
+ System.out.println("Took: " + Long.toString((endTime - startTime) / 1000) + " microseconds");
+ }
+};
diff --git a/aoc-day1/worse/README b/aoc-day1/worse/README
@@ -0,0 +1,3 @@
+This solution is not that great. It works, but it's also pretty much a copy of
+my solution written in C. Check the aoc-day1/better directory for a more
+"Java-like" solution.
diff --git a/aoc-day1/worse/Solver.java b/aoc-day1/worse/Solver.java
@@ -0,0 +1,75 @@
+import java.util.Scanner;
+import java.io.*;
+
+public class Solver {
+ private String fileName;
+
+ public Solver(String fn) {
+ fileName = fn;
+ }
+
+ private Scanner openFile() {
+ try {
+ File file = new File(this.fileName);
+ Scanner sc = new Scanner(file);
+ return sc;
+ }
+ catch (FileNotFoundException e) {
+ System.err.println("File " + this.fileName + " not found!");
+ System.exit(1);
+ }
+ return null;
+ }
+
+ // This feels sloppy
+ private void arrayInsert(int[] array, int index, int value) {
+ for (int i = 2; i > index; i--) {
+ array[i] = array[i-1];
+ }
+ array[index] = value;
+ }
+
+ // Find the elf carrying the most calories
+ public int solvePartOne() {
+ Scanner fileReader = openFile();
+ int mostCalories = 0;
+ int currentCalories = 0;
+ while (fileReader.hasNextLine()) {
+ String line = fileReader.nextLine();
+ if (line.isEmpty()) {
+ if (currentCalories > mostCalories) {
+ mostCalories = currentCalories;
+ }
+ currentCalories = 0;
+ continue;
+ }
+ currentCalories += Integer.parseInt(line);
+ }
+ fileReader.close();
+ return mostCalories;
+ }
+
+ // Find the top three elves carrying the most calories
+ public int solvePartTwo() {
+ Scanner fileReader = openFile();
+ int[] bestThree = { 0, 0, 0 };
+ int currentCalories = 0;
+ while (fileReader.hasNextLine()) {
+ String line = fileReader.nextLine();
+ if (line.isEmpty()) {
+ for (int i = 0; i < 3; i++) {
+ if (currentCalories > bestThree[i]) {
+ this.arrayInsert(bestThree, i, currentCalories);
+ break;
+ }
+ }
+ currentCalories = 0;
+ continue;
+ }
+ currentCalories += Integer.parseInt(line);
+ }
+ fileReader.close();
+ return bestThree[0] + bestThree[1] + bestThree[2];
+ }
+}
+
diff --git a/file-operations/aoc-day1/input.txt b/aoc-day1/worse/input.txt
diff --git a/file-operations/aoc-day1/Main.java b/file-operations/aoc-day1/Main.java
@@ -1,22 +0,0 @@
-// Using the Advent of Code 2022 Day 1 challenge as a practical example for
-// reading and writing to a file.
-
-import java.util.Scanner;
-
-public class Main {
- public static void main(String[] args) {
- System.out.println("Advent of Code 2022, Day 1");
-
- Scanner sc = new Scanner(System.in);
- System.out.print("File containing input data: ");
- String fileName = sc.nextLine();
-
- Solver solver = new Solver(fileName);
-
- int result = solver.solvePartOne();
- System.out.println("Part One: " + result);
-
- result = solver.solvePartTwo();
- System.out.println("Part Two: " + result);
- }
-};
diff --git a/file-operations/aoc-day1/Solver.java b/file-operations/aoc-day1/Solver.java
@@ -1,76 +0,0 @@
-import java.util.Scanner;
-import java.io.*;
-
-public class Solver {
- String fileName;
-
- public Solver(String fn) {
- fileName = fn;
- }
-
- private Scanner openFile() {
- try {
- System.out.println("Opening " + this.fileName + "...");
- File file = new File(this.fileName);
- Scanner sc = new Scanner(file);
- return sc;
- }
- catch (FileNotFoundException e) {
- System.err.println("File " + this.fileName + " not found!");
- System.exit(1);
- }
- return null;
- }
-
- // This feels sloppy
- private void arrayInsert(int[] array, int index, int value) {
- for (int i = 2; i > index; i--) {
- array[i] = array[i-1];
- }
- array[index] = value;
- }
-
- // Find the elf carrying the most calories
- public int solvePartOne() {
- Scanner fileReader = openFile();
- int mostCalories = 0;
- int currentCalories = 0;
- while (fileReader.hasNextLine()) {
- String line = fileReader.nextLine();
- if (line.isEmpty()) {
- if (currentCalories > mostCalories) {
- mostCalories = currentCalories;
- }
- currentCalories = 0;
- continue;
- }
- currentCalories += Integer.parseInt(line);
- }
- fileReader.close();
- return mostCalories;
- }
-
- // Find the top three elves carrying the most calories
- public int solvePartTwo() {
- Scanner fileReader = openFile();
- int[] bestThree = { 0, 0, 0 };
- int currentCalories = 0;
- while (fileReader.hasNextLine()) {
- String line = fileReader.nextLine();
- if (line.isEmpty()) {
- for (int i = 0; i < 3; i++) {
- if (currentCalories > bestThree[i]) {
- this.arrayInsert(bestThree, i, currentCalories);
- break;
- }
- }
- currentCalories = 0;
- continue;
- }
- currentCalories += Integer.parseInt(line);
- }
- fileReader.close();
- return bestThree[0] + bestThree[1] + bestThree[2];
- }
-}
-