How to collect all integer from a string of numbers

I am trying to make a sudoku solver in Rust and right now, I am trying to read the starting board state from a text file. The string contains

0 4 3 0 8 0 2 5 0
6 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 9 4
9 0 0 0 0 4 0 7 0
0 0 0 6 0 8 0 0 0
0 1 0 2 0 0 0 0 3
8 2 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 5
0 3 4 0 9 0 7 1 0

and I was wondering if there was a way to store all the integers into an array or vector so that I can transfer the values into a 2-dimensional array that would represent a sudoku board. Any help would be appreciated. Thank you!

Sounds like if your data is in a &[u8]

let v = bytes.iter().cloned().filter(|c| b"0123456789".contains(c) ).map(|c| c - b'0').collect::<Vec<u8>>();

Do I have to use a crate for this? Also is there a way to do this without crates?

No, this would not require a crate.

let board = board_str
    .lines()
    .map(|line| {
        line.split_ascii_whitespace()
            .map(|col| col.parse::<i32>())
            .collect::<Result<Vec<_>, _>>()
    })
    .collect::<Result<Vec<_>, _>>()
    .unwrap_or_else(|err| panic!("Cannot parse a column: {}", err));

You can use .lines() to get iterator of lines.
And for each lines, you can use .split_ascii_whitespace() to get columns delimited by ASCII whitespaces.
Then you can .collect() them and create Vec<Vec<i32>> (or whatever you want).

This requires only std library.

1 Like

Alternative approach,

struct Sudoku {data: Vec<u8>}

fn parse(input: &str) -> Sudoku {
    let mut data: Vec<u8> = Vec::with_capacity(81);
    for c in input.chars() {
        if c=='.' || c=='0' {
            data.push(0);
        } else if c.is_digit(10) {
            data.push(c as u8-'0' as u8);
        }
    }
    return Sudoku{data};
}

impl std::ops::Index<(usize,usize)> for Sudoku {
    type Output = u8;
    fn index(&self, index: (usize,usize)) -> &u8 {
        &self.data[9*index.0+index.1]
    }
}

impl std::fmt::Display for Sudoku {
    fn fmt(&self, f: &mut std::fmt::Formatter)
    -> std::fmt::Result
    {
        static RULE: &str = " ------+-------+------ ";
        for i in 0..9 {
            if i>0 && i%3==0 {writeln!(f,"{}",RULE).unwrap();}
            for j in 0..9 {
                if j>0 && j%3==0 {write!(f," |").unwrap();}
                let digit = self[(i,j)];
                if digit==0 {
                    write!(f," .").unwrap();
                } else {
                    write!(f," {}",digit).unwrap();
                }
            }
            writeln!(f).unwrap();
        }
        return Ok(());
    }
}

static S1: &str = "
. 4 3 | . 8 . | 2 5 .
6 . . | . . . | . . .
. . . | . . 1 | . 9 4
------+-------+------
9 . . | . . 4 | . 7 .
. . . | 6 . 8 | . . .
. 1 . | 2 . . | . . 3
------+-------+------
8 2 . | 5 . . | . . .
. . . | . . . | . . 5
. 3 4 | . 9 . | 7 1 .
";

fn main() {
    let s = parse(S1);
    println!("{}",s);
}

BTW, you won't be able to do much in Rust without crates. It's normal to use plenty of crates even for most basic stuff. While some languages prefer to have everything built-in and not use dependencies, Rust is the opposite: it intentionally has a small standard library, and made it easy to rely on crates for everything.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.