Browse Source

Randomized improvements

Randomly choose one close cheaper house and try to move there.
master
Jirka Sejkora 3 years ago
parent
commit
3d17279613
  1. 109
      Cargo.lock
  2. 9
      Cargo.toml
  3. 53
      src/find_useless.rs
  4. 81
      src/main.rs

109
Cargo.lock

@ -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
Cargo.toml

@ -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

@ -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

@ -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…
Cancel
Save