Back to blog

Unlocking the global snow production:Advent Calendar Coding Challenge 2023

Unlocking the global snow production:Advent Calendar Coding Challenge 2023

Day 1: Trebuchet to the Rescue!

The Quest Begins

Imagine waking up to an elfin commotion, only to be told that global snow production is in jeopardy! That's how my Advent Calendar coding adventure began. Elves, maps with stars, and a mission to restore snow operations by checking fifty stars before Christmas - talk about a seasonal challenge!

The Puzzling Plunge

As I was trying to wrap my head around weather machines and sky-bound operations, I found myself strapped into a... trebuchet?! Yes, you read that right. My journey to solving these puzzles was literally launching off with a bang!

The Calibration Conundrum

The Elves handed me a calibration document, essential for my task. But there was a twist - a young Elf's artistic expression had turned the document into a cryptic canvas. My mission? To decipher calibration values hidden in lines of text.

The Puzzle

Each line in the document had a unique calibration value, found by combining the first and last digits. Sounds simple, right? Well, not quite. Here's where I had to put my coding skills to the test.

The first and last digits were hidden in the text, and I had to find them. The first digit was the first digit in the line, and the last digit was the last digit in the line. I had to find the first and last digits, combine them, and add them to the total sum.

Example

two1nine eightwothree abcone2threexyz xtwone3four 4nineeightseven2 zoneight234 7pqrstsixteen

Javascript Solution

console.time("Execution Time"); const fs = require('fs'); fs.readFile('calibration-list.txt', 'utf8', (err, data) => { if (err) { console.error("Error reading the file:", err); return; } const lines = data.split('\n'); // Split the file content into lines let totalSum = 0; lines.forEach(line => { const firstDigit = line.match(/\d/); // Find the first digit const lastDigit = line.match(/\d(?=[^\d]*$)/); // Find the last digit if (firstDigit && lastDigit) { const calibrationValue = parseInt(firstDigit[0] + lastDigit[0], 10); totalSum += calibrationValue; } }); console.log("Total sum of calibration values:", totalSum); }); console.timeEnd("Execution Time");
Execution Time: 4.531ms Total sum of calibration values: 56108

Python Solution

import time start_time = time.perf_counter() with open('calibration-list.txt', 'r') as file: lines = file.readlines() total_sum = 0 for line in lines: line = line.strip() # Remove any leading/trailing whitespace or newlines first_digit = next((char for char in line if char.isdigit()), None) last_digit = next((char for char in reversed(line) if char.isdigit()), None) if first_digit and last_digit: calibration_value = int(first_digit + last_digit) total_sum += calibration_value print("Total sum of calibration values:", total_sum) end_time = time.perf_counter() execution_time_ms = (end_time - start_time) * 1000 # Convert to milliseconds print(f"Execution Time: {execution_time_ms:.3f} ms")
Total sum of calibration values: 56108 Execution Time: 3.134 ms

GO Solution

package main import ( "bufio" "fmt" "os" "regexp" "strconv" "time" "unicode" ) func main() { startTime := time.Now() file, err := os.Open("calibration-list.txt") if err != nil { fmt.Println("Error opening the file:", err) return } defer file.Close() scanner := bufio.NewScanner(file) var totalSum int for scanner.Scan() { line := scanner.Text() // Find the first digit firstDigit := regexp.MustCompile(`\d`).FindString(line) // Manually find the last digit by iterating over the string from the end var lastDigit string for i := len(line) - 1; i >= 0; i-- { if unicode.IsDigit(rune(line[i])) { lastDigit = string(line[i]) break } } if firstDigit != "" && lastDigit != "" { calibrationValue, err := strconv.Atoi(firstDigit + lastDigit) if err != nil { fmt.Println("Error converting string to integer:", err) continue } // fmt.Printf("Line: %s, Value: %d\n", line, calibrationValue) // Debug print totalSum += calibrationValue } } if err := scanner.Err(); err != nil { fmt.Println("Error reading the file:", err) return } fmt.Println("Total sum of calibration values:", totalSum) endTime := time.Since(startTime) fmt.Printf("Execution Time: %s\n", endTime) }
Total sum of calibration values: 56108 Execution Time: 1.824143ms

The Twist: A Spelled-Out Challenge

Just when I thought I had it all figured out, the Elves threw in another curveball. Some digits were spelled out! This meant revisiting each line, deciphering the real first and last digits, and recalculating.

The Puzzle, Part Two

Armed with this new information, I dove back into the puzzle. Words like "one", "two", "three", etc., were now part of my digit-detective work.

Javascript Solution

console.time("Execution Time"); const fs = require('fs'); function findDigit(str, spelledNumbers, isReversed) { let text = ''; for (let char of str) { text = isReversed ? char + text : text + char; const index = spelledNumbers.findIndex(spelledNum => text.includes(spelledNum)); if (index > -1) return index + 1; if (!isNaN(char)) return parseInt(char); } return -1; } const fileContent = fs.readFileSync("calibration-list.txt", "utf-8"); const spelledNumbers = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]; const totalSum = fileContent.split("\n").map(line => { const firstDigit = findDigit(line, spelledNumbers, false); const lastDigit = findDigit([...line].reverse().join(''), spelledNumbers, true); return firstDigit * 10 + lastDigit; }).reduce((total, value) => total + value, 0); console.log("Total sum of calibration values:", totalSum); console.timeEnd("Execution Time");
Total sum of calibration values: 55652 Execution Time: 21.607ms

Python Solution

import re import time start_time = time.perf_counter() with open('calibration-list.txt', 'r') as f: lines = f.read().split('\n') def adventDayOne(lines): values = {'one': '1', 'two': '2', 'three': '3', 'four': '4', 'five': '5', 'six': '6', 'seven': '7', 'eight': '8', 'nine': '9'} total = 0 for line in lines: nums = re.findall(r'(?=([0-9]|one|two|three|four|five|six|seven|eight|nine))', line) first = values.get(nums[0], nums[0]) last = values.get(nums[-1], nums[-1]) total += int(first + last) return total print(adventDayOne(lines)) end_time = time.perf_counter() execution_time_ms = (end_time - start_time) * 1000 # Convert to milliseconds print(f"Execution Time: {execution_time_ms:.3f} ms")
Total sum of calibration values: 55652 Execution Time: 4.171 ms

Reflections and Revelations

It was a journey filled with surprises, learning, and a dash of elfin magic. Stay tuned for more tales and puzzles as my Advent Calendar coding adventure continues!

It was a fun challenge to solve, and I'm looking forward to the next one! If you want to try it yourself, you can find the challenge here. It was the first time using GO, and I'm impressed with the performance. I'm looking forward to learning more about it.