Giter Club home page Giter Club logo

Comments (14)

simonw avatar simonw commented on June 28, 2024

I think a numeric comparison will work well here. Look for cases where either the first range encloses the second or vice-versa.

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

So here's a mystery that stumped me for a while.

I wrote this code, based on my previous answers:

use std::fs;
use std::io;
use std::io::BufRead;

fn main() {
    // Read file line by line
    let file = fs::File::open("input.txt")?;
    let reader = io::BufReader::new(file);
    for line in reader.lines() {
        println!("{}", line.unwrap());
    }
}

That looks fine to me - but the compiler says:

   Compiling day_04 v0.1.0 (/Users/simon/Dropbox/Development/advent-of-code-2022-in-rust/day_04)
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
  --> src/main.rs:7:43
   |
5  | / fn main() {
6  | |     // Read file line by line
7  | |     let file = fs::File::open("input.txt")?;
   | |                                           ^ cannot use the `?` operator in a function that returns `()`
8  | |     let reader = io::BufReader::new(file);
...  |
11 | |     }
12 | | }
   | |_- this function should return `Result` or `Option` to accept `?`
   |
   = help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `day_04` due to previous error

So I pasted that into ChatGPT and it said:

The error message is telling you that you are using the ? operator in a function that doesn't return a Result or Option type. The ? operator is used to return an error value from a function if the operation being performed returns an error. However, in a function that doesn't return a Result or Option, there is no way to return an error value, so the ? operator can't be used.

To fix this error, you will need to change your function to return a Result or Option type. You can do this by adding a Result or Option return type to your function signature. For example, you could change your function to the following:

fn main() -> Result<(), std::io::Error> {
    // Read file line by line
    let file = fs::File::open("input.txt")?;
    let reader = io::BufReader::new(file);
    // Process the lines
    for line in reader.lines() {
        let line = line?;
        println!("{}", line);
    }
    // Return success
    Ok(())
}

In this example, the main function now has a return type of Result<(), std::io::Error>, which means it will return either an error value or a value indicating success (in this case, an empty tuple ()). This allows the ? operator to be used in the function to return any errors that occur.

It took me a bit to understand why changing the function signature (adding -> Result<(), std::io::Error>) would fix the compile error.

Then I got it: the ?; operator means "do this and return an error if it fails" - but the fn main() function by default didn't have a signature that included the possibility it might return an error.

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

Here's the version of the code that works:

use std::fs;
use std::io;
use std::io::BufRead;

fn main() -> Result<(), std::io::Error> {
    // Read file line by line
    let file = fs::File::open("input.txt")?;
    let reader = io::BufReader::new(file);
    for line in reader.lines() {
        let line = line?;
        println!("{}", line);
    }
    Ok(())
}

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

I asked it which of these was better idiomatic Rust and it had a strong opinion:

image

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

Tried this:

use std::fs;
use std::io;
use std::io::BufRead;
fn main() -> Result<(), std::io::Error> {
// Read file line by line
let file = fs::File::open("input.txt")?;
let reader = io::BufReader::new(file);
let mut score = 0;
for line in reader.lines() {
let line = line?;
// Line is e.g. 41-47,40-80 - parse into a-b,c-d
// first use split_once('-')
let (one, two) = line.split_once(',').unwrap();
let (a, b) = one.split_once('-').unwrap();
let (c, d) = two.split_once('-').unwrap();
// Parse those into numbers
let a = a.parse::<u32>().unwrap();
let b = b.parse::<u32>().unwrap();
let c = c.parse::<u32>().unwrap();
let d = d.parse::<u32>().unwrap();
// Check if range a-b contains c-d or vice versa
if (a <= c && c <= b) || (a <= d && d <= b) {
println!("{}-{} fully overlaps {}-{}", a, b, c, d);
score += 1;
}
}
println!("Score: {}", score);
Ok(())
}

Mostly written by Copilot, prompted by my commits.

Apparently wrong:

That's not the right answer; your answer is too high. If you're stuck, make sure you're using the full input data; there are also some general tips on the about page, or you can ask for hints on the subreddit. Please wait one minute before trying again. (You guessed 831.)

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

Question was: "In how many assignment pairs does one range fully contain the other?"

Maybe exact matches shouldn't count?

No, tried that - still got an answer that was too high.

