nsi:langages:rust:solutions:ghostleg
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Solution Ghostleg en Rust
Solution de ce problème.
// src/lib.rs
use std::fs::File;
use std::io::{ self, BufRead, BufReader };
fn transposition(line:&str, indice:usize) -> String {
/* indice: rang d'un caractère
fait la transpositon entre le rang voulu et le rang +1
renvoie une copie de la ligne avec la modif faite */
let n = line.len();
if indice >= n-1 {
panic!("dépassement d'indice !");
}
let mut out = String::new();
let mut right = ' ';
for (i,c) in line.chars().enumerate() {
if i == indice {
right = c;
} else {
out.push(c);
}
if i == indice + 1 {
out.push(right);
}
}
out
}
fn ghostleg_line(line:&str, gline:&str) -> String {
/* partant d'une ligne, ex: "ABC"
et d'une ligne de ghostleg, ex |--| |
calcule la ligne suivante, ex "BAC */
let mut s = String::from(line);
for (i,c) in gline.chars().enumerate() {
if i % 3 == 1 && c == '-' {
s = transposition(&s, i/3);
}
}
s
}
fn get_head(line:&str) -> String {
/* renvoie une copie de line sans les espace */
let mut s = String::new();
for c in line.chars() {
if c != ' ' && c != '\n' {
s.push(c);
}
}
s
}
fn read_lines(filename: &str) -> io::Lines<BufReader<File>> {
let file = match File::open(filename){
Ok(f) => f,
Err(erreur) => panic!("Erreur d'ouverture du fichier : {:?}", erreur),
};
return io::BufReader::new(file).lines();
}
pub fn ghostleg(filename: &str) -> String {
/* text: ensemble du texte du ghostleg
renvoie la chaîne finale */
let mut lines = read_lines(filename);
let first_line = match lines.next() {
Some(Ok(line)) => line,
Some(Err(erreur)) => panic!("Erreur lecture première ligne : {:?}", erreur),
None => panic!("Texte vide !"),
};
let mut s = get_head(&first_line);
for getline in lines {
let line = match getline {
Ok(l) => l,
Err(_erreur) => continue,
};
if line.starts_with('|') {
s = ghostleg_line(&s, &line);
}
}
s
}
#[cfg(test)]
mod tests {
#[test]
fn transposition_test() {
let in_str = "ABCDEF";
assert_eq!(crate::transposition(in_str, 3), String::from("ABCEDF"));
assert_eq!(crate::transposition(in_str, 0), String::from("BACDEF"));
}
#[test]
#[should_panic]
fn transposition_panic_test() {
let in_str = "ABCDEF";
crate::transposition(in_str, 8);
}
#[test]
fn ghostleg_line_test() {
assert_eq!(crate::ghostleg_line("ABC", "|--| |"), String::from("BAC"));
assert_eq!(crate::ghostleg_line("ABCDEF", "| |--| | |--|"), String::from("ACBDFE"));
}
#[test]
fn get_head() {
assert_eq!(crate::get_head("A B C \n"), String::from("ABC"));
}
}
Vous noterez la présence de match un peu lourds qui sont là pour palier à toute erreur possible, notamment en cours de lecture de la prochaine ligne. J'ai trouvé sur internet le système de Buffer utilisé pour la lecture de ligne. L'objet Lines produit des item compliqué puisqu'ils sont enveloppé dans Option (soit quelque chose Some, soit None) et une possibilité d'erreur Result (soit Ok soi Err).
// src/main.rs
use std::env;
use ghostleg::ghostleg;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
panic!("Usage : {} filename", args[0]);
}
let filename = &args[1];
let s = ghostleg(filename);
print!("{}\n", s);
}
nsi/langages/rust/solutions/ghostleg.txt · Dernière modification : de goupillwiki
