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