Giter Club home page Giter Club 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

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 {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 dev-ardi avatar erjanmx avatar flyingfox avatar gobanos avatar jcgruenhage avatar petreeftime avatar samueltardieu avatar sof3 avatar williammartin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

cargo-aoc's Issues

Support for running in Debug mode

cargo-aoc's autobuild currently compiles the project using cargo run --release.

While this is a cool feature and allows for faster code execution, building in release-mode means we're removing the debug symbols, thus preventing an user to use a debugger such as LLDB or gdb.

I think a --debug option in the default cargo aoc command is necessary, and would allow the use of a debugger.

Any objection ? Otherwise, I'll implement this and post a PR during the Weekend.

Allow generator to get untrimmed input

Hi.

My input for day 13 must not be trimmed as it starts with significant spaces at the beginning of the first line. Is there a way to indicate that the input should not be trimmed for a particular problem?

the trait `std::borrow::Borrow<day10::Chart>` is not implemented for `aoc_runner::ArcStr`

I can't seem to shake this compiler error when working on day10, part2

   Compiling advent_of_code_2019 v0.1.0 (/var/home/masond/rust/aoc)
error[E0277]: the trait bound `aoc_runner::ArcStr: std::borrow::Borrow<day10::Chart>` is not satisfied
  --> src/day10.rs:56:1
   |
56 | #[aoc(day10, part2)]
   | ^^^^^^^^^^^^^^^^^^^^ the trait `std::borrow::Borrow<day10::Chart>` is not implemented for `aoc_runner::ArcStr`
   |
   = help: the following implementations were found:
             <aoc_runner::ArcStr as std::borrow::Borrow<[u8]>>
             <aoc_runner::ArcStr as std::borrow::Borrow<std::sync::Arc<str>>>
             <aoc_runner::ArcStr as std::borrow::Borrow<str>>

My function definitions very similar for both parts1 and 2 but only part2 shows the above problem:

#[aoc(day10, part1)]
fn solve_part1(chart: &Chart) -> Answer {
#[aoc(day10, part2)]
fn solve_part2(chart: &Chart) -> Answer {

#19 looks related but instead of AsRef not being implemented now Borrow is not implemented.

Aaaaand I've now realised what I was missing, but I'll share in case it helps others (sorry in advance for the issue spam)

My generator targeted part1 and since both parts used the same struct, Chart, I didn't make a new generator for part2. The fix was to make the generator run for both parts:

#[aoc_generator(day10, part1)] -> #[aoc_generator(day10)]

Cut a release?

Would it be possible to cut a 0.3 release with the current code? Nobody would be forced to upgrade if you think it is not ready, but some of us would really love to use more advanced features (such as the ability to select an alternate input) more easily.

Unexpected type argument?

First, thanks for making this. I've found it very helpful.

Second, starting with day 8, I'm getting an error I don't know how to solve. It is probably user error.

I'm extremely new to rust (using AoC as an excuse/reason to try it out and learn), so it could be something incredibly stupid on my part, but I can't see any difference between my usage of #[aoc(day7, part1)] yesterday (which runs fine) and my usage of #[aoc(day8, part1)] for today (day 8).

If I comment out the aoc decorators, my day 8 part 1 test runs successfully (with some warnings about unused functions).

My code is visible here: https://github.com/WGriffing/advent-of-code/blob/master/2020/src/day08.rs (I'm sure it's not great, but that's a separate issue).

    Checking aoc2020 v0.1.0 (/path/to/advent-of-code/2020)
error[E0107]: wrong number of type arguments: expected 0, found 2
  --> src/day08.rs:35:1
   |
35 | #[aoc(day8, part1)]
   | ^^^^^^^^^^^^^^^^^^^
   | |
   | unexpected type argument
   | unexpected type argument
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0107`.
error: could not compile `aoc2020`

To learn more, run the command again with --verbose.
An error occurs : cargo build failed with code 101

Any idea what I'm doing wrong here?

Consider using Borrow instead of AsRef

I'm still not entirely certain when to use Borrow and when to use AsRef, but it appears that there's a blank impl Borrow<T> for T but there's no equivalent blanket impl for AsRef.

The motivation here is being able to write something like

struct Graph {}

#[aoc_generator(day2)]
fn input_generator(input: &str) -> Graph {}

#[aoc(day2, part1)]
fn part1(input: &Graph) -> usize {}

Since cargo-aoc uses AsRef, this doesn't work as there's no impl AsRef<Graph> for Graph. If it used Borrow then the blanket impl would make this work.

This would not be a backwards-compatible change, as there exists AsRef impls that convert between str and [u8] but there's no equivalent Borrow impl. That said, it seems unexpected that someone would have a generator that produces e.g. a String and a corresponding solver that expects a &[u8].

Input is stripping leading whitespace

I'm running into issues with day13 and it appears that the input that cargo-aoc is giving me is stripping all leading whitespace from the first line. The actual first line of my input/2018/day13.txt file is

                    /--------------------------------------------------\                                        /----------------\                    

but the line that cargo-aoc is giving me as input is

/--------------------------------------------------\                                        /----------------\                    

An error occurs : No matching day & part found

Cargo.toml

[package]
name = "aoc2020"
version = "0.1.0"
authors = ["Brady Dean <[email protected]>"]
edition = "2018"

[dependencies]
aoc-runner = "0.3.0"
aoc-runner-derive = "0.3.0"
itertools = "0.9.0"

lib.rs

pub mod day1;
aoc_runner_derive::aoc_lib!{ year = 2020 }

src/day1.rs

use aoc_runner_derive::aoc;
use aoc_runner_derive::aoc_generator;

use itertools::Itertools;

#[aoc_generator(day1)]
pub fn input_generator(input: &str) -> Vec<u32> {
    //...
}

#[aoc(day1, part1)]
pub fn solve_part1(input: &[u32]) -> Option<u32> {
    //...
}

From the command line:

PS E:\Projects\aoc2020> cargo aoc -d 1 -p 1
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
An error occurs : No matching day & part found

use_after_free issue with nightly

I believe my solution for day 1 is correct here, but I'm seeing the following when cargo runing

$ cargo run
   Compiling advent-of-code-2018 v0.1.0 (/Users/danno/code/advent-of-code-2018)
thread 'main' panicked at 'use-after-free in `proc_macro` handle', src/libcore/option.rs:1008:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: custom attribute panicked
 --> src/day_1.rs:8:1
  |
8 | #[aoc(day1, part1)]
  | ^^^^^^^^^^^^^^^^^^^
  |
  = help: message: use-after-free in `proc_macro` handle

error: aborting due to previous error

error: Could not compile `advent-of-code-2018`.

To learn more, run the command again with --verbose.

Here's the BT:

$ RUST_BACKTRACE=1 cargo run
   Compiling advent-of-code-2018 v0.1.0 (/Users/danno/code/advent-of-code-2018)
thread 'main' panicked at 'use-after-free in `proc_macro` handle', src/libcore/option.rs:1008:5
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::_print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
   6: std::panicking::continue_panic_fmt
   7: rust_begin_unwind
   8: core::panicking::panic_fmt
   9: core::option::expect_failed
  10: <proc_macro::bridge::TokenTree<G, P, I, L> as proc_macro::bridge::rpc::DecodeMut<'a, '_, S>>::decode
  11: std::panicking::try::do_call
  12: __rust_maybe_catch_panic
  13: <proc_macro::bridge::server::Dispatcher<proc_macro::bridge::server::MarkedTypes<S>> as proc_macro::bridge::server::DispatcherTrait>::dispatch
  14: <proc_macro::bridge::closure::Closure<'a, A, R> as core::convert::From<&'a mut F>>::from::call
  15: <proc_macro::bridge::closure::Closure<'a, A, R> as core::convert::From<&'a mut F>>::from::call
  16: proc_macro::diagnostic::Diagnostic::emit::to_internal
             at src/libproc_macro/bridge/closure.rs:40
             at src/libproc_macro/bridge/client.rs:243
             at src/libproc_macro/bridge/client.rs:327
             at src/libproc_macro/bridge/client.rs:292
             at src/libproc_macro/bridge/scoped_cell.rs:83
             at src/libproc_macro/bridge/client.rs:290
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libstd/thread/local.rs:309
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libstd/thread/local.rs:255
             at src/libproc_macro/bridge/client.rs:289
             at src/libproc_macro/bridge/client.rs:320
             at src/libproc_macro/bridge/client.rs:236
             at src/libproc_macro/lib.rs:148
  17: core::clone::impls::<impl core::clone::Clone for usize>::clone
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libcore/convert.rs:455
  18: proc_macro2::imp::nightly_works::{{closure}}
             at /Users/danno/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.24/src/unstable.rs:179
  19: <proc_macro::TokenStream as core::clone::Clone>::clone
             at /Users/danno/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.24/src/unstable.rs:248
  20: <proc_macro::TokenStream as core::clone::Clone>::clone
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libcore/ops/function.rs:286
  21: <core::str::Bytes<'_> as core::iter::iterator::Iterator>::next
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libcore/option.rs:424
  22: <core::str::Bytes<'_> as core::iter::iterator::Iterator>::next
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libcore/iter/mod.rs:1328
  23: <core::str::Bytes<'_> as core::iter::iterator::Iterator>::next
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libcore/iter/mod.rs:799
  24: <proc_macro2::TokenStream as core::clone::Clone>::clone
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libproc_macro/lib.rs:171
  25: <core::str::Bytes<'_> as core::iter::iterator::Iterator>::next
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libcore/iter/iterator.rs:1477
  26: <proc_macro2::TokenStream as core::clone::Clone>::clone
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libproc_macro/lib.rs:189
  27: <proc_macro::TokenStream as core::clone::Clone>::clone
             at /Users/danno/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.24/src/unstable.rs:245
  28: <alloc::vec::SetLenOnDrop<'a> as core::ops::drop::Drop>::drop
             at /Users/danno/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.24/src/lib.rs:170
  29: <proc_macro2::TokenStream as core::clone::Clone>::clone
             at /Users/danno/.cargo/registry/src/github.com-1ecc6299db9ec823/quote-0.6.10/src/ext.rs:41
  30: <proc_macro2::TokenStream as core::clone::Clone>::clone
             at /Users/danno/.cargo/registry/src/github.com-1ecc6299db9ec823/quote-0.6.10/src/to_tokens.rs:173
  31: <&'a T as quote::to_tokens::ToTokens>::to_tokens
             at /Users/danno/.cargo/registry/src/github.com-1ecc6299db9ec823/quote-0.6.10/src/to_tokens.rs:77
  32: aoc_runner_derive::runner::runner_impl::{{closure}}
             at /Users/danno/.cargo/registry/src/github.com-1ecc6299db9ec823/aoc-runner-derive-0.1.3/src/runner.rs:49
  33: <std::thread::local::LocalKey<T>>::try_with
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libstd/thread/local.rs:309
  34: <std::thread::local::LocalKey<T>>::with
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libstd/thread/local.rs:255
  35: aoc_runner_derive::runner::runner_impl
             at /Users/danno/.cargo/registry/src/github.com-1ecc6299db9ec823/aoc-runner-derive-0.1.3/src/runner.rs:29
  36: aoc_runner_derive::aoc
             at /Users/danno/.cargo/registry/src/github.com-1ecc6299db9ec823/aoc-runner-derive-0.1.3/src/lib.rs:44
  37: std::panicking::try::do_call
             at src/libproc_macro/bridge/client.rs:419
             at src/libproc_macro/bridge/scoped_cell.rs:88
             at src/libproc_macro/bridge/scoped_cell.rs:83
             at src/libproc_macro/bridge/scoped_cell.rs:88
             at src/libproc_macro/bridge/client.rs:316
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libstd/thread/local.rs:309
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libstd/thread/local.rs:255
             at src/libproc_macro/bridge/client.rs:316
             at src/libproc_macro/bridge/client.rs:411
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libstd/panic.rs:319
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libstd/panicking.rs:310
  38: panic_unwind::dwarf::eh::read_encoded_pointer
             at src/libpanic_unwind/lib.rs:102
  39: proc_macro::bridge::client::<impl proc_macro::bridge::Bridge<'_>>::enter::{{closure}}::{{closure}}
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libstd/panicking.rs:289
             at /rustc/d09466ceb1374bd0ff1c490bfd50133b8ca67558/src/libstd/panic.rs:398
             at src/libproc_macro/bridge/client.rs:410
  40: proc_macro::bridge::server::run_server
  41: <syntax_ext::proc_macro_impl::AttrProcMacro as syntax::ext::base::AttrProcMacro>::expand
  42: syntax::ext::expand::MacroExpander::expand_invoc
  43: syntax::ext::expand::MacroExpander::expand_fragment
  44: syntax::ext::expand::MacroExpander::expand_crate
  45: rustc_driver::driver::phase_2_configure_and_expand_inner::{{closure}}
  46: rustc::util::common::time
  47: rustc_driver::driver::phase_2_configure_and_expand
  48: rustc_driver::driver::compile_input
  49: rustc_driver::run_compiler_with_pool
  50: <scoped_tls::ScopedKey<T>>::set
  51: rustc_driver::run_compiler
  52: rustc_driver::monitor::{{closure}}
  53: __rust_maybe_catch_panic
  54: rustc_driver::run
  55: rustc_driver::main
  56: std::rt::lang_start::{{closure}}
  57: std::panicking::try::do_call
  58: __rust_maybe_catch_panic
  59: std::rt::lang_start_internal
  60: main
query stack during panic:
end of query stack
error: custom attribute panicked
 --> src/day_1.rs:8:1
  |
8 | #[aoc(day1, part1)]
  | ^^^^^^^^^^^^^^^^^^^
  |
  = help: message: use-after-free in `proc_macro` handle

error: aborting due to previous error

error: Could not compile `advent-of-code-2018`.

To learn more, run the command again with --verbose.

called `Result::unwrap()` on an `Err` value: AlreadyConsumed

There seems to be some sort of incompatibility between some of the macros and the RLS. When I first start up RLS on my project everything is fine and there are no errors. However as soon as I make any sort of code change RLS comes up with the above error on both the #[aoc_generator(day1)] derive and the aoc_main! invocation. There are never any errors if I cargo check or cargo build or cargo run, this seems to be purely an issue with RLS. If I restart the RLS the error then goes away, until I make another code change.

Cannot return `HashMap` from Generator

error[E0599]: no method named `as_ref` found for type `std::collections::HashMap<usize, day4::Guard>` in the current scope
  --> src/day4.rs:47:1
   |
47 | #[aoc(day4, part1)]
   | ^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error
#[aoc_generator(day4)]
pub fn gen(input: &str) -> HashMap<usize, Guard> 

E0308 with 0.3.0

With cargo-aoc 0.3.0 from crates.io, regardless of whether or not cargo-aoc 0.2.0 was previously installed, I get the following. Reproducible for me on CentOS 7 and Windows 10. Rustc is 1.39.0 for both. Uninstalling and returning to 0.2.0 fixes it.

error[E0308]: mismatched types
--> src/main.rs:19:44
|
19 | match Factory::day9_part1_original(input_day9.clone()) {
| ^^^^^^^^^^^^^^^^^^ expected struct aoc_runner::ArcStr, found a different
|
= note: expected type aoc_runner::ArcStr (struct aoc_runner::ArcStr)
found type aoc_runner::ArcStr (struct aoc_runner::ArcStr)
note: Perhaps two different versions of crate aoc_runner are being used?
--> src/main.rs:19:44
|
19 | match Factory::day9_part1_original(input_day9.clone()) {
| ^^^^^^^^^^^^^^^^^^

error[E0308]: mismatched types
--> src/main.rs:37:44
|
37 | match Factory::day9_part2_original(input_day9.clone()) {
| ^^^^^^^^^^^^^^^^^^ expected struct aoc_runner::ArcStr, found a different
|
= note: expected type aoc_runner::ArcStr (struct aoc_runner::ArcStr)
found type aoc_runner::ArcStr (struct aoc_runner::ArcStr)
note: Perhaps two different versions of crate aoc_runner are being used?
--> src/main.rs:37:44
|
37 | match Factory::day9_part2_original(input_day9.clone()) {
| ^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try rustc --explain E0308.
error: could not compile aoc-autobuild.`

Specify a different input file

It would be great if cargo aoc would let us specify an alternate input file. This way, it could be easier to run our code over examples or other people's inputs, for example when assisting them.

Run with debug-assertions and overflow-checks turned on

This is some-what similar to #18, where the debug symbols are turned on, but there are quite a few other differences between the dev and release profiles.

Certain classes of bugs are ignored in the release profile, and it makes finding them difficult. The easiest thing to do would be add the following to the profile if a flag is turned on.

debug-assertions = true
overflow-checks = true

The overflow checks are really useful to make sure you aren't overflowing on a multiplication step that is common at the end. The debug-assertion, makes sure that you aren't doing something dumb that would normally be caught.

The release profile disables them compared to the dev profile.

An error occurs : entity not found cannot run cargo aoc (2019)

$ cargo aoc -d 6 -p 1
An error occurs : entity not found

I can't work out why I'm getting this error. I was happily using cargo-aoc (on another computer) for the first 5 days. I've started at day 6 on a different laptop but get this error.

There might be something in the files below that I've missed.
It's a bit of a weird & uninformative error and I think it comes from cargo-aoc (Clap) but not 100% sure.
It might be that "missing" days 1-5 causes this - if so is there a way to tell cargo-aoc to skip these days?

lib.rs
use aoc_runner;
use aoc_runner_derive::aoc_lib;

pub mod day6;
pub mod day10;

aoc_lib!{ year = 2019 }
main.rs
use aoc_runner_derive::aoc_main;

fn foo<'a>(input: &'a str) -> &'a str {
    "foo"
}

aoc_main! { lib = advent_of_code_2019 }
Cargo.toml
[package]
name = "advent_of_code_2019"    
version = "0.1.0"
authors = ["David Mason <[email protected]>"]
edition = "2018"
 
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
itertools = "0.8.2"
aoc-runner = "0.3.0"
aoc-runner-derive = "0.3.0"
day6.rs
use aoc_runner_derive::{aoc,aoc_generator};
...
#[aoc_generator(day6)]
fn input_generator(input: &str) -> Tree<String> { ... }

#[aoc(day6, part1)]
pub fn solve_part1(orbits: &Tree<String>) -> usize { ... }

Finally, input is definitely there.

$ ls input/2019/
day6.txt

--features support

I want to add visualisation, but I don't want it every time, because it slows things down, so I want something like cargo aoc --features video which would enable video:

#[aoc(day1, part1)]
fn part1(input: &[i32]) -> i32 {
  #[cfg(feature = "video")]
  let mut video = ...;
  for i in input {
    ...
    #[cfg(feature = "video")]
    video.add_frame(...);
  }
  42
}

Two workarounds which I see now, is to change default back and forth in Cargo.toml:

[features]
video = []
defaults = ["video"]

or to decide it in runtime based on some environment variable.

Flame graph

This is very much a feature request, not an issue. Not sure if you'd like it in your inbox or something, but oh well.

I recently found the flamegraph crate which lets you make flamegraphs from criterion results. Is there a possibility of adding a subcommand to bench for use of this?

Thanks!

Allow &str input in aoc function after generator was defined.

It should be possible to implement an generator to return e.g. a struct and one implementation of the solution to use the generated &struct but simultaneously another solution to use the default &str type.
At the moment expected `str`, found struct `struct` is thrown.

This is due to the default "pass through" being disabled after implementing a generator.

nvm

My mistake, sorry.

[Request] Benchmark generator

Would it be possible to benchmark generator functions with Criterion?

It would be useful to compare different parsing methods (logos, regex, nom, pest, etc).

Wrong number of type arguments: expected 1, found 2

error[E0107]: wrong number of type arguments: expected 1, found 2
   --> src/day3.rs:101:1
    |
101 | #[aoc(day3,part1)]
    | ^^^^^^^^^^^^^^^^^^ unexpected type argument

I've started running into this issue now that I've hit day 3 (only discovered AoC around Christmas.

My solver functions in question look like this:

pub fn solver_part1(input: &[Claim]) -> usize {
    let mut g = Grid::new();
    for claim in input {
        for p in claim.iter_points() {
            *g.entry(p).or_default() += 1;
        }
    }
    g.values().filter(|&&count| count > 1).count()
}

I've got the first two days solved just fine and I can't tell what's causing the problem.

Reuse generator outputs

Right now the generator function is run again before each part, even if all parts request exactly the same input. This wastes computation time because the puzzle input has to be parsed and transformed at least twice.

It would be preferable if the output of the generator function could be reused, especially if the solver functions only take immutable references, like the examples in the readme.

For example, if the generator returns a Vec,

#[aoc_generator(day2)]
pub fn input_generator(input: &str) -> Vec<Gift> {
    // ...
}

and the solvers take an immutable slice or another reference type,

#[aoc(day2, part1)]
pub fn solve_part1(input: &[Gift]) -> u32 {
    // ...
}

#[aoc(day2, part2)]
pub fn solve_part2(input: &[Gift]) -> u32 {
    // ...
}

it should be possible to use the same Vec returned by the generator for both solvers.

Suggestion: Run all benchmarks

Maybe add a flag to run all days and parts, for example for CI?

Something like cargo aoc --all and cargo aoc bench --all.

missing `bench` in implementation

I've updated cargo-aoc to v0.2.2 and also updated aoc-runner and aoc-runner-derive in my project to the latest version, but now I get the following error for all my aoc macro invocations when I try to run it with cargo aoc:

error[E0046]: not all trait items implemented, missing: `bench`
 --> src/day1.rs:8:1
  |
8 | #[aoc(day1, part1)]
  | ^^^^^^^^^^^^^^^^^^^ missing `bench` in implementation
  |
  = note: `bench` from trait: `fn(&Self, for<'r> fn(&'r (dyn std::fmt::Display + 'r)))`

When I run it with cargo run it doesn't give any errors and works normally.

Did I forget to update something?

Support cargo workspaces

Without multi-year support I was hoping to at least use cargo workspaces to reuse the build cache between years.

Unfortunately, that causes issues for the runner:

  • You can't run cargo aoc from the workspaces root. Fair enough, it doesn't know about -p <workspace>.
  • You can't run cargo aoc in a workspace either, it bails out with error occurs : entity not found.

Could the second error be fixed at all?

Support cloned values

It'd be a great addition if we could generate values and have them cloned:

// This is day 2, 2019
#[aoc_generator(day2)]
pub fn gen(input: &str) -> Vec<isize> {
    input
        .split(",")
        .map(|s| s.trim())
        .flat_map(|s| s.parse::<isize>())
        .collect()
}

#[aoc(day2, part1)]
#[clone]
pub fn day2_impl1(input: Vec<isize>) -> isize {
    unimplemented!()
}

Running solutions with `RUST_LOG=DEBUG`

I was wondering if there is any way to show the debug statements produced by our 'day code'? Currently, it seems like cargo aoc is suppressing debug statements. As it seems like some of the problems in this year's AOC require visual checking, I think it would be cool if logging worked.

Allow running specific (/last) day (and/or part) from the regular executable

cargo aoc is running the last day by default and has flags for choosing which year/day/part to run. But the executable itself does not have these flags, and it'll always run all the days.

It would be convenient to give the executable the ability to run specific days, so that we could use cargo run -- -d13 or cargo run -- --last-day (new flag, in case you want to keep the old behavior when no flags are given) instead of cargo aoc. cargo run is more convenient since it is more customisable (I mainly care about the --quiet flag), does not rebuild in release mode on every run.

#[aoc(day1, part1)]: Custom attribute panicked

Any thoughts on this one? Can't build an initial project based on the 2015 example repo. Mine, for reference: https://github.com/richchurcher/advent-of-code. I'm fairly new to Rust so I may be overlooking something obvious.

19:35 $ cargo build --verbose
       Fresh unicode-xid v0.1.0
       Fresh itoa v0.4.3
       Fresh aoc-runner v0.1.0
       Fresh proc-macro2 v0.4.24
       Fresh ryu v0.2.7
       Fresh serde v1.0.80
       Fresh quote v0.6.10
       Fresh serde_json v1.0.33
       Fresh syn v0.15.22
       Fresh serde_derive v1.0.80
       Fresh aoc-runner-internal v0.1.0
       Fresh aoc-runner-derive v0.1.1
   Compiling advent_of_code v0.1.0 (/w/advent-of-code)
     Running `rustc --crate-name advent_of_code src/lib.rs --color always --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=0be99721b277c061 -C extra-filename=-0be99721b277c061 --out-dir /w/advent-of-code/target/debug/deps -C incremental=/w/advent-of-code/target/debug/incremental -L dependency=/w/advent-of-code/target/debug/deps --extern aoc_runner=/w/advent-of-code/target/debug/deps/libaoc_runner-be157ae2a09ebca4.rlib --extern aoc_runner_derive=/w/advent-of-code/target/debug/deps/libaoc_runner_derive-1a513b71b4753c17.so`
error: custom attribute panicked
 --> src/day1.rs:1:1
  |
1 | #[aoc(day1, part1)]
  | ^^^^^^^^^^^^^^^^^^^
  |
  = help: message: explicit panic
error: aborting due to previous error
error: Could not compile `advent_of_code`.
Caused by:
  process didn't exit successfully: `rustc --crate-name advent_of_code src/lib.rs --color always --crate-type lib --emit=dep-info,link -C debuginfo=2 -C metadata=0be99721b277c061 -C extra-filename=-0be99721b277c061 --out-dir /w/advent-of-code/target/debug/deps -C incremental=/w/advent-of-code/target/debug/incremental -L dependency=/w/advent-of-code/target/debug/deps --extern aoc_runner=/w/advent-of-code/target/debug/deps/libaoc_runner-be157ae2a09ebca4.rlib --extern aoc_runner_derive=/w/advent-of-code/target/debug/deps/libaoc_runner_derive-1a513b71b4753c17.so` (exit code: 1)

Output of rustup show:

Default host: x86_64-unknown-linux-gnu
stable-x86_64-unknown-linux-gnu (default)
rustc 1.30.1 (1433507eb 2018-11-07)

main.rs:

extern crate advent_of_code_2018;
extern crate aoc_runner_derive;
extern crate aoc_runner;

use aoc_runner_derive::aoc_main;

aoc_main! { lib = advent_of_code_2018 }

lib.rs:

extern crate aoc_runner;

#[macro_use]
extern crate aoc_runner_derive;

pub mod day1;

aoc_lib!{ year = 2018 }

day1.rs:

#[aoc(day1, part1)]
pub fn calibrate_device (input: &str) {
    return 0;
}

Allow downloading the inputs of all the days

If i clone my solution repo on a different computer, it's a hassle to run cargo aoc input on each and every day - and without it I can't build. It would be nice to have a cargo aoc input --all that will download all the input files of a given year.

Could not create input directory

Hello again 😄 with the latest update there's a panic if the input directory already exists, it seems?

$ cargo aoc input
Requesting input for year 2018, day 2 ...
thread 'main' panicked at 'Could not create input directory: Os { code: 17, kind: AlreadyExists
, message: "File exists" }', libcore/result.rs:1009:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

The contents of the directory were:

21:56 $ tree
.
└── 2018
    └── day1.txt

1 directory, 1 file

And as you can see, I was looking for day 2. Been fun using the tool so far though!

Change input name from day1.txt to day01.txt?

Hey!

Just started using this and was wondering how hard it would be to change the input file names from input/2019/day1.txt etc to input/2019/day01.txt. That would mean they sort nicely for days 10 and beyond.

Getting the part2 result as a by-product of solving part1

Does someone have a good suggestion on how to organize the code when your solution of part1 also yields the answer to part2? Would I use a global to store the part2 result, and then just return that in the part2 function? Or is there a cleaner way to do it?

Trim end of input?

The end of the input isn't being trimmed of whitespace which was unexpected. I'm not sure if trimming the beginning would interfere with any of the puzzles.

Add option to only generate the aoc-autobuild source

To make it easier to debug with the runner, please add an option to only generate the runner binary code (so let us skip execution of cargo run). Something like cargo aoc generate or an extra switch for cargo aoc ...

That way I can tell VSCode / LLDB to pre-run cargo aoc generate -d ... before then starting a debug session from the aoc-autobuild binary.

Cannot use lifetimes in return types for `aoc{,_generator}`

When one uses a return value with a lifetime in it, #[aoc(...)] panicks with an error similar to:

~/…/personal/advent-of-code-2018 lifetime-problems$ cargo build
   Compiling advent-of-code-2018 v0.1.0 (<snip>)
error[E0261]: use of undeclared lifetime name `'a`
  --> src\day6.rs:47:1
   |
47 | #[aoc(day6, part1)]
   | ^^^^^^^^^^^^^^^^^^^ undeclared lifetime

error: aborting due to previous error

For more information about this error, try `rustc --explain E0261`.
error: Could not compile `advent-of-code-2018`.

To learn more, run the command again with --verbose.

You can check out a fully-reproducible example that the above is based on in the lifetime-problems branch of my AoC2018 solutions. The most interesting file is day6.rs, which I'll inline for posterity since I'll be deleting that branch once this issue is resolved:

use {
    aoc_runner_derive::{
        aoc,
        aoc_generator,
    },
    re_parse::{
        Regex,
        ReParse,
    },
    serde_derive::Deserialize,
    std::str::Split,
};

#[derive(Debug, Deserialize, ReParse)]
#[re_parse(regex = r#"(?P<x>\d{1,10}), (?P<y>\d{1,10})"#)]
struct Coordinate {
    x: u32,
    y: u32,
}

#[derive(Debug)]
struct CoordinateParser<'a> {
    input: Split<'a, char>,
}

impl<'a> CoordinateParser<'a> {
    pub fn new(input: Split<'a, char>) -> Self {
        Self {
            input,
        }
    }
}

impl Iterator for CoordinateParser<'_> {
    type Item = Coordinate;

    fn next(&mut self) -> Option<Self::Item> {
        Some(self.input.next()?.parse().unwrap())
    }
}

#[aoc_generator(day6)]
fn day6_generator<'a>(input: &'a str) -> CoordinateParser<'a> {
    CoordinateParser::new(input.trim().split('\n'))
}

#[aoc(day6, part1)]
pub fn day6_part1(input: CoordinateParser<'_>) -> u32 {
    println!("input: {:#?}", input);
    0
}

Format using Debug trait

Hello,

Could it be possible to support the Debug trait as well as the Display trait?

If not, is there a way to fmt a Vec<T>?

Thanks in advance.

input to generator function seems to be missing trailing newlines

I ran into some trouble with today's (2020/day 4) problem because the generator was passing a truncated form of the input files sans any trailing newlines. I'm unclear as to why this happens because my functioning test case also uses include_str! but its replicable and happens to any number of trailing newlines. I'm using aoc-runner and aoc-runner-derive version 0.30 and cargo-aoc version 0.3.2.

Store correct answers so later refactoring doesn't accidently break solutions.