I used:

        if (a <= c && c <= b) || (a <= d && d <= b) && (a != c && b != d) {

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

I cheated and ran the solution from https://fasterthanli.me/series/advent-of-code-2022/part-4 - it gets 490, so I should change my code until I get that number too.

That example uses .filter(|(a, b)| a.contains_or_is_contained(b)) where that function is defined using fancy traits as:

trait InclusiveRangeExt {
    fn contains_range(&self, other: &Self) -> bool;

    // 👋 new! we can have trait methods with default implementations
    fn contains_or_is_contained(&self, other: &Self) -> bool {
        self.contains_range(other) || other.contains_range(self)
    }
}

impl<T> InclusiveRangeExt for RangeInclusive<T>
where
    T: PartialOrd,
{
    fn contains_range(&self, other: &Self) -> bool {
        self.contains(other.start()) && self.contains(other.end())
    }
}

Which itself uses use itertools::Itertools; which I had to install with cargo add itertools.

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

I tried to figure out how to remove that itertools package. I asked ChatGPT and it clearly didn't know but made stuff up anyway! It told me to run cargo remove itertools - but that's not a command. I kept pasting it error messages and it kept making new guesses, none of which worked.

I won't paste in the full transcript because it got tedious. I eventually decided to edit the Cargo.toml file by hand instead:

image

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

image

CleanShot 2022-12-04 at 21 11 27@2x

This gave me the right result.

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

use std::fs;
use std::io;
use std::io::BufRead;
fn range_contains_range(range: (u32, u32), other: (u32, u32)) -> bool {
range.0 <= other.0 && range.1 >= other.1
}
fn main() -> Result<(), std::io::Error> {
// Read file line by line
let file = fs::File::open("input.txt")?;
let reader = io::BufReader::new(file);
let mut score = 0;
for line in reader.lines() {
let line = line?;
// Line is e.g. 41-47,40-80 - parse into a-b,c-d
// first use split_once('-')
let (one, two) = line.split_once(',').unwrap();
let (a, b) = one.split_once('-').unwrap();
let (c, d) = two.split_once('-').unwrap();
// Parse those into numbers
let a = a.parse::<u32>().unwrap();
let b = b.parse::<u32>().unwrap();
let c = c.parse::<u32>().unwrap();
let d = d.parse::<u32>().unwrap();
let range1 = (a, b);
let range2 = (c, d);
if range_contains_range(range1, range2) || range_contains_range(range2, range1) {
score += 1;
}
}
println!("Score: {}", score);
Ok(())
}

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

Part 2:

It seems like there is still quite a bit of duplicate work planned. Instead, the Elves would like to know the number of pairs that overlap at all.

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

Copilot completed this task for me based just on my new function name:

fn range_overlaps_range(range: (u32, u32), other: (u32, u32)) -> bool {
    range.0 <= other.0 && other.0 <= range.1
        || range.0 <= other.1 && other.1 <= range.1
        || other.0 <= range.0 && range.0 <= other.1
        || other.0 <= range.1 && range.1 <= other.1
}

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

use std::fs;
use std::io;
use std::io::BufRead;
fn range_overlaps_range(range: (u32, u32), other: (u32, u32)) -> bool {
range.0 <= other.0 && other.0 <= range.1
|| range.0 <= other.1 && other.1 <= range.1
|| other.0 <= range.0 && range.0 <= other.1
|| other.0 <= range.1 && range.1 <= other.1
}
fn main() -> Result<(), std::io::Error> {
// Read file line by line
let file = fs::File::open("input.txt")?;
let reader = io::BufReader::new(file);
let mut score = 0;
for line in reader.lines() {
let line = line?;
// Line is e.g. 41-47,40-80 - parse into a-b,c-d
// first use split_once('-')
let (one, two) = line.split_once(',').unwrap();
let (a, b) = one.split_once('-').unwrap();
let (c, d) = two.split_once('-').unwrap();
// Parse those into numbers
let a = a.parse::<u32>().unwrap();
let b = b.parse::<u32>().unwrap();
let c = c.parse::<u32>().unwrap();
let d = d.parse::<u32>().unwrap();
let range1 = (a, b);
let range2 = (c, d);
if range_overlaps_range(range1, range2) {
score += 1;
}
}
println!("Score: {}", score);
Ok(())
}

from advent-of-code-2022-in-rust.

simonw avatar simonw commented on June 28, 2024

image

image

from advent-of-code-2022-in-rust.

Related Issues (17)

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.