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" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" | 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]] | [[package]] | ||||||
| name = "getrandom" | name = "getrandom" | ||||||
| version = "0.2.0" | version = "0.2.0" | ||||||
|  | @ -23,12 +45,36 @@ dependencies = [ | ||||||
|  "wasi", |  "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]] | [[package]] | ||||||
| name = "libc" | name = "libc" | ||||||
| version = "0.2.81" | version = "0.2.81" | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" | checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "number_prefix" | ||||||
|  | version = "0.3.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a" | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "ppv-lite86" | name = "ppv-lite86" | ||||||
| version = "0.2.10" | version = "0.2.10" | ||||||
|  | @ -40,6 +86,7 @@ name = "prague" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "byteorder", |  "byteorder", | ||||||
|  |  "indicatif", | ||||||
|  "rand", |  "rand", | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
|  | @ -83,8 +130,70 @@ dependencies = [ | ||||||
|  "rand_core", |  "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]] | [[package]] | ||||||
| name = "wasi" | name = "wasi" | ||||||
| version = "0.9.0+wasi-snapshot-preview1" | version = "0.9.0+wasi-snapshot-preview1" | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" | 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] | [dependencies] | ||||||
| byteorder = "1.3.4" | byteorder = "1.3.4" | ||||||
| rand = "0.8.0" | 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 rand::prelude::{StdRng, SliceRandom}; | ||||||
| use byteorder::{LittleEndian, ReadBytesExt}; |  | ||||||
| use rand::prelude::StdRng; |  | ||||||
| use rand::{SeedableRng, Rng, thread_rng}; | use rand::{SeedableRng, Rng, thread_rng}; | ||||||
| 
 | 
 | ||||||
| const SIZE: usize = 16384; | pub const SIZE: usize = 16384; | ||||||
| 
 | 
 | ||||||
| struct City { | pub struct City { | ||||||
|     prices: Vec<u16>, |     prices: Vec<u16>, | ||||||
|     buyable_house_count: usize |     buyable_house_count: usize | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl City { | 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 { |     pub fn new(prices: Vec<u16>) -> Self { | ||||||
|         let mut buyable_house_count = 0; |         let mut buyable_house_count = 0; | ||||||
|         for &price in &prices { |         for &price in &prices { | ||||||
|  | @ -42,7 +54,8 @@ impl City { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct House { | #[derive(Eq, PartialEq, Hash, Copy, Clone)] | ||||||
|  | pub struct House { | ||||||
|     x: usize, |     x: usize, | ||||||
|     y: usize, |     y: usize, | ||||||
| } | } | ||||||
|  | @ -54,18 +67,7 @@ impl House { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn main() { | fn main() { | ||||||
|     let values = std::fs::read("01.in").unwrap(); |     let city = City::read_from_file("01.in"); | ||||||
|     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"); |  | ||||||
| 
 | 
 | ||||||
|     loop { |     loop { | ||||||
|         let seed: u64 = thread_rng().gen(); |         let seed: u64 = thread_rng().gen(); | ||||||
|  | @ -101,16 +103,47 @@ fn main() { | ||||||
|             let finished = claimed_houses == city.get_house_count(); |             let finished = claimed_houses == city.get_house_count(); | ||||||
| 
 | 
 | ||||||
|             if finished { |             if finished { | ||||||
|                 let price = get_price(&city, &houses); |  | ||||||
|                 eprintln!("Price: {}", price); |  | ||||||
|                 //print_houses(&houses);
 |  | ||||||
|                 break; |                 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(); |     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 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) { |         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>) { | fn print_houses(houses: &Vec<House>) { | ||||||
|     eprintln!("{}", houses.len()); |     println!("{}", houses.len()); | ||||||
|     for house in houses { |     for house in houses { | ||||||
|         eprintln!("{} {}", house.y, house.x); |         println!("{} {}", house.y, house.x); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue