Overview
After my post last night, @aspittel suggested that we start a daily discussion post chain for these challenges. I think that's a neat idea, and significantly more efficient than everyone saying "Hey check out my git repo!"
I'm excited about this year's Advent mission, time traveling to save Christmas! This will be a place for discussing today's problem, Chronal Calibration. We're tasked with calibrating our time travel device by adding up sequential integers.
On a side note, if you get some extra time, it's probably a good idea to set up some infrastructure for reading input text from a file, because almost all of last year's challenges gave a few simpler examples (good for writing some basic tests) and then a huge-ish input given as a multiline plaintext file.
If you haven't solved today's puzzle yet, stop reading now, because I'm going to post my solution here. If you have finished a solution, post it in the comments! Also feel free to give (loving, instructional, nice) feedback to others' solutions to help them read better or run faster. I've seen a few people that are using this opportunity to learn a new language, so if you see something that works but isn't idiomatic to your favorite language, go ahead and offer suggestions! This includes me, since I'm just learning Rust, so I'm sure it's going to be a mixture of poorly translated Python-isms and gobbledygook.
My Solution
// day1.rs
/// Given a bunch of integers (changes in frequency), one per line,
/// calculate the final sum
pub fn final_frequency(text: &str) -> i32 {
text.lines()
.map(|value: &str| -> i32 {value.parse().expect("Not a number")})
.sum()
}
/// Given a bunch of integers (changes in frequency), one per line,
/// calculate the running sum until you hit a cumulative sum that you've
/// seen before. Return that first repeated cumulative sum.
pub fn first_duplicate_frequency(text: &str) -> i32 {
let mut history = vec![0];
let mut total = 0;
for line in text.lines().cycle() {
let value: i32 = line.parse().expect("Not a number.");
total += value;
if history.contains(&total) {
return total;
}
history.push(total);
}
return 0;
}
#[cfg(test)]
mod tests {
use super::final_frequency;
use super::first_duplicate_frequency;
#[test]
fn final_all_positives() {
assert_eq!(3, final_frequency("+1\n+1\n+1"));
}
// More tests...
// main.rs
// This file will change day to day as I just use it to exercise each day's module.
use std::fs::File;
use std::io::prelude::*;
mod day1;
fn main() {
let mut input = File::open("data/day1.txt").expect("File not found.");
let mut contents = String::new();
input.read_to_string(&mut contents).expect("Couldn't read file.");
println!("{}", day1::first_duplicate_frequency(&contents));
}
DEV Leaderboards
Lastly, I created a "private" leaderboard for DEV.to, in case anyone's interested. Apparently, they only hold 200 people per leaderboard, though, so first-come-first serve. Obviously, there are waaaay more than 200 people in the DEV family, so if you get there and the room is full, feel free to create your own on the Advent of Code site and post your room code in the comments. If I see somebody post a room code, I'll do my best to edit my post and copy it below, but read through the comments just in case I miss it.
Happy-- I mean, Merry Coding! I'm excited to see what people think.
@rpalo: 224198-25048a19
Latest comments (73)
Pt 2 JS/Node Solution:
Hi Ryan.. Just starting on the #adventofcode series.
Just curious how you are reading the inputs. E.g. first problem says the input is on adventofcode.com/2018/day/1/input
Do you parse the page to get the inputs?
Or copy/paste and store it as a file? Sorry if this sounds dumb.. But am wondering how you are downloading the file?
Thanks
No problem! That would be slick to have it download the page for me, but I just go to the link and copy the text. I've got a directory in my project called
data
, and each day's input asday1.txt
,day2.txt
, etc. Then I just change the filename that I'm reading.Let me know if this helps or if you have other questions :)
Thanks. The data folder makes sense.
A little late to starting on this, but I am excited to get going!
JS
Part 1 (A little bit trolly)
Part 2 (could probably use some optimizations)
This seemed easiest to do in
awk
:Part 1
Part 2
awk
's arrays are basically hashes/associative arrays, so you can just use the frequencies as keys much like the Python dictionary solutions. Becauseawk
is really focused on processing a list of files, this uses a hack on the built-in variable that tracks where on that listawk
has gotten to, so it only stops once it's found the duplicate.I just wanted to confess that Day 1 Part 1 I just used a spreadsheet. That got the answer, but then I used my program to proceed.
Honestly, you could argue that Excel is a highly parallel GUI-based programming tool. I’d say that’s fair. 😀
C#
Part 1
Part 2
Hmm... I just took the input and stuck it in an array rather than reading it from disk. That's not hard to do in Swift though, maybe I'll go back and add in the file loading.
In any case, here is what I did in my Playground!
Swift
Part 1
This one was super easy in Swift via it's
reduce(_:_:)
function. Given that I had theInts
in anArray
, it was a one liner. I added some context to the output because why not?For those of you new to Swift, this version of
reduce
has two inputs. The first one is the starting value for the accumulator and the second is the closure of what to do with the values from the collection. This is simply a shorthand syntax for adding all the values in a collection together and returning it. The long version looks like this:Part 2
This part was a bit tougher and my first attempt had all kinds of bad smells like breaking to function labels and such. Eventually I wrapped it all up in a closure that takes an
Array
ofInt
values and then returns a singleInt
with the first repeated number.Essentially this is a for-loop version of the
reduce
operation, but then I also maintain a history of the values in aSet
and check to see if this is a value we've run into before.I solved the second one with a closure instead of a regular function because I've been teaching myself more about them lately.
Thanks! The explanations are really interesting too!
Clojure:
(
utils/read-file
just slurps and splits by newlines)Part 1:
Part 2:
Three different PHP solutions - two of them code-golfed: particleflux.codes/post/2018/adven...
TLDR:
I'm enjoying reading everyone's solutions. After doing last year's in Haskell I'm using Kotlin to try to improve my knowledge of the language and libraries. I'm also avoiding using an IDE, as auto-suggest and magic building don't teach you what's really going on under the hood.
I know the idea is to avoid everyone's github but I'm writing notes on my solutions at github.com/neilgall/adventofcode2018
Hi there!
I've used Javascript.
Here's my part one solution:
I just read the input from file, parsed to a int array and used the
reduce
function.Talking about the second part, I've user a dictionary to store frequencies and retrieve them quickly (access is O(1)), cycling in a circular manner through the provided diffs:
I'm planning to do this in Go too, since I'd love to practice this language, but I haven't much time for now :(
I'm doing this in C++ this year, but as we are proposing original solutions with very expressive languages, I'll show a solution in OCaml :)
OCaml
Part 1
Part 2
Using lists is not very efficient but the code is quite short, that is nice.
1.1
A bit overcomplicated. Didn't know parseInt parses signs too 😅
1.2
The first result is the solution, not quite sure why it prints so many other results after that even if I set matchFound = true though 🤔
Thanks for this Ryan! I've joined the leaderboard. Good luck to everyone!
Here's my solution in Crystal, both parts are included as one class:
There are also tests here.
Super cool idea! Just joined the private leaderboard!