diff --git a/Cargo.lock b/Cargo.lock index 506f124..66ac287 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,17 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "ahash" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + [[package]] name = "byteorder" version = "1.3.4" @@ -40,6 +52,18 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "getrandom" version = "0.2.0" @@ -51,6 +75,24 @@ dependencies = [ "wasi", ] +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashlink" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d99cf782f0dc4372d26846bec3de7804ceb5df083c2d4462c0b8d2330e894fa8" +dependencies = [ + "hashbrown", +] + [[package]] name = "indicatif" version = "0.15.0" @@ -84,12 +126,34 @@ version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" +[[package]] +name = "libsqlite3-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d31059f22935e6c31830db5249ba2b7ecd54fd73a9909286f0a67aa55c2fbd" +dependencies = [ + "pkg-config", + "vcpkg", +] + +[[package]] +name = "memchr" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" + [[package]] name = "number_prefix" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a" +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + [[package]] name = "ppv-lite86" version = "0.2.10" @@ -104,6 +168,7 @@ dependencies = [ "indicatif", "itertools", "rand", + "rusqlite", ] [[package]] @@ -161,6 +226,27 @@ version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" +[[package]] +name = "rusqlite" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38ee71cbab2c827ec0ac24e76f82eca723cee92c509a65f67dee393c25112" +dependencies = [ + "bitflags", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "memchr", + "smallvec", +] + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + [[package]] name = "terminal_size" version = "0.1.15" @@ -177,6 +263,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +[[package]] +name = "vcpkg" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index f3460a8..b22e49e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ byteorder = "1.3.4" rand = "0.8.0" indicatif = "0.15.0" itertools = "0.10.0" +rusqlite = "0.24.2" [[bin]] name = "prague" diff --git a/src/db.rs b/src/db.rs new file mode 100644 index 0000000..533dbeb --- /dev/null +++ b/src/db.rs @@ -0,0 +1,59 @@ +use crate::city::House; +use rusqlite::{Connection, NO_PARAMS, params, Result}; +use std::collections::HashMap; + +pub struct LayoutDB { + connection: Connection, + layouts: Vec +} + +pub struct SavedLayout { + id: usize, + houses: Vec +} + +impl LayoutDB { + pub fn from_file(filename: &str) -> Result { + let connection = Connection::open(filename)?; + let mut layouts: HashMap> = HashMap::new(); + + // We need to dispose the statement so we can move the connection later + { + let mut stmt = connection.prepare("SELECT layout_id, x, y FROM houses")?; + let mut rows = stmt.query(NO_PARAMS)?; + + while let Some(row) = rows.next()? { + let id: u32 = row.get(0)?; + let x: u32 = row.get(1)?; + let y: u32 = row.get(2)?; + layouts.entry(id).or_default().push((x, y)); + } + } + + let layouts = layouts.into_iter().map(|(id, xy_pairs)| + SavedLayout + { + id: id as usize, + houses: xy_pairs.into_iter().map(|(x, y)| House { x: x as usize, y: y as usize }).collect(), + } + ).collect(); + + Ok(LayoutDB { connection, layouts }) + } + + pub fn layouts(&self) -> &Vec { + &self.layouts + } + + pub fn add_layout(&self, houses: &Vec, fully_optimized: bool) -> Result<()> { + self.connection.execute("INSERT INTO layouts (is_fully_optimized) VALUES (?1)", + params![fully_optimized])?; + let layout_id = self.connection.last_insert_rowid(); + for house in houses { + self.connection.execute("INSERT INTO houses (layout_id, x, y) VALUES (?1, ?2, ?3)", + params![layout_id, house.x as u32, house.y as u32])?; + } + + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 53ce4b5..c4e33ed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,12 +4,17 @@ use std::fmt; use std::fmt::Formatter; use std::collections::{HashMap, HashSet}; use city::{HouseLayout, City, House}; +use crate::db::LayoutDB; mod optimization; mod population; mod city; +mod db; fn main() { + let 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"); let mut best_price: Option = None; @@ -45,6 +50,7 @@ fn main() { break; } } + db.add_layout(&layout.houses(), true).expect("Failed to insert into DB"); } }