From 63ed9e7fe01d98764167d6372dd568a7858a4745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Sejkora?= Date: Wed, 13 Jan 2021 01:43:23 +0100 Subject: [PATCH] Horizontal cuts (through transpose) --- src/combine-layouts.rs | 36 ++++++++++++++++++++++++++++++++---- src/combine.rs | 33 ++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/combine-layouts.rs b/src/combine-layouts.rs index 193543e..58b3dea 100644 --- a/src/combine-layouts.rs +++ b/src/combine-layouts.rs @@ -1,5 +1,5 @@ use db::LayoutDB; -use city::City; +use city::{City, House, SIZE}; use itertools::Itertools; mod city; @@ -18,8 +18,36 @@ fn main() { const TOP_LAYOUT_COUNT: usize = 100; - let chosen_layouts = sorted.iter().take(TOP_LAYOUT_COUNT).map(|l| l.houses()).collect(); - eprintln!("Starting to combine {} top houses DB; vertical cuts", TOP_LAYOUT_COUNT); + let chosen_layouts: Vec<_> = sorted.iter().take(TOP_LAYOUT_COUNT).map(|l| l.houses().clone()).collect(); - combine::try_combine(&city, &chosen_layouts, &chosen_layouts); + //eprintln!("Starting to combine {} top houses DB; vertical cuts", TOP_LAYOUT_COUNT); + //combine::try_combine(&city, &chosen_layouts, &chosen_layouts, false); + + eprintln!("Transposing..."); + let transposed_city = transpose_city(&city); + let transposed_chosen_layouts: Vec<_> = chosen_layouts.iter().map(|x| transpose_layout(x)).collect(); + eprintln!("Starting to combine {} top houses DB; horizontal cuts", TOP_LAYOUT_COUNT); + combine::try_combine(&transposed_city, &transposed_chosen_layouts, &transposed_chosen_layouts, true); +} + +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_layout(houses: &Vec) -> Vec { + let mut transposed = Vec::new(); + for house in houses { + transposed.push(House::new(house.y, house.x)); + } + + transposed } \ No newline at end of file diff --git a/src/combine.rs b/src/combine.rs index e67548b..9b142b4 100644 --- a/src/combine.rs +++ b/src/combine.rs @@ -5,7 +5,7 @@ use itertools::iproduct; use std::collections::VecDeque; use std::collections::vec_deque::Iter; -pub fn try_combine(city: &City, left_layouts: &Vec<&Vec>, right_layouts: &Vec<&Vec>) { +pub fn try_combine(city: &City, left_layouts: &Vec>, right_layouts: &Vec>, print_transposed: bool) { // Sorted in reverse so we can remove from the end let mut left_houses_sorted: Vec> = left_layouts.iter() .map(|l| l.iter().sorted_by(|h1, h2| h2.x.cmp(&h1.x)).map(|x| *x).collect()) @@ -33,7 +33,12 @@ pub fn try_combine(city: &City, left_layouts: &Vec<&Vec>, right_layouts: let mut best_price = None; // x is the last left coordinate, x+1 is right for x in 0..SIZE { - eprintln!("Starting x {}", x); + if print_transposed { + eprintln!("Starting y {}", x); + } else { + eprintln!("Starting x {}", x); + } + // Update the lines for (left_line, left_houses) in lefts.iter_mut().zip(left_houses_sorted.iter_mut()) { while let Some(house) = left_houses.last() { @@ -69,12 +74,22 @@ pub fn try_combine(city: &City, left_layouts: &Vec<&Vec>, right_layouts: if is_compatible(city, &left, &right) { if best_price.is_none() || price < best_price.unwrap() { best_price = Some(price); - eprintln!("{} - new best score, cut on x {}, left {} - right {}, printing", price, x, left_i, right_i); - println!("{} - new best score, cut on x {}, left {} - right {}", price, x, left_i, right_i); - let new_houses: Vec<_> = left.houses().chain(right.houses()).collect(); - println!("{}", new_houses.len()); - for house in new_houses { - println!("{} {}", house.y, house.x); + if print_transposed { + eprintln!("{} - new best score, cut on y {}, left {} - right {}, printing", price, x, left_i, right_i); + println!("{} - new best score, cut on y {}, left {} - right {}", price, x, left_i, right_i); + let new_houses: Vec<_> = left.houses().chain(right.houses()).collect(); + println!("{}", new_houses.len()); + for house in new_houses { + println!("{} {}", house.x, house.y); + } + } else { + eprintln!("{} - new best score, cut on x {}, left {} - right {}, printing", price, x, left_i, right_i); + println!("{} - new best score, cut on x {}, left {} - right {}", price, x, left_i, right_i); + let new_houses: Vec<_> = left.houses().chain(right.houses()).collect(); + println!("{}", new_houses.len()); + for house in new_houses { + println!("{} {}", house.y, house.x); + } } } compatibles += 1; @@ -86,7 +101,7 @@ pub fn try_combine(city: &City, left_layouts: &Vec<&Vec>, right_layouts: } } - eprintln!("{}/{} compatible", compatibles, compatibles + incompatibles); + eprintln!("{} incompatibles checked before {} compatible", incompatibles, compatibles); } }