I quite often get the correct solution with very messy code, then tidy up. A few days later I may refactor multiple solutions together to tidy up further.

It would be nice to store the 'correct' answer in the #[aoc(day1,part1)] line, or maybe a 2nd annotation, which then gets assert_eq!ed in the surrounding code.

That way, once I know the correct answer, I could store it in code and be sure my solutions are all still correct.

Of course I could manually put in the asserts, but that might be verbose?

Alternatively, if there were a version of assert_eq! which returned one of its arguments, that could be quite succinct...

(also, this solution wouldn't work great for the 'graphical' problems where the answer is letters made from a grid of # and space characters)

Suggestion: Check solutions

It would be nice to have some way of checking the solutions are still correct after a refactor. Maybe in the form of a output file in the input directory. Solutions would be supplied by the user and only checked when present.

Runner support for multiple years

I noticed cargo aoc input downloads inputs into directories by year.

Are there any plans to support multiple years per project in the runner? It would be nice to have all my advent years in the same repo.

Alpha support for `Result`s

Generators & Runners now support Results in return position !
I need some feedback before release, so please install alpha & comment on this issue.

Setup

In your Cargo.toml:

aoc-runner = "0.2.0-alpha1"
aoc-runner-derive = "0.2.0-alpha1"

In your terminal:
$ cargo install cargo-aoc --force --version 0.2.0-alpha1

Examples

#[aoc_generator(day1)]
fn parse_input(input: &str) -> Result<Vec<i32>, ParseIntError> {
    input
        .lines()
        .map(|l| l.parse())
        .collect()
}

#[aoc(day1, part1)]
fn part1(freqs: &[i32]) -> i32 {
    freqs.iter().sum()
}

Known limitation

By far, the biggest limitation is that I need the return type to be called Result (it still can be prefixed with a path), with at least a template parameter.
So these wont work :

type MyRes = Result<Vec<i32>, ParseIntError>;

#[aoc_generator(day1)]
fn parse_input(input: &str) -> MyRes {
    ...
}
type Result = std::result::Result<Vec<i32>, ParseIntError>;

#[aoc_generator(day1)]
fn parse_input(input: &str) -> MyRes {
    ...
}

Generated input files aren't found

Downloaded input files from cargo aoc input are txt files in directories by year (eg. /input/2017/day1.txt), but it expects files without an extension and not categorized by year (eg. /input/day1). The specific error I'm getting is

error: couldn't read src/../input/day1: No such file or directory (os error 2)

Export `aoc-runner` from user crate

cargo-aoc generate crates with a dependency to aoc-runner, so both must be one the same version.

A solution is to export aoc-runner from user crate and remove cargo-aoc's dependency.

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.