Add a tool for importing logs to the DB
This commit is contained in:
parent
e819099f92
commit
8e526c8c17
5 changed files with 113 additions and 13 deletions
30
Cargo.lock
generated
30
Cargo.lock
generated
|
@ -6,6 +6,15 @@ version = "0.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
|
checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.7.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
@ -168,6 +177,7 @@ dependencies = [
|
||||||
"indicatif",
|
"indicatif",
|
||||||
"itertools",
|
"itertools",
|
||||||
"rand",
|
"rand",
|
||||||
|
"regex",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -213,18 +223,21 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.4.2"
|
version = "1.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
|
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
|
"thread_local",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.21"
|
version = "0.6.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
|
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rusqlite"
|
name = "rusqlite"
|
||||||
|
@ -257,6 +270,15 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
|
|
|
@ -12,7 +12,12 @@ rand = "0.8.0"
|
||||||
indicatif = "0.15.0"
|
indicatif = "0.15.0"
|
||||||
itertools = "0.10.0"
|
itertools = "0.10.0"
|
||||||
rusqlite = "0.24.2"
|
rusqlite = "0.24.2"
|
||||||
|
regex = "1.4.3"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "prague"
|
name = "prague"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "import-logs"
|
||||||
|
path = "src/import-logs.rs"
|
||||||
|
|
17
src/db.rs
17
src/db.rs
|
@ -1,5 +1,5 @@
|
||||||
use crate::city::House;
|
use crate::city::House;
|
||||||
use rusqlite::{Connection, NO_PARAMS, params, Result};
|
use rusqlite::{Connection, NO_PARAMS, params, Result, Transaction};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub struct LayoutDB {
|
pub struct LayoutDB {
|
||||||
|
@ -45,15 +45,16 @@ impl LayoutDB {
|
||||||
&self.layouts
|
&self.layouts
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_layout(&self, houses: &Vec<House>, fully_optimized: bool) -> Result<()> {
|
pub fn add_layout(&mut self, houses: &Vec<House>, fully_optimized: bool) -> Result<()> {
|
||||||
self.connection.execute("INSERT INTO layouts (is_fully_optimized) VALUES (?1)",
|
let transaction = self.connection.transaction()?;
|
||||||
params![fully_optimized])?;
|
transaction.execute("INSERT INTO layouts (is_fully_optimized) VALUES (?1)",
|
||||||
let layout_id = self.connection.last_insert_rowid();
|
params![fully_optimized])?;
|
||||||
|
let layout_id = transaction.last_insert_rowid();
|
||||||
for house in houses {
|
for house in houses {
|
||||||
self.connection.execute("INSERT INTO houses (layout_id, x, y) VALUES (?1, ?2, ?3)",
|
transaction.execute("INSERT INTO houses (layout_id, x, y) VALUES (?1, ?2, ?3)",
|
||||||
params![layout_id, house.x as u32, house.y as u32])?;
|
params![layout_id, house.x as u32, house.y as u32])?;
|
||||||
}
|
}
|
||||||
|
transaction.commit()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
72
src/import-logs.rs
Normal file
72
src/import-logs.rs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
use std::io;
|
||||||
|
use std::io::BufRead;
|
||||||
|
use regex::Regex;
|
||||||
|
use crate::city::House;
|
||||||
|
use crate::db::LayoutDB;
|
||||||
|
|
||||||
|
mod city;
|
||||||
|
mod db;
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
Out,
|
||||||
|
ReadPrice,
|
||||||
|
In(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut db = LayoutDB::from_file("layouts.sqlite").expect("Failed to load the DB");
|
||||||
|
let stdin = io::stdin();
|
||||||
|
|
||||||
|
let price_regex = Regex::new("^Price ([0-9]*), seed ([0-9]*)$").unwrap();
|
||||||
|
|
||||||
|
let mut state = State::Out;
|
||||||
|
let mut current_price = String::new();
|
||||||
|
let mut current_seed = String::new();
|
||||||
|
let mut houses = Vec::new();
|
||||||
|
for line in stdin.lock().lines() {
|
||||||
|
let line = line.unwrap();
|
||||||
|
state = match state {
|
||||||
|
State::Out => {
|
||||||
|
if let Some(captures) = price_regex.captures(&line) {
|
||||||
|
let price = captures.get(1).unwrap().as_str().to_string();
|
||||||
|
let seed = captures.get(2).unwrap().as_str().to_string();
|
||||||
|
|
||||||
|
// Ensure we only save the last layout for a seed
|
||||||
|
if seed != current_seed && !houses.is_empty() {
|
||||||
|
eprintln!("Saved house with seed {}, price {}", current_seed, current_price);
|
||||||
|
db.add_layout(&houses, true);
|
||||||
|
} else {
|
||||||
|
houses.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
current_seed = seed;
|
||||||
|
current_price = price;
|
||||||
|
State::ReadPrice
|
||||||
|
} else {
|
||||||
|
State::Out
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State::ReadPrice => {
|
||||||
|
let count: usize = line.parse().expect("Failed to read house count");
|
||||||
|
State::In(count)
|
||||||
|
},
|
||||||
|
State::In(count) => {
|
||||||
|
let mut parts = line.split_whitespace();
|
||||||
|
let x: usize = parts.next().unwrap().parse().expect("Failed to read x");
|
||||||
|
let y: usize = parts.next().unwrap().parse().expect("Failed to read y");
|
||||||
|
houses.push(House {x, y});
|
||||||
|
|
||||||
|
if count == 1 {
|
||||||
|
State::Out
|
||||||
|
} else {
|
||||||
|
State::In(count - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !houses.is_empty() {
|
||||||
|
eprintln!("Saved house with seed {}, price {}", current_seed, current_price);
|
||||||
|
db.add_layout(&houses, true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ mod city;
|
||||||
mod db;
|
mod db;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let db = LayoutDB::from_file("layouts.sqlite").expect("Failed to load the DB");
|
let mut db = LayoutDB::from_file("layouts.sqlite").expect("Failed to load the DB");
|
||||||
eprintln!("Loaded the DB, {} stored layouts", db.layouts().len());
|
eprintln!("Loaded the DB, {} stored layouts", db.layouts().len());
|
||||||
|
|
||||||
let city = City::read_from_file("01.in");
|
let city = City::read_from_file("01.in");
|
||||||
|
|
Loading…
Reference in a new issue