Prepare dijkstra in path command

This commit is contained in:
Joscha 2022-10-22 16:23:35 +02:00
parent 67f405a21e
commit 8b62ff78bd
2 changed files with 57 additions and 22 deletions

View file

@ -2,32 +2,67 @@ use std::fs::File;
use std::io::{self, BufReader}; use std::io::{self, BufReader};
use std::path::Path; use std::path::Path;
use crate::data::AdjacencyList; use crate::data::{AdjacencyList, Page, PageInfo};
use crate::util; use crate::util;
fn find_index_of_title(pages: &[Page<PageInfo>], title: &str) -> u32 {
let title = util::normalize_link(title);
pages
.iter()
.enumerate()
.filter(|(_, p)| !p.data.redirect)
.find(|(_, p)| util::normalize_link(&p.data.title) == title)
.map(|(i, _)| i)
.expect("invalid title") as u32
}
struct DijkstraPageInfo {
distance: u32,
prev_page_idx: u32,
}
impl Default for DijkstraPageInfo {
fn default() -> Self {
Self {
distance: u32::MAX,
prev_page_idx: u32::MAX,
}
}
}
fn dijkstra(
mut data: AdjacencyList<DijkstraPageInfo, ()>,
from_idx: u32,
to_idx: u32,
) -> Option<Vec<u32>> {
todo!()
}
pub fn path(datafile: &Path, from: &str, to: &str) -> io::Result<()> { pub fn path(datafile: &Path, from: &str, to: &str) -> io::Result<()> {
eprintln!(">> Import"); println!(">> Import");
let mut databuf = BufReader::new(File::open(datafile)?); let mut databuf = BufReader::new(File::open(datafile)?);
let data = AdjacencyList::read(&mut databuf)?; let data = AdjacencyList::read(&mut databuf)?;
let pages = data.pages.clone();
let data = data
.change_page_data(&|_| DijkstraPageInfo::default())
.change_link_data(&|_| ());
eprintln!(">> Locate from and to"); println!(">> Locate from and to");
let from = util::normalize_link(from); let from_idx = find_index_of_title(&pages, from);
let to = util::normalize_link(to); let to_idx = find_index_of_title(&pages, to);
let (from_i, from_p) = data
.pages println!(">> Find path");
.iter() let path = dijkstra(data, from_idx, to_idx);
.enumerate()
.filter(|(_, p)| !p.data.redirect) if let Some(path) = path {
.find(|(_, p)| util::normalize_link(&p.data.title) == from) println!("Path found:");
.unwrap_or_else(|| panic!("no article called {from}")); for page_idx in path {
let (to_i, to_p) = data let page = &pages[page_idx as usize];
.pages println!(" - {}", page.data.title);
.iter() }
.enumerate() } else {
.filter(|(_, p)| !p.data.redirect) println!("No path found");
.find(|(_, p)| util::normalize_link(&p.data.title) == to) }
.unwrap_or_else(|| panic!("no article called {to}"));
dbg!(from_i, from_p, to_i, to_p);
Ok(()) Ok(())
} }

View file

@ -217,7 +217,7 @@ impl AdjacencyList<PageInfo, LinkInfo> {
} }
impl<P, L> AdjacencyList<P, L> { impl<P, L> AdjacencyList<P, L> {
pub fn change_page_data<P2: Clone>(self, page_f: &impl Fn(P) -> P2) -> AdjacencyList<P2, L> { pub fn change_page_data<P2>(self, page_f: &impl Fn(P) -> P2) -> AdjacencyList<P2, L> {
let pages = self let pages = self
.pages .pages
.into_iter() .into_iter()
@ -230,7 +230,7 @@ impl<P, L> AdjacencyList<P, L> {
} }
} }
pub fn change_link_data<L2: Clone>(self, link_f: &impl Fn(L) -> L2) -> AdjacencyList<P, L2> { pub fn change_link_data<L2>(self, link_f: &impl Fn(L) -> L2) -> AdjacencyList<P, L2> {
let links = self let links = self
.links .links
.into_iter() .into_iter()