Git Product home page Git Product logo

cargo-aoc's Introduction

Cargo Advent of Code Helper

cargo-aoc is a simple CLI tool that aims to be a helper for the Advent of Code.

Implement your solution. Let us handle the rest.

Features

  • Input downloading
  • Running your solution
  • Automatic benchmarking of your solution using Criterion

Getting started

Install cargo aoc

cargo-aoc is hosted as a binary on crates.io. Boot a terminal and install the program using cargo install cargo-aoc

If you installed cargo-aoc in a previous year, it may be out of date now and this will cause build errors because of a version mismatch if you use the latest version of the aoc-runner and aoc-runner-derive below. If that's the case, then update it with cargo install cargo-aoc --force.

Setting up the CLI

You will need to find your session token for the AoC in order for cargo-aoc to work. Thankfully, finding your token is easy since it is stored in your Browser's cookies. Open up the devtools of your browser, and then :

  • Firefox: "Storage" tab, Cookies, and copy the "Value" field of the session cookie.
  • Google Chrome / Chromium: "Application" tab, Cookies, and copy the "Value" field of the session cookie.

Once you have it, simply run : cargo aoc credentials -s {token}

You're now ready to start coding !

NOTE: If for some reason your token has changed, dont forget to change it back.

cargo aoc credentials will show the currently stored user token

Setting up the project

In order for cargo-aoc to work properly, you have to set the project up correctly.

If you get lost during the process, you can take this example repository of AoC 2015 as a template.

First, you must add a dependency on aoc-runner and aoc-runner-derive in your Cargo.toml. At the end of the src/lib.rs, you will have to use the macro aoc_lib!{ year = XXXX }, where XXXX is the year of the AoC puzzles being solved.

When implementing a solution for a day, you have to provide functions and tag them accordingly. A function is either a solver or a generator.

Those two types of functions are being executed and benchmarked seperately. Lets have a closer look :

Generator functions

Generators allows you to provide a custom type to the solver functions. Sometimes in AoC, you have to parse an input and extract a logical structure out of it, before you can actually solve the problem.

Generator functions are tagged #[aoc_generator(dayX)].

Because examples are worth a thousand words, lets take a look at Year 2015, Day 2 :

From the puzzle's description, we know that [we] have a list of the dimensions (length l, width w, and height h) of each present, each present on one line, represented like so: {L}x{W}x{H}.

We might want to first parse the input and extract logical Gift structs out of it, like:

pub struct Gift {
    l: u32,
    w: u32,
    h: u32
}

In @Gobanos' reference implementation, we can see that he instead chose to settle for a custom type : type Gift = (u32, u32, u32);.

Thus, writing a generator for Gifts is fairly simple:

#[aoc_generator(day2)]
pub fn input_generator(input: &str) -> Vec<Gift> {
    input
        .lines()
        .map(|l| {
            let mut gift = l.trim().split('x').map(|d| d.parse().unwrap());
            (
                gift.next().unwrap(),
                gift.next().unwrap(),
                gift.next().unwrap(),
            )
        }).collect()
}

As you can see, generators take a &str (or a &[u8]) type as an input, and outputs any type that you want, so you can then use it in solver functions.

link to doc

Solver functions

Solver functions are typically your algorithms, they take any input type provided by a generator, and return any type that you want to use, provided that it implements the Display trait.

Solver functions are tagged #[aoc(day2, part1)]. Optionally, you can have multiple implementation for the same part of a day. You must then use a name to tag them correctly, for example : #[aoc(day2, part1, for_loop)].

Following with the previous example, implementing a solver for the part one could be done like this :

#[aoc(day2, part1)]
pub fn solve_part1(input: &[Gift]) -> u32 {
    input
        .iter()
        .map(|&(l, w, h)| {
            let (s1, s2) = smallest_side((l, w, h));
            2 * l * w + 2 * w * h + 2 * h * l + s1 * s2
        })
        .sum()
}

Notice how we're taking the Gifts generated previously, and using Rust's iterators to solve the problem efficiently, all the while keeping the code maintainable.

The output of this particular solver is an u32, which of course implements Display. When running your solution using cargo aoc, said result will then get printed in the console, along with other informations about execution time.

link to doc

Downloading your input manually

cargo aoc input will download an input and store it in input/{year}/day_{day}.txt.

Please note that by default, we're taking today's date as the argument. Of course, you can change this using : cargo aoc input -d {day} -y {year}

Running your solution

cargo aoc will run the latest implemented day, downloading your input beforehand. It will show you the result, and a short summary of how well it did perform.

Example output on my Chromebook, running @Gobanos' AOC2015 :

[olivier@olivier-pc advent-of-code-2015]$ cargo aoc
    Finished dev [unoptimized + debuginfo] target(s) in 0.12s
   Compiling aoc-autobuild v0.1.0 (/home/olivier/Workspace/Rust/advent-of-code-2015/target/aoc/aoc-autobuild)
    Finished release [optimized] target(s) in 0.87s
     Running `target/release/aoc-autobuild`
AOC 2015
Day 5 - Part 1 : 238
        generator: 18.122µs,
        runner: 420.958µs

Day 5 - Part 2 : 69
        generator: 5.499µs,
        runner: 1.142373ms

If you want to run an older puzzle, or only a specific part, specify those using cargo aoc -d {day} -p {part}.

Benchmarking your solution

Benchmarking is powered by Criterion. Use cargo aoc bench to launch the benchmarks, just like you would use cargo aoc.

Benchmarks for each days are then generated in target/aoc/aoc-autobench/target/criterion.

You can open the benchmark automatically in your Browser afterwards, using cargo aoc bench -o

Soon(tm), you will also be able to use our (free) online platform, to compare your results with those of the community.


Happy Advent of Code !

cargo-aoc's People

Contributors

aliscode avatar darthgandalf avatar erjanmx avatar flyingfox avatar gobanos avatar havvy avatar jcgruenhage avatar michaelmelanson avatar petreeftime avatar samueltardieu avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.