Advent of Code has begun! I'll be completing this year's coding challenges using Apex.
--- Day 1: Trebuchet?! ---
Let's dive into Day 1's challenge part 1. Setting up a reusable LWC Puzzle Input File Reader. And with Apex, I'll tackle the first part of the puzzle.
https://adventofcode.com/2023/day/1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<lightning-card title="Puzzle File Reader"> | |
<div class="slds-p-around_medium"> | |
<lightning-input type="file" label="Select File" onchange={handlePuzzleInputChange}></lightning-input> | |
{puzzleInputFileName} | |
<div class="slds-p-top_small"> | |
<lightning-button label="Read Puzzle Input" onclick={uploadPuzzleInput} disabled={disabled}></lightning-button> | |
</div> | |
</div> | |
</lightning-card> | |
<lightning-card title="Puzzle Result"> | |
<div class="slds-p-around_medium"> | |
Answer: {puzzleAnswer} | |
</div> | |
</lightning-card> | |
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { LightningElement } from 'lwc'; | |
import readPuzzleInput from '@salesforce/apex/Advent.readPuzzleInput'; | |
export default class AdventofCode_FileReader extends LightningElement { | |
puzzleInput; | |
puzzleInputFileName; | |
puzzleAnswer; | |
handlePuzzleInputChange(event) { | |
this.puzzleInput = event.target.files[0]; | |
this.puzzleInputFileName = event.target.files[0].name; | |
} | |
get disabled() { | |
return this.puzzleInput ? false : true; | |
} | |
uploadPuzzleInput() { | |
if (this.puzzleInput) { | |
const reader = new FileReader(); | |
reader.onload = () => { | |
const fileContent = reader.result; | |
// process the puzzle input | |
readPuzzleInput({ fileName: this.puzzleInput.name, fileContent }) | |
.then(result => { | |
// Handle success | |
console.log('File uploaded successfully:', result); | |
this.puzzleAnswer = result; | |
}) | |
.catch(error => { | |
// Handle error | |
console.error('Error uploading file:', error); | |
}); | |
}; | |
reader.readAsText(this.puzzleInput); | |
} | |
} | |
} |
Reusable Puzzle Input Apex File Reader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public with sharing class Advent { | |
@AuraEnabled | |
public static Integer readPuzzleInput(String fileName, String fileContent) { | |
return read_lines(fileContent); | |
} | |
public static Integer read_lines(String puzzleInput) { | |
// Split by newline chars | |
List<String> lines = puzzleInput.split('\n'); | |
// call puzzle solution | |
return day01.part1(lines); | |
} | |
} |
Day 01 Solution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public with sharing class day01 { | |
public static Map<String,String> numberMap = new Map<String,String>{ | |
'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' | |
}; | |
public static Integer part1(List<String> puzzleInputLines) { | |
System.debug(puzzleInputLines); | |
Integer total = 0; | |
for(String line : puzzleInputLines) { | |
System.debug(line); | |
String first = firstMatch(line); | |
String last = lastMatch(line); | |
String fullMatch = first + last; | |
total += Integer.valueOf(fullMatch); | |
} | |
return total; | |
} | |
public static String firstMatch(String line) { | |
String returnVal; | |
// Iterate through each character in the line (first match) | |
for (Integer i = 0; i < line.length(); i++) { | |
// Get the character at the current index | |
String currentChar = line.substring(i, i + 1); | |
if(numberMap.get(currentChar) != null) { | |
returnVal = numberMap.get(currentChar); | |
break; | |
} | |
} | |
return returnVal; | |
} | |
public static String lastMatch(String line) { | |
String returnVal; | |
// Iterate through each character in the line in reverse order (last match) | |
for (Integer i = line.length() - 1; i >= 0; i--) { | |
// Get the character at the current index | |
String currentChar = line.substring(i, i + 1); | |
if(numberMap.get(currentChar) != null) { | |
returnVal = numberMap.get(currentChar); | |
break; | |
} | |
} | |
return returnVal; | |
} | |
} |
Day 01 - Part 1 complete!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public with sharing class day01 { | |
public static Map<String,String> numberMap = new Map<String,String>{ | |
'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' | |
}; | |
public static Integer part2(List<String> puzzleInputLines) { | |
System.debug(puzzleInputLines); | |
Integer total = 0; | |
for(String line : puzzleInputLines) { | |
System.debug(line); | |
String fullMatch = matchIncludingSpelledOutNumbers(line); | |
total += Integer.valueOf(fullMatch); | |
} | |
return total; | |
} | |
public static String matchIncludingSpelledOutNumbers(String line) { | |
List<String> returnVal = new List<String>(); | |
// Iterate through each character in the line (first match) | |
for (Integer i = 0; i < line.length(); i++) { | |
// Get the character string at the current index to the end | |
String currentChars = line.substring(i, line.length()); | |
for(String numKey : numberMap.keySet()) { | |
// check if starts with matches a key in the spelled out number map | |
if(currentChars.startsWith(numKey)) { | |
returnVal.add(numberMap.get(numKey)); | |
} | |
} | |
} | |
return returnVal[0] + returnVal[returnVal.size() - 1]; | |
} | |
} |
Day 01 - Part 2 complete!
Thanks for sharing, its helpful. I think we can use String.reverse() to use the firstMatch(). This way we may not need lastMatch(). Is my understanding correct ? I have not tried myself but will check on weekend.
ReplyDelete