83 lines
3.1 KiB
Rust
83 lines
3.1 KiB
Rust
use db::{LayoutDB, SavedLayout};
|
|
use city::{City, House, SIZE};
|
|
use itertools::Itertools;
|
|
use crate::combine::transpose_layout;
|
|
|
|
mod city;
|
|
mod db;
|
|
mod combine;
|
|
|
|
#[derive(Eq, PartialEq)]
|
|
enum LastStep {
|
|
None, Vertical, Horizontal
|
|
}
|
|
|
|
fn main() {
|
|
let mut db = LayoutDB::from_file("layouts.sqlite").expect("Failed to load the DB");
|
|
eprintln!("Loaded the DB, {} stored layouts", db.layouts().len());
|
|
|
|
let city = City::read_from_file("01.in");
|
|
eprintln!("Loaded the city file, {} houses", city.get_house_count());
|
|
|
|
eprintln!("Building a transposed city...");
|
|
let transposed_city = transpose_city(&city);
|
|
eprintln!("Finished building a transposed city");
|
|
|
|
const TOP_LAYOUT_COUNT: usize = 300;
|
|
|
|
let mut cache = combine::CompatibilityCache::new();
|
|
|
|
let mut last_improve_step = LastStep::None;
|
|
loop {
|
|
if last_improve_step == LastStep::Vertical { break; }
|
|
eprintln!("Starting to combine {} top houses DB; vertical cuts", TOP_LAYOUT_COUNT);
|
|
let sorted: Vec<SavedLayout> = db.layouts().iter()
|
|
.sorted_by(|x, y| city::get_price(&city, x.houses()).cmp(&city::get_price(&city, y.houses())))
|
|
.map(|layout| (*layout).clone())
|
|
.collect();
|
|
let chosen_layouts: Vec<_> = sorted.into_iter().take(TOP_LAYOUT_COUNT).collect();
|
|
if combine::try_combine(&city, &chosen_layouts, &chosen_layouts, &mut db, &mut cache, false) {
|
|
last_improve_step = LastStep::Vertical;
|
|
}
|
|
eprintln!("Finished vertical cuts, improvement: {}", last_improve_step == LastStep::Vertical);
|
|
|
|
if last_improve_step == LastStep::Horizontal { break; }
|
|
|
|
let sorted: Vec<SavedLayout> = db.layouts().iter()
|
|
.sorted_by(|x, y| city::get_price(&city, x.houses()).cmp(&city::get_price(&city, y.houses())))
|
|
.map(|layout| (*layout).clone())
|
|
.collect();
|
|
let chosen_layouts: Vec<_> = sorted.into_iter().take(TOP_LAYOUT_COUNT).collect();
|
|
let transposed_chosen_layouts: Vec<_> = chosen_layouts.iter().map(|x| transpose_saved_layout(x)).collect();
|
|
|
|
eprintln!("Starting to combine {} top houses DB; horizontal cuts", TOP_LAYOUT_COUNT);
|
|
if combine::try_combine(&transposed_city, &transposed_chosen_layouts, &transposed_chosen_layouts, &mut db, &mut cache, true) {
|
|
last_improve_step = LastStep::Horizontal;
|
|
}
|
|
eprintln!("Finished horizontal cuts, improvement: {}", last_improve_step == LastStep::Horizontal);
|
|
|
|
if last_improve_step == LastStep::None { break; }
|
|
}
|
|
}
|
|
|
|
fn transpose_city(city: &City) -> City {
|
|
let mut transposed_prices = vec![0u16; SIZE * SIZE];
|
|
for y in 0..SIZE {
|
|
for x in 0..SIZE {
|
|
// Sorry, cache! Not worth optimizing with blocks,
|
|
// this is not going to be ran often.
|
|
transposed_prices[y * SIZE + x] = city.get_price_xy(y, x);
|
|
}
|
|
}
|
|
|
|
City::new(transposed_prices)
|
|
}
|
|
|
|
fn transpose_saved_layout(layout: &SavedLayout) -> SavedLayout {
|
|
let mut transposed = Vec::new();
|
|
for house in layout.houses() {
|
|
transposed.push(House::new(house.y, house.x));
|
|
}
|
|
|
|
SavedLayout::new(layout.id(), transposed)
|
|
}
|