From 0a273d659472abe0ae9a454cb77e1520ce3e4d3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Sejkora?= Date: Wed, 23 Dec 2020 04:16:16 +0100 Subject: [PATCH] Random generation --- Cargo.lock | 90 +++++++++++++++++++++++++++++ Cargo.toml | 11 ++++ src/main.rs | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 260 insertions(+) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..6bc4ce7 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,90 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "getrandom" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "prague" +version = "0.1.0" +dependencies = [ + "byteorder", + "rand", +] + +[[package]] +name = "rand" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76330fb486679b4ace3670f117bbc9e16204005c4bde9c4bd372f45bed34f12" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8b34ba8cfb21243bd8df91854c830ff0d785fff2e82ebd4434c2644cb9ada18" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ff5f70a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "prague" +version = "0.1.0" +authors = ["Jiří Sejkora "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +byteorder = "1.3.4" +rand = "0.8.0" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..281ca80 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,159 @@ +use std::fs::File; +use byteorder::{LittleEndian, ReadBytesExt}; +use rand::prelude::StdRng; +use rand::{SeedableRng, Rng, thread_rng}; + +const SIZE: usize = 16384; + +struct City { + prices: Vec, + buyable_house_count: usize +} + +impl City { + pub fn new(prices: Vec) -> Self { + let mut buyable_house_count = 0; + for &price in &prices { + if price > 0 { + buyable_house_count += 1; + } + } + City { prices, buyable_house_count } + } + + pub fn get_price(&self, house: &House) -> u16 { + self.prices[house.y * SIZE + house.x] + } + + pub fn is_house(&self, house: &House) -> bool { + self.get_price(&house) > 0 + } + + pub fn get_house_count(&self) -> usize { + self.buyable_house_count + } +} + +struct House { + x: usize, + y: usize, +} + +impl House { + pub fn new(x: usize, y: usize) -> Self { + House { x, y } + } +} + +fn main() { + let values = std::fs::read("01.in").unwrap(); + let mut prices: Vec = 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 { + let seed: u64 = thread_rng().gen(); + eprintln!("Starting seed {}", seed); + + let mut rng = StdRng::seed_from_u64(seed); + let mut reachable = vec![false; SIZE * SIZE]; + let mut houses: Vec = Vec::new(); + let mut claimed_houses = 0; + loop { + loop { + let x = rng.gen_range(0..SIZE); + let y = rng.gen_range(0..SIZE); + let house = House::new(x, y); + if city.is_house(&house) && !reachable[y * SIZE + x] { + 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) { + let index = y as usize * SIZE + x as usize; + if !reachable[index] { + reachable[index] = true; + if city.is_house(&House::new(x as usize, y as usize)) { + claimed_houses += 1; + } + } + } + } + houses.push(house); + //eprintln!("{} houses", houses.len()); + break; + } + } + + let finished = claimed_houses == city.get_house_count(); + + if finished { + let price = get_price(&city, &houses); + eprintln!("Price: {}", price); + //print_houses(&houses); + break; + } + } + } +} + +fn get_neighbors(city: &City, house: &House) -> Vec { + 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) { + let house = House::new(x as usize, y as usize); + if city.get_price(&house) > 0 { + neighbors.push(house); + } + } + } + + neighbors +} + +fn print_houses(houses: &Vec) { + eprintln!("{}", houses.len()); + for house in houses { + eprintln!("{} {}", house.y, house.x); + } +} + +fn get_price(city: &City, houses: &Vec) -> u32 { + let mut price = 0u32; + for house in houses { + price += city.get_price(&house) as u32; + } + + price +} + +fn is_valid(city: &City, houses: &Vec) -> Option { + let mut reachable = vec![false; SIZE * SIZE]; + let mut price = 0u32; + + for house in houses { + assert!(city.prices[house.y * SIZE + house.x] > 0); + + 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) { + reachable[y as usize * SIZE + x as usize] = true; + } + } + price += city.get_price(&house) as u32; + } + + for y in 0..SIZE { + for x in 0..SIZE { + if !reachable[y * SIZE + x] && city.prices[y * SIZE + x] > 0 { + return None; + } + } + } + + Some(price) +}