September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -1,93 +1,187 @@
|
|||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string input = {
|
||||
"des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee\n"
|
||||
"dw01 ieee dw01 dware gtech\n"
|
||||
"dw02 ieee dw02 dware\n"
|
||||
"dw03 std synopsys dware dw03 dw02 dw01 ieee gtech\n"
|
||||
"dw04 dw04 ieee dw01 dware gtech\n"
|
||||
"dw05 dw05 ieee dware\n"
|
||||
"dw06 dw06 ieee dware\n"
|
||||
"dw07 ieee dware\n"
|
||||
"dware ieee dware\n"
|
||||
"gtech ieee gtech\n"
|
||||
"ramlib std ieee\n"
|
||||
"std_cell_lib ieee std_cell_lib\n"
|
||||
"synopsys\n"
|
||||
"cycle_11 cycle_12\n"
|
||||
"cycle_12 cycle_11\n"
|
||||
"cycle_21 dw01 cycle_22 dw02 dw03\n"
|
||||
"cycle_22 cycle_21 dw01 dw04" };
|
||||
|
||||
class TopSort {
|
||||
|
||||
public:
|
||||
TopSort(const string& input){
|
||||
stringstream ss(input);
|
||||
string buf;
|
||||
|
||||
while(getline(ss, buf)){
|
||||
stringstream ls(buf);
|
||||
string target, subtarget;
|
||||
ls >> target;
|
||||
|
||||
while(ls >> subtarget){
|
||||
if(target.compare(subtarget) == 0)
|
||||
continue;
|
||||
|
||||
dependencies.emplace(subtarget, 0);
|
||||
parents[subtarget].push_back(target);
|
||||
++dependencies[target];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void solve(){
|
||||
for(const auto& pair : dependencies)
|
||||
if(pair.second == 0)
|
||||
sorted.push_back(pair.first);
|
||||
|
||||
for(unsigned int i = 0; i < sorted.size(); ++i){
|
||||
string target = sorted[i];
|
||||
|
||||
for(string& parent : parents[target])
|
||||
if(--dependencies[parent] == 0)
|
||||
sorted.push_back(parent);
|
||||
}
|
||||
|
||||
for(const auto& pair : dependencies)
|
||||
if(pair.second != 0)
|
||||
unorderable.push_back(pair.first);
|
||||
}
|
||||
|
||||
friend ostream& operator<<(ostream& os, const TopSort& ts) {
|
||||
for(const string& s : ts.sorted)
|
||||
os << s << endl;
|
||||
if(ts.unorderable.size() > 0){
|
||||
cout << "Unorderable:" << endl;
|
||||
for(const string& s : ts.unorderable)
|
||||
os << s << endl;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
vector<string> sorted;
|
||||
vector<string> unorderable;
|
||||
|
||||
unordered_map<string, int> dependencies;
|
||||
unordered_map<string, vector<string>> parents;
|
||||
template <typename Goal>
|
||||
class topological_sorter
|
||||
{
|
||||
protected:
|
||||
struct relations
|
||||
{
|
||||
std::size_t
|
||||
dependencies;
|
||||
std::set<Goal>
|
||||
dependents;
|
||||
};
|
||||
std::map<Goal, relations>
|
||||
map;
|
||||
public:
|
||||
void
|
||||
add_goal(Goal const& goal)
|
||||
{
|
||||
map[goal];
|
||||
}
|
||||
void
|
||||
add_dependency(Goal const& goal, Goal const& dependency)
|
||||
{
|
||||
if(dependency == goal)
|
||||
return;
|
||||
auto&
|
||||
dependents = map[dependency].dependents;
|
||||
if(dependents.find(goal) == dependents.end())
|
||||
{
|
||||
dependents.insert(goal);
|
||||
++map[goal].dependencies;
|
||||
}
|
||||
}
|
||||
template <typename Container>
|
||||
void
|
||||
add_dependencies(Goal const& goal, Container const& dependencies)
|
||||
{
|
||||
for(auto const& dependency : dependencies)
|
||||
add_dependency(goal, dependency);
|
||||
}
|
||||
template <typename ResultContainer, typename CyclicContainer>
|
||||
void
|
||||
destructive_sort(ResultContainer& sorted, CyclicContainer& unsortable)
|
||||
{
|
||||
sorted.clear();
|
||||
unsortable.clear();
|
||||
for(auto const& lookup : map)
|
||||
{
|
||||
auto const&
|
||||
goal = lookup.first,
|
||||
relations = lookup.second;
|
||||
if(relations.dependencies == 0)
|
||||
sorted.push_back(goal);
|
||||
}
|
||||
for(std::size_t index = 0; index < sorted.size(); ++index)
|
||||
for(auto const& goal : map[sorted[index]].dependents)
|
||||
if(--map[goal].dependencies == 0)
|
||||
sorted.push_back(goal);
|
||||
for(auto const& lookup : map)
|
||||
{
|
||||
auto const&
|
||||
goal = lookup.first,
|
||||
relations = lookup.second;
|
||||
if(relations.dependencies != 0)
|
||||
unsortable.push_back(goal);
|
||||
}
|
||||
}
|
||||
template <typename ResultContainer, typename CyclicContainer>
|
||||
void
|
||||
sort(ResultContainer& sorted, CyclicContainer& unsortable)
|
||||
{
|
||||
topological_sorter<Goal>
|
||||
temporary = *this;
|
||||
temporary.destructive_sort(sorted, unsortable);
|
||||
}
|
||||
void
|
||||
clear()
|
||||
{
|
||||
map.clear();
|
||||
}
|
||||
};
|
||||
|
||||
int main () {
|
||||
TopSort ts(input);
|
||||
ts.solve();
|
||||
cout << ts;
|
||||
/*
|
||||
Example usage with text strings
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace
|
||||
std;
|
||||
|
||||
void
|
||||
display_heading(string const& message)
|
||||
{
|
||||
cout << endl << "~ " << message << " ~" << endl;
|
||||
}
|
||||
void
|
||||
display_results(string const& input)
|
||||
{
|
||||
topological_sorter<string>
|
||||
sorter;
|
||||
vector<string>
|
||||
sorted,
|
||||
unsortable;
|
||||
stringstream
|
||||
lines(input);
|
||||
string
|
||||
line;
|
||||
while(getline(lines, line))
|
||||
{
|
||||
stringstream
|
||||
buffer(line);
|
||||
string
|
||||
goal,
|
||||
dependency;
|
||||
buffer >> goal;
|
||||
sorter.add_goal(goal);
|
||||
while(buffer >> dependency)
|
||||
sorter.add_dependency(goal, dependency);
|
||||
}
|
||||
sorter.destructive_sort(sorted, unsortable);
|
||||
if(sorted.size() == 0)
|
||||
display_heading("Error: no independent variables found!");
|
||||
else
|
||||
{
|
||||
display_heading("Result");
|
||||
for(auto const& goal : sorted)
|
||||
cout << goal << endl;
|
||||
}
|
||||
if(unsortable.size() != 0)
|
||||
{
|
||||
display_heading("Error: cyclic dependencies detected!");
|
||||
for(auto const& goal : unsortable)
|
||||
cout << goal << endl;
|
||||
}
|
||||
}
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
if(argc == 1)
|
||||
{
|
||||
string
|
||||
example =
|
||||
"des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee\n"
|
||||
"dw01 ieee dw01 dware gtech\n"
|
||||
"dw02 ieee dw02 dware\n"
|
||||
"dw03 std synopsys dware dw03 dw02 dw01 ieee gtech\n"
|
||||
"dw04 dw04 ieee dw01 dware gtech\n"
|
||||
"dw05 dw05 ieee dware\n"
|
||||
"dw06 dw06 ieee dware\n"
|
||||
"dw07 ieee dware\n"
|
||||
"dware ieee dware\n"
|
||||
"gtech ieee gtech\n"
|
||||
"ramlib std ieee\n"
|
||||
"std_cell_lib ieee std_cell_lib\n"
|
||||
"synopsys\n"
|
||||
"cycle_11 cycle_12\n"
|
||||
"cycle_12 cycle_11\n"
|
||||
"cycle_21 dw01 cycle_22 dw02 dw03\n"
|
||||
"cycle_22 cycle_21 dw01 dw04";
|
||||
display_heading("Example: each line starts with a goal followed by it's dependencies");
|
||||
cout << example << endl;
|
||||
display_results(example);
|
||||
display_heading("Enter lines of data (press enter when finished)");
|
||||
string
|
||||
line,
|
||||
data;
|
||||
while(getline(cin, line) && !line.empty())
|
||||
data += line + '\n';
|
||||
if(!data.empty())
|
||||
display_results(data);
|
||||
}
|
||||
else while(*(++argv))
|
||||
{
|
||||
ifstream
|
||||
file(*argv);
|
||||
typedef istreambuf_iterator<char>
|
||||
iterator;
|
||||
display_results(string(iterator(file), iterator()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
57
Task/Topological-sort/JavaScript/topological-sort-1.js
Normal file
57
Task/Topological-sort/JavaScript/topological-sort-1.js
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
const libs =
|
||||
`des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee
|
||||
dw01 ieee dw01 dware gtech
|
||||
dw02 ieee dw02 dware
|
||||
dw03 std synopsys dware dw03 dw02 dw01 ieee gtech
|
||||
dw04 dw04 ieee dw01 dware gtech
|
||||
dw05 dw05 ieee dware
|
||||
dw06 dw06 ieee dware
|
||||
dw07 ieee dware
|
||||
dware ieee dware
|
||||
gtech ieee gtech
|
||||
ramlib std ieee
|
||||
std_cell_lib ieee std_cell_lib
|
||||
synopsys`;
|
||||
|
||||
// A map of the input data, with the keys as the packages, and the values as
|
||||
// and array of packages on which it depends.
|
||||
const D = libs
|
||||
.split('\n')
|
||||
.map(e => e.split(' ').filter(e => e != ''))
|
||||
.reduce((p, c) =>
|
||||
p.set(c[0], c.filter((e, i) => i > 0 && e !== c[0] ? e : null)), new Map());
|
||||
[].concat(...D.values()).forEach(e => {
|
||||
D.set(e, D.get(e) || [])
|
||||
});
|
||||
|
||||
// The above map rotated so that it represents a DAG of the form
|
||||
// Map {
|
||||
// A => [ A, B, C],
|
||||
// B => [C],
|
||||
// C => []
|
||||
// }
|
||||
// where each key represents a node, and the array contains the edges.
|
||||
const G = [...D.keys()].reduce((p, c) =>
|
||||
p.set(
|
||||
c,
|
||||
[...D.keys()].filter(e => D.get(e).includes(c))),
|
||||
new Map()
|
||||
);
|
||||
|
||||
// An array of leaf nodes; nodes with 0 in degrees.
|
||||
const Q = [...D.keys()].filter(e => D.get(e).length == 0);
|
||||
|
||||
// The result array.
|
||||
const S = [];
|
||||
while (Q.length) {
|
||||
const u = Q.pop();
|
||||
S.push(u);
|
||||
G.get(u).forEach(v => {
|
||||
D.set(v, D.get(v).filter(e => e !== u));
|
||||
if (D.get(v).length == 0) {
|
||||
Q.push(v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Solution:', S);
|
||||
16
Task/Topological-sort/JavaScript/topological-sort-2.js
Normal file
16
Task/Topological-sort/JavaScript/topological-sort-2.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
Solution: [
|
||||
'ieee',
|
||||
'std_cell_lib',
|
||||
'gtech',
|
||||
'dware',
|
||||
'dw07',
|
||||
'dw06',
|
||||
'dw05',
|
||||
'dw02',
|
||||
'dw01',
|
||||
'dw04',
|
||||
'std',
|
||||
'ramlib',
|
||||
'synopsys',
|
||||
'dw03',
|
||||
'des_system_lib' ]
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
sub print_topo_sort ( %deps ) {
|
||||
my %ba;
|
||||
for %deps.kv -> $before, @afters {
|
||||
for @afters -> $after {
|
||||
%ba{$before}{$after} = 1 if $before ne $after;
|
||||
%ba{$after} //= {};
|
||||
}
|
||||
}
|
||||
|
||||
while %ba.grep( not *.value )».key -> @afters {
|
||||
say ~@afters.sort;
|
||||
%ba.delete(@afters);
|
||||
%ba.values».delete(@afters);
|
||||
}
|
||||
|
||||
say %ba ?? "Cycle found! {%ba.keys.sort}" !! '---';
|
||||
}
|
||||
|
||||
my %deps =
|
||||
des_system_lib => < std synopsys std_cell_lib des_system_lib dw02
|
||||
dw01 ramlib ieee >,
|
||||
dw01 => < ieee dw01 dware gtech >,
|
||||
dw02 => < ieee dw02 dware >,
|
||||
dw03 => < std synopsys dware dw03 dw02 dw01 ieee gtech >,
|
||||
dw04 => < dw04 ieee dw01 dware gtech >,
|
||||
dw05 => < dw05 ieee dware >,
|
||||
dw06 => < dw06 ieee dware >,
|
||||
dw07 => < ieee dware >,
|
||||
dware => < ieee dware >,
|
||||
gtech => < ieee gtech >,
|
||||
ramlib => < std ieee >,
|
||||
std_cell_lib => < ieee std_cell_lib >,
|
||||
synopsys => < >;
|
||||
|
||||
print_topo_sort(%deps);
|
||||
%deps<dw01>.push: 'dw04'; # Add unresolvable dependency
|
||||
print_topo_sort(%deps);
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
sub print_topo_sort ( %deps ) {
|
||||
my %ba = %deps.kv».map: * => set;
|
||||
%ba{.key}.=union(set .value) if .key ne .value
|
||||
for %deps.map: { .key X=> .value }
|
||||
|
||||
while %ba.grep((:!value))».key -> @afters {
|
||||
say ~@afters.sort;
|
||||
%ba.delete(@afters);
|
||||
%ba{*}».=difference(@afters);
|
||||
}
|
||||
|
||||
say %ba ?? "Cycle found! {%ba.keys.sort}" !! '---';
|
||||
}
|
||||
15
Task/Topological-sort/Zkl/topological-sort-1.zkl
Normal file
15
Task/Topological-sort/Zkl/topological-sort-1.zkl
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
fcn topoSort(data){ // data is L( L(root,L(leaves)),...)
|
||||
allDs:=data.pump(List,fcn(rds){ T(Void.Write,Void.Write,rds[1]) }).copy();
|
||||
roots:=Dictionary(data); // dictionary of root:leaves
|
||||
L:=List();
|
||||
S:=data.pump(List,'wrap([(r,_)]){ if(allDs.holds(r)) Void.Skip else r }).copy();
|
||||
while(S){ //while S is non-empty do
|
||||
(n:=S.pop()) : L.append(_); //remove a node n from S, add n to tail of L
|
||||
foreach m in (ds:=roots.find(n,List)){ //node m with an edge e from n to m
|
||||
allDs.del(allDs.index(m));
|
||||
if (Void==allDs.find(m)) S.append(m); //m has no other incoming edges
|
||||
} roots.del(n); // remove edge e from the graph
|
||||
}
|
||||
if(roots) throw(Exception.ValueError("Cycle: "+roots.keys));
|
||||
L
|
||||
}
|
||||
19
Task/Topological-sort/Zkl/topological-sort-2.zkl
Normal file
19
Task/Topological-sort/Zkl/topological-sort-2.zkl
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
data:=T(
|
||||
"des_system_lib", "std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee",
|
||||
"dw01", "ieee dw01 dware gtech",
|
||||
"dw02", "ieee dw02 dware",
|
||||
"dw03", "std synopsys dware dw03 dw02 dw01 ieee gtech",
|
||||
"dw04", "dw04 ieee dw01 dware gtech",
|
||||
"dw05", "dw05 ieee dware",
|
||||
"dw06", "dw06 ieee dware",
|
||||
"dw07", "ieee dware",
|
||||
"dware", "ieee dware",
|
||||
"gtech", "ieee gtech",
|
||||
"ramlib", "std ieee",
|
||||
"std_cell_lib", "ieee std_cell_lib",
|
||||
"synopsys", "",
|
||||
);
|
||||
data=data.pump(List,Void.Read,fcn(r,ds){
|
||||
T( r, ds.replace(r,"").strip().split().copy() ) // leaves writable 'cause they will be
|
||||
});
|
||||
topoSort(data).println();
|
||||
Loading…
Add table
Add a link
Reference in a new issue