10
Newb solving AoC in rust (programming.dev)
submitted 11 months ago by bia@programming.dev to c/rust@programming.dev

Sorry if this is a stupid question, but I'm struggling with what I think is ownership in rust.

I'm completely new to rust, but have done low level languages before so I know the concept of pointers pretty well. However, this rust ownership I can't quite wrap my head around.

I'm trying to refactor my solution to AoC Day 4 Part 2 using a struct reference instead of a stand-alone vector.

The error I'm getting, and can't figure out is in the process function at line

cards.iter_mut().for_each(|card | {

The error is

cannot borrow cards as mutable more than once at a time second mutable borrow occurs here

There is a lot of parsing in my code, so I stuck that in a spoiler below.

The relevant code is:

#[derive(Debug)]
struct Card {
    id: u32,
    score: u32,
    copies: u32,
}

fn process(input: &str) -> u32 {
    let mut cards: Vec = parse_cards(input);

    cards.iter_mut().for_each(|card| {
        let copy_from = card.id as usize + 1;
        let copy_to: usize = copy_from + card.score as usize - 1;

        if card.score == 0 || copy_from > cards.len() {
            return;
        }

        for card_copy in cards[copy_from - 1..copy_to].iter() {
            let id = card_copy.id as usize - 1;
            let add = cards[card.id as usize - 1].copies;
            cards[id].copies += add;
        }
    });

    return cards.iter().map(|c| c.copies).sum();
}

Other code:

spoiler

fn main() {
    let input = include_str!("./input1.txt");
    let output = process(input);
    dbg!(output);
}

fn parse_cards(input: &str) -> Vec {
    return input.lines().map(|line| parse_line(line)).collect();
}

fn parse_line(line: &str) -> Card {
    let mut card_split = line.split(':');
    let id = card_split
        .next()
        .unwrap()
        .replace("Card", "")
        .trim()
        .parse::()
        .unwrap();

    let mut number_split = card_split.next().unwrap().trim().split('|');

    let winning: Vec = number_split
        .next()
        .unwrap()
        .trim()
        .split_whitespace()
        .map(|nbr| nbr.trim().parse::().unwrap())
        .collect();
    let drawn: Vec = number_split
        .next()
        .unwrap()
        .trim()
        .split_whitespace()
        .map(|nbr| nbr.trim().parse::().unwrap())
        .collect();

    let mut score = 0;

    for nbr in &drawn {
        if winning.contains(&nbr) {
            score = score + 1;
        }
    }

    return Card {
        id,
        score,
        copies: 1,
    };
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn full_test() {
        let result = process(
            "Card 1: 41 48 83 86 17 | 83 86  6 31 17  9 48 53
        Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19
        Card 3:  1 21 53 59 44 | 69 82 63 72 16 21 14  1
        Card 4: 41 92 73 84 69 | 59 84 76 51 58  5 54 83
        Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36
        Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11",
        );
        assert!(result != 0);
        assert_eq!(result, 30);
    }
}

you are viewing a single comment's thread
view the rest of the comments
[-] rutrum@lm.paradisus.day 5 points 11 months ago

Yeah when you iterate over cards mutably, you're borrowing it again at the line cards[id].copies +=... I think. If you're going to access the card by index there then you loop over indicies at the top lop instead of iter_mut

[-] bia@programming.dev 2 points 11 months ago

Thanks, I tried that. But now I get the error.

cannot borrow cards as mutable because it is also borrowed as immutable

[-] Anders429@programming.dev 1 points 11 months ago

Can you show us your code for when you tried this suggestion?

[-] bia@programming.dev 2 points 11 months ago

I solved it by using indicies instead, that way I got around the borrow checker.

[-] Anders429@programming.dev 1 points 11 months ago

That's actually what the comment above was suggesting, which is why I was wondering why you couldn't get it to work. Glad you got it working!

load more comments (1 replies)
load more comments (1 replies)
this post was submitted on 04 Dec 2023
10 points (100.0% liked)

Rust

5999 readers
20 users here now

Welcome to the Rust community! This is a place to discuss about the Rust programming language.

Wormhole

!performance@programming.dev

Credits

  • The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)

founded 1 year ago
MODERATORS