Cod sursa(job #2639827)

Utilizator TincaMateiTinca Matei TincaMatei Data 4 august 2020 01:05:47
Problema Generare de permutari Scor 100
Compilator rs Status done
Runda Arhiva educationala Marime 2.38 kb
use std::fs::File;
use std::io::{Read, Write, BufWriter};

// Generates permutations in reversed order
struct RevPermutationGenerator {
  n: usize,
  rec: Option<Box<RevPermutationGenerator>>,
  collection: Vec<i32>,
  first_pnt: i32,
}

impl RevPermutationGenerator {
  fn new(n: usize, collection: &[i32]) -> RevPermutationGenerator {
    assert_eq!(collection.len(), n);
    
    let mut new_collection = vec![0; n];
    new_collection.copy_from_slice(collection);
    RevPermutationGenerator {
      n,
      rec: None,
      collection: new_collection,
      first_pnt: -1,
    }
  }
}

impl Iterator for RevPermutationGenerator {
  type Item = Vec<i32>;

  fn next(&mut self) -> Option<Self::Item> {
    if self.n == 1 {
      self.first_pnt += 1;
      return if self.first_pnt == 0 { Some(vec![self.collection[0]]) } else { None }
    }
    
    if let None = self.rec {
      self.first_pnt += 1;
      let mut gen = Box::new(RevPermutationGenerator::new(self.n - 1, &self.collection[1..]));
      let mut perm = gen.next().unwrap();
      perm.push(self.collection[0]);

      self.rec = Some(gen);
      return Some(perm)
    } else {
      let mut gen = self.rec.take().unwrap();
      let perm = gen.next();

      match perm {
      None => {
        self.first_pnt += 1;
        if self.first_pnt as usize == self.n {
          return None;
        }

        self.collection.swap(0, self.first_pnt as usize);

        let mut gen = Box::new(RevPermutationGenerator::new(self.n - 1, &self.collection[1..]));
        let mut perm = gen.next().unwrap();
        perm.push(self.collection[0]);
        
        self.rec = Some(gen);
        return Some(perm);
      }
      Some(mut perm) => {
        perm.push(self.collection[0]);
        self.rec = Some(gen);
        return Some(perm);
      }
      }
    }
  }
}

fn main() {
  let mut fin = File::open("permutari.in").unwrap();
  let mut fout = BufWriter::new(File::create("permutari.out").unwrap());

  let mut line = String::new();
  fin.read_to_string(&mut line).unwrap();

  let n : usize = line.trim().parse().unwrap();
 
  let initial_perm : Vec<i32> = (1..n+1).map(|x| {x as i32}).collect();
  let perm_iterator = RevPermutationGenerator::new(n, &initial_perm);
  
  perm_iterator.for_each(|x| {
    x.iter().rev().for_each(|y| { fout.write(format!("{} ", y).as_bytes()).unwrap(); } );
    fout.write("\n".as_bytes()).unwrap();
  });

  fout.flush().unwrap();
}