Skip to content
Snippets Groups Projects
Commit 13ccf4e7 authored by Valerian Wintner's avatar Valerian Wintner
Browse files

base attempt at algorithm

parent 76137157
No related branches found
No related tags found
No related merge requests found
......@@ -2,4 +2,127 @@
* A simple graph structure, using
*/
pub fn foo() {}
use std::collections::{HashMap, HashSet};
use std::hash::Hash;
#[derive(PartialOrd, Ord)]
pub enum PlayingNode {
Red { id: String, counter: u32 },
Green { id: String },
}
impl PlayingNode {
pub fn id(&self) -> &String {
match self {
PlayingNode::Red { id, .. } => id,
PlayingNode::Green { id } => id,
}
}
}
impl PartialEq for PlayingNode {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(
Self::Red {
id: l_id,
counter: l_counter,
},
Self::Red {
id: r_id,
counter: r_counter,
},
) => l_id == r_id && l_counter == r_counter,
(Self::Green { id: l_id }, Self::Green { id: r_id }) => l_id == r_id,
(_, _) => false,
}
}
}
impl Eq for PlayingNode {}
impl Hash for PlayingNode {
fn hash<H>(&self, state: &mut H)
where
H: std::hash::Hasher,
{
self.id().hash(state);
}
}
pub type Nodes = Vec<String>;
pub type Predecessors = HashMap<String, HashSet<PlayingNode>>;
pub type Successors = HashMap<String, HashSet<String>>;
pub type WinningPositions = HashSet<String>;
pub type AdditionalWinning = HashSet<String>;
/*
* Insert this node into the winning positions, and also all red nodes that counted down to 0 (recursively) due to being predecessors of an inserted node.
*/
fn insert_node(node: String, additional_winning: &mut AdditionalWinning, pred: &mut Predecessors) {
let mut to_insert = vec![node];
while let Some(node) = to_insert.pop() {
additional_winning.insert(node.clone());
let predecessors = pred.entry(node);
predecessors.and_modify(|predecessors| {
let mut changed_predecessors = HashSet::new();
for predecessor in predecessors.iter() {
if let PlayingNode::Red { id, counter } = predecessor {
let counter = counter - 1;
if counter == 0 {
to_insert.push(id.clone());
} else {
changed_predecessors.insert(PlayingNode::Red {
id: id.clone(),
counter,
});
}
}
}
*predecessors = changed_predecessors
});
}
}
/**
* Calculates new winning positions, iterative step
*/
pub fn pre(
greens: Nodes,
winning_positions: &WinningPositions,
succ: &mut Successors,
pred: &mut Predecessors,
) -> (Nodes, AdditionalWinning) {
let mut additional_winning: AdditionalWinning = HashSet::new();
let mut remaining_greens: Nodes = Vec::new();
for green in greens {
let successors = &succ[&green];
// Intersection between successors of green node and winning positions is empty set
if successors.is_disjoint(winning_positions) {
remaining_greens.push(green);
}
// A successor is in the set of winning positions: Add to it.
else {
insert_node(green, &mut additional_winning, pred);
}
}
(remaining_greens, additional_winning)
}
pub fn winning_positions(
greens: Nodes,
final_positions: WinningPositions,
mut succ: Successors,
mut pred: Predecessors,
) -> WinningPositions {
let mut winning_positions = final_positions;
let mut greens = greens;
loop {
let (changed_greens, additional_winnings) =
pre(greens, &winning_positions, &mut succ, &mut pred);
if additional_winnings.is_empty() {
return winning_positions;
}
greens = changed_greens;
winning_positions.extend(additional_winnings);
}
}
mod arena;
use std::collections::{HashMap, HashSet};
use std::env;
use std::fs::{self, File};
use std::io::{Read, Write};
......@@ -12,6 +13,8 @@ use graphviz_rust::printer::{DotPrinter, PrinterContext};
use graphviz_rust::*;
use graphviz_rust::{exec, parse};
use crate::arena::*;
fn main() {
let mut args = env::args();
let filename = args.next().unwrap();
......@@ -23,6 +26,13 @@ fn main() {
let g2 = change_graph(&g);
let greens: Nodes = Vec::new();
let final_positions: WinningPositions = HashSet::new();
let succ: Successors = HashMap::new();
let pred: Predecessors = HashMap::new();
let _ = arena::winning_positions(greens, final_positions, succ, pred);
output(&g2);
}
......@@ -33,6 +43,7 @@ fn change_graph(g: &Graph) -> Graph {
};
for mut e in stmts.iter_mut() {
if let Stmt::Node(n) = &mut e {
dbg!(&n.attributes);
let attrs = vec![
NodeAttributes::shape(shape::square),
NodeAttributes::fillcolor(color_name::red),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment