Randomized improvements
Randomly choose one close cheaper house and try to move there.
This commit is contained in:
		
							parent
							
								
									748d9eaacd
								
							
						
					
					
						commit
						3d17279613
					
				
					 4 changed files with 228 additions and 24 deletions
				
			
		
							
								
								
									
										109
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										109
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							|  | @ -12,6 +12,28 @@ version = "0.1.10" | |||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "console" | ||||
| version = "0.13.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a50aab2529019abfabfa93f1e6c41ef392f91fbf179b347a7e96abb524884a08" | ||||
| dependencies = [ | ||||
|  "encode_unicode", | ||||
|  "lazy_static", | ||||
|  "libc", | ||||
|  "regex", | ||||
|  "terminal_size", | ||||
|  "unicode-width", | ||||
|  "winapi", | ||||
|  "winapi-util", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "encode_unicode" | ||||
| version = "0.3.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "getrandom" | ||||
| version = "0.2.0" | ||||
|  | @ -23,12 +45,36 @@ dependencies = [ | |||
|  "wasi", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "indicatif" | ||||
| version = "0.15.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4" | ||||
| dependencies = [ | ||||
|  "console", | ||||
|  "lazy_static", | ||||
|  "number_prefix", | ||||
|  "regex", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "lazy_static" | ||||
| version = "1.4.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "libc" | ||||
| version = "0.2.81" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "number_prefix" | ||||
| version = "0.3.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "ppv-lite86" | ||||
| version = "0.2.10" | ||||
|  | @ -40,6 +86,7 @@ name = "prague" | |||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "byteorder", | ||||
|  "indicatif", | ||||
|  "rand", | ||||
| ] | ||||
| 
 | ||||
|  | @ -83,8 +130,70 @@ dependencies = [ | |||
|  "rand_core", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "regex" | ||||
| version = "1.4.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" | ||||
| dependencies = [ | ||||
|  "regex-syntax", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "regex-syntax" | ||||
| version = "0.6.21" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "terminal_size" | ||||
| version = "0.1.15" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4bd2d183bd3fac5f5fe38ddbeb4dc9aec4a39a9d7d59e7491d900302da01cbe1" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
|  "winapi", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "unicode-width" | ||||
| version = "0.1.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "wasi" | ||||
| version = "0.9.0+wasi-snapshot-preview1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "winapi" | ||||
| version = "0.3.9" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" | ||||
| dependencies = [ | ||||
|  "winapi-i686-pc-windows-gnu", | ||||
|  "winapi-x86_64-pc-windows-gnu", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "winapi-i686-pc-windows-gnu" | ||||
| version = "0.4.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "winapi-util" | ||||
| version = "0.1.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" | ||||
| dependencies = [ | ||||
|  "winapi", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "winapi-x86_64-pc-windows-gnu" | ||||
| version = "0.4.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" | ||||
|  |  | |||
|  | @ -9,3 +9,12 @@ edition = "2018" | |||
| [dependencies] | ||||
| byteorder = "1.3.4" | ||||
| rand = "0.8.0" | ||||
| indicatif = "0.15.0" | ||||
| 
 | ||||
| [[bin]] | ||||
| name = "prague" | ||||
| path = "src/main.rs" | ||||
| 
 | ||||
| [[bin]] | ||||
| name = "find-useless" | ||||
| path = "src/find_useless.rs" | ||||
|  |  | |||
							
								
								
									
										53
									
								
								src/find_useless.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/find_useless.rs
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,53 @@ | |||
| use indicatif::{ProgressBar, ProgressStyle}; | ||||
| use std::collections::HashSet; | ||||
| use main::{get_neighbors, House, City}; | ||||
| 
 | ||||
| mod main; | ||||
| 
 | ||||
| fn main() { | ||||
|     let city = City::read_from_file("01.in"); | ||||
|     let bar = ProgressBar::new(city.get_house_count() as u64); | ||||
|     bar.set_style(ProgressStyle::default_bar() | ||||
|         .template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({msg}) ({eta})") | ||||
|         .progress_chars("#>-")); | ||||
| 
 | ||||
|     let mut useless_count = 0; | ||||
|     let mut checked_count = 0; | ||||
|     for y in 0..main::SIZE { | ||||
|         for x in 0..main::SIZE { | ||||
|             if city.is_house_xy(x, y) { | ||||
|                 let house = House::new(x, y); | ||||
| 
 | ||||
|                 let house_neighbors = get_neighbors(&city, &house); | ||||
|                 let mut useless = true; | ||||
|                 for neighbor in &house_neighbors { | ||||
|                     if city.get_price(&house) < city.get_price(&neighbor) { | ||||
|                         useless = false; | ||||
|                         break; | ||||
|                     } | ||||
|                     let neighbor_neighbors: HashSet<_> = get_neighbors(&city, &neighbor).into_iter().collect(); | ||||
|                     // Check if house_neighbors is a subset of neighbor_neighbors
 | ||||
|                     let all_in = &house_neighbors.iter().all(|item| neighbor_neighbors.contains(item)); | ||||
|                     if !all_in { | ||||
|                         useless = false; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if useless { | ||||
|                     println!("{} {}", y, x); | ||||
|                     useless_count += 1; | ||||
|                 } else { | ||||
|                     //println!("Y{} X{} may be sometimes worth buying", y, x);
 | ||||
|                 } | ||||
| 
 | ||||
|                 checked_count += 1; | ||||
|                 bar.set_message(&*format!("{}, {:.2}%", useless_count, 100.0 * useless_count as f64/checked_count as f64)); | ||||
|                 bar.inc(1); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     bar.finish(); | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										81
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								src/main.rs
									
									
									
									
									
								
							|  | @ -1,16 +1,28 @@ | |||
| use std::fs::File; | ||||
| use byteorder::{LittleEndian, ReadBytesExt}; | ||||
| use rand::prelude::StdRng; | ||||
| use rand::prelude::{StdRng, SliceRandom}; | ||||
| use rand::{SeedableRng, Rng, thread_rng}; | ||||
| 
 | ||||
| const SIZE: usize = 16384; | ||||
| pub const SIZE: usize = 16384; | ||||
| 
 | ||||
| struct City { | ||||
| pub struct City { | ||||
|     prices: Vec<u16>, | ||||
|     buyable_house_count: usize | ||||
| } | ||||
| 
 | ||||
| impl City { | ||||
|     pub fn read_from_file(filename: &str) -> Self { | ||||
|         let values = std::fs::read(filename).unwrap(); | ||||
|         let mut prices: Vec<u16> = Vec::new(); | ||||
| 
 | ||||
|         for y in 0..SIZE { | ||||
|             for x in 0..SIZE { | ||||
|                 let price = (values[(y * SIZE + x) * 2] as u16) | ((values[(y * SIZE + x) * 2] as u16) << 8); | ||||
|                 prices.push(price); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         City::new(prices) | ||||
|     } | ||||
| 
 | ||||
|     pub fn new(prices: Vec<u16>) -> Self { | ||||
|         let mut buyable_house_count = 0; | ||||
|         for &price in &prices { | ||||
|  | @ -42,7 +54,8 @@ impl City { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| struct House { | ||||
| #[derive(Eq, PartialEq, Hash, Copy, Clone)] | ||||
| pub struct House { | ||||
|     x: usize, | ||||
|     y: usize, | ||||
| } | ||||
|  | @ -54,18 +67,7 @@ impl House { | |||
| } | ||||
| 
 | ||||
| fn main() { | ||||
|     let values = std::fs::read("01.in").unwrap(); | ||||
|     let mut prices: Vec<u16> = Vec::new(); | ||||
| 
 | ||||
|     for y in 0..SIZE { | ||||
|         for x in 0..SIZE { | ||||
|             let price = (values[(y * SIZE + x) * 2] as u16) | ((values[(y * SIZE + x) * 2] as u16) << 8); | ||||
|             prices.push(price); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let city = City::new(prices); | ||||
|     println!("Created city"); | ||||
|     let city = City::read_from_file("01.in"); | ||||
| 
 | ||||
|     loop { | ||||
|         let seed: u64 = thread_rng().gen(); | ||||
|  | @ -101,16 +103,47 @@ fn main() { | |||
|             let finished = claimed_houses == city.get_house_count(); | ||||
| 
 | ||||
|             if finished { | ||||
|                 let price = get_price(&city, &houses); | ||||
|                 eprintln!("Price: {}", price); | ||||
|                 //print_houses(&houses);
 | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         let mut price = get_price(&city, &houses); | ||||
|         eprintln!("Finished randomized init, price: {}", price); | ||||
|         loop { | ||||
|             let house = &houses.choose(&mut rng).unwrap(); | ||||
|             let mut new_candidate: Option<House> = None; | ||||
|             for _ in 0..5000 { | ||||
|                 let delta_x = rng.gen_range(-50..=50); | ||||
|                 let delta_y = rng.gen_range(-50..=50); | ||||
|                 let new_x = (house.x as i32 + delta_x).max(0).min(SIZE as i32 - 1) as usize; | ||||
|                 let new_y = (house.y as i32 + delta_y).max(0).min(SIZE as i32 - 1) as usize; | ||||
|                 if city.is_house_xy(new_x, new_y) && city.get_price_xy(new_x, new_y) < city.get_price(&house) { | ||||
|                     new_candidate = Some(House::new(new_x, new_y)); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if let Some(candidate) = new_candidate { | ||||
|                 eprint!("Found candidate..."); | ||||
|                 let mut new_houses: Vec<_> = houses.to_vec().into_iter().filter(|h| &h != house).collect(); | ||||
|                 new_houses.push(candidate); | ||||
|                 if let Some(new_price) = is_valid(&city, &new_houses) { | ||||
|                     let price_diff = new_price as i64 - price as i64; | ||||
|                     eprintln!(" candidate is valid, price diff: {}.", price_diff); | ||||
|                     eprintln!("New price: {}", new_price); | ||||
|                     price = new_price; | ||||
|                     houses = new_houses; | ||||
|                     print_houses(&houses); | ||||
|                 } else { | ||||
|                     eprintln!(" candidate is invalid."); | ||||
|                 } | ||||
|             } else { | ||||
|                 eprintln!("Did not find candidate"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn get_neighbors(city: &City, house: &House) -> Vec<House> { | ||||
| pub fn get_neighbors(city: &City, house: &House) -> Vec<House> { | ||||
|     let mut neighbors = Vec::new(); | ||||
|     for y in (house.y as i32 - 500).max(0)..=(house.y as i32 + 500).min((SIZE - 1) as i32) { | ||||
|         for x in (house.x as i32 - 500).max(0)..=(house.x as i32 + 500).min((SIZE - 1) as i32) { | ||||
|  | @ -125,9 +158,9 @@ fn get_neighbors(city: &City, house: &House) -> Vec<House> { | |||
| } | ||||
| 
 | ||||
| fn print_houses(houses: &Vec<House>) { | ||||
|     eprintln!("{}", houses.len()); | ||||
|     println!("{}", houses.len()); | ||||
|     for house in houses { | ||||
|         eprintln!("{} {}", house.y, house.x); | ||||
|         println!("{} {}", house.y, house.x); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue