Advertisement
Guest User

Untitled

a guest
Dec 12th, 2019
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 4.94 KB | None | 0 0
  1. use std::io::{self, Read};
  2.  
  3. use regex::Regex;
  4.  
  5. fn read_stdin() -> String{
  6.     let mut buffer = String::new();
  7.     io::stdin().read_to_string(&mut buffer).expect("did not recieve anything from stdin");
  8.     return buffer;
  9. }
  10.  
  11.  
  12. #[derive(Debug, Clone, Hash, PartialEq, Eq)]
  13. struct Coord{
  14.     x: i64,
  15.     y: i64,
  16.     z: i64
  17. }
  18.  
  19. impl Coord{
  20.     fn add(&self, other: &Coord) -> Coord{
  21.         return Coord{
  22.             x: self.x + other.x,
  23.             y: self.y + other.y,
  24.             z: self.z + other.z
  25.         };
  26.     }
  27.  
  28.     fn sum_of_absolute_coords(&self) -> i64{
  29.         return self.x.abs() + self.y.abs() + self.z.abs();
  30.     }
  31. }
  32.  
  33. #[derive(Debug, Clone, PartialEq, Eq, Hash)]
  34. struct CBody{
  35.     pos: Coord,
  36.     velocity: Coord
  37. }
  38.  
  39. impl CBody{
  40.     fn new(nx: i64, ny: i64, nz: i64) -> CBody{
  41.         CBody{
  42.             pos: Coord{x: nx, y: ny, z: nz},
  43.             velocity: Coord{x: 0, y: 0, z: 0}
  44.         }
  45.     }
  46.     fn update(&mut self){
  47.         self.pos.x += self.velocity.x;
  48.         self.pos.y += self.velocity.y;
  49.         self.pos.z += self.velocity.z;
  50.     }
  51.     fn total_energy(&self) -> i64{
  52.         return self.pos.sum_of_absolute_coords() * self.velocity.sum_of_absolute_coords();
  53.     }
  54. }
  55.  
  56.  
  57.  
  58. fn update_velocities(planets: &mut Vec<CBody>){
  59.  
  60.     for i in 0..(planets.len()){
  61.         for j in (i + 1)..(planets.len()){
  62.             if planets[i].pos.x < planets[j].pos.x{
  63.                 planets[i].velocity.x += 1;          
  64.                 planets[j].velocity.x -= 1;          
  65.             }else if planets[j].pos.x < planets[i].pos.x{
  66.                 planets[j].velocity.x += 1;          
  67.                 planets[i].velocity.x -= 1;          
  68.             }
  69.             if planets[i].pos.y < planets[j].pos.y{
  70.                 planets[i].velocity.y += 1;          
  71.                 planets[j].velocity.y -= 1;          
  72.             }else if planets[j].pos.y < planets[i].pos.y{
  73.                 planets[j].velocity.y += 1;          
  74.                 planets[i].velocity.y -= 1;          
  75.             }
  76.             if planets[i].pos.z < planets[j].pos.z{
  77.                 planets[i].velocity.z += 1;          
  78.                 planets[j].velocity.z -= 1;          
  79.             }else if planets[j].pos.z < planets[i].pos.z{
  80.                 planets[j].velocity.z += 1;          
  81.                 planets[i].velocity.z -= 1;          
  82.             }
  83.         }
  84.     }
  85.  
  86. }
  87.  
  88. fn move_planets(planets: &mut Vec<CBody>){
  89.     for i in 0..(planets.len()){
  90.         planets[i].update();
  91.     }
  92. }
  93.  
  94. fn check_loops(planets: &Vec<CBody>, has_looped: &mut Vec<bool>, steps: &usize){
  95.     if !has_looped[0] && planets.iter()
  96.         .filter(
  97.             |p|
  98.             p.velocity.x != 0
  99.         ).count() == 0{
  100.         println!("x looped at {}", steps);
  101.         has_looped[0] = true;
  102.     }
  103.     if !has_looped[1] && planets.iter()
  104.         .filter(
  105.             |p|
  106.             p.velocity.y != 0
  107.         ).count() == 0{
  108.         println!("y looped at {}", steps);
  109.         has_looped[1] = true;
  110.     }
  111.     if !has_looped[2] && planets.iter()
  112.         .filter(
  113.             |p|
  114.             p.velocity.z != 0
  115.         ).count() == 0{
  116.         println!("z looped at {}", steps);
  117.         has_looped[2] = true;
  118.     }
  119.    
  120. }
  121.  
  122. fn simulate_until(mut planets: Vec<CBody>, count: usize) -> Vec<CBody> {
  123.     let mut steps: usize = 0;
  124.  
  125.     loop{
  126.         update_velocities(&mut planets);
  127.         move_planets(&mut planets);
  128.         steps += 1;
  129.  
  130.         if steps % (count / 10) == 0{
  131.             println!("{}", steps);
  132.         }
  133.  
  134.         if steps == count{
  135.             break;
  136.         }
  137.  
  138.     }
  139.     return planets;
  140. }
  141.  
  142. fn simulate(planets: Vec<CBody>) -> Vec<CBody>{
  143.     let mut new_planets = planets.clone();
  144.     let mut steps: usize = 0;
  145.     let mut has_looped: Vec<bool> = vec![false,false,false];
  146.  
  147.     loop{
  148.         update_velocities(&mut new_planets);
  149.         move_planets(&mut new_planets);
  150.         steps += 1;
  151.  
  152.         check_loops(&new_planets, &mut has_looped, &steps);
  153.  
  154.         if has_looped.iter().filter(|b| !(**b)).count() == 0{
  155.        
  156.             return new_planets;
  157.         }
  158.  
  159.     }
  160.  
  161. }
  162.  
  163. fn energy(planets: &Vec<CBody>) -> i64{
  164.     return
  165.         planets
  166.         .iter()
  167.         .map(|p|
  168.             {
  169.                 //dbg!(&p.pos);
  170.                 //dbg!(&p.velocity);
  171.                 p.total_energy()
  172.             }
  173.         ).sum();
  174.            
  175. }
  176.  
  177. fn main(){
  178.     let pattern = Regex::new(r"<x=(-?\d+), y=(-?\d+), z=(-?\d+)>").unwrap();
  179.  
  180.     let io_input: String = read_stdin();
  181.  
  182.     let planets: Vec<CBody> =
  183.         pattern
  184.         .captures_iter(&io_input)
  185.         .map(|g|
  186.             CBody::new(
  187.                 g[1].parse().unwrap(),
  188.                 g[2].parse().unwrap(),
  189.                 g[3].parse().unwrap()
  190.             )
  191.         ).collect();
  192.    
  193.    
  194.     //let after_sim = simulate(planets);
  195.     let after_sim = simulate_until(planets, 1000000000);
  196.    
  197.     println!("{:?}", after_sim);
  198. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement