topological-sort.nut 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. auto recipes = [
  2. ["martian stew", "thingy,pig,cheese danish,chicken"],
  3. ["cheese danish", "flour,butter,egg,vanilla,cream cheese,sugar"],
  4. ["butter", "milk,salt"],
  5. ["thingy", "iron,apple,vanilla"],
  6. ["cream cheese", "milk,salt"],
  7. ["chicken", "worm"],
  8. ["worm", "apple"],
  9. ["egg", "chicken"],
  10. ["milk", "cow"],
  11. ["cow", "grass"],
  12. ["pig", "apple,worm"]
  13. ];
  14. auto function to_graph(recipes)
  15. {
  16. //get recipes into a canonical form for further manipulation
  17. auto nodes = [];
  18. auto nodemap = {};
  19. local function add_node(name)
  20. {
  21. auto node;
  22. if( name in nodemap )
  23. node = nodemap[name];
  24. else
  25. {
  26. node = {"name": name};
  27. nodes.append(node);
  28. nodemap[name] <- node;
  29. }
  30. return node;
  31. }
  32. foreach( recipe, ingredients in recipes )
  33. {
  34. ingredients = ingredients.split(",");
  35. auto node = add_node(recipe);
  36. node["edges"] <- ingredients;
  37. foreach( ingredient in ingredients )
  38. node = add_node(ingredient);
  39. }
  40. foreach( node in nodes )
  41. {
  42. if( "edges" in node )
  43. node["edges"] = tuple(nodemap[ingredient] for ingredient in node["edges"]);
  44. else
  45. node["edges"] = ();
  46. }
  47. return nodes;
  48. }
  49. // Print a list of the nodes along with the outgoing edges of each:
  50. foreach( n in to_graph(recipes) )
  51. {
  52. print(format("%-20s", n["name"]), [n2["name"] for n2 in n["edges"]]);
  53. }