Jirka Sejkora
4 years ago
commit
0a273d6594
3 changed files with 260 additions and 0 deletions
@ -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" |
@ -0,0 +1,11 @@ |
|||
[package] |
|||
name = "prague" |
|||
version = "0.1.0" |
|||
authors = ["Jiří Sejkora <sejsel@sejsel.cz>"] |
|||
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" |
@ -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<u16>, |
|||
buyable_house_count: usize |
|||
} |
|||
|
|||
impl City { |
|||
pub fn new(prices: Vec<u16>) -> 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<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 { |
|||
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<House> = 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<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) { |
|||
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<House>) { |
|||
eprintln!("{}", houses.len()); |
|||
for house in houses { |
|||
eprintln!("{} {}", house.y, house.x); |
|||
} |
|||
} |
|||
|
|||
fn get_price(city: &City, houses: &Vec<House>) -> u32 { |
|||
let mut price = 0u32; |
|||
for house in houses { |
|||
price += city.get_price(&house) as u32; |
|||
} |
|||
|
|||
price |
|||
} |
|||
|
|||
fn is_valid(city: &City, houses: &Vec<House>) -> Option<u32> { |
|||
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) |
|||
} |
Loading…
Reference in new issue