Oliver Eyton-Williams ee1e8abd87
feat(curriculum): restore seed + solution to Chinese (#40683)
* feat(tools): add seed/solution restore script

* chore(curriculum): remove empty sections' markers

* chore(curriculum): add seed + solution to Chinese

* chore: remove old formatter

* fix: update getChallenges

parse translated challenges separately, without reference to the source

* chore(curriculum): add dashedName to English

* chore(curriculum): add dashedName to Chinese

* refactor: remove unused challenge property 'name'

* fix: relax dashedName requirement

* fix: stray tag

Remove stray `pre` tag from challenge file.

Signed-off-by: nhcarrigan <nhcarrigan@gmail.com>

Co-authored-by: nhcarrigan <nhcarrigan@gmail.com>
2021-01-12 19:31:00 -07:00

5.0 KiB
Raw Blame History

id, title, challengeType, videoUrl, dashedName
id title challengeType videoUrl dashedName
594fa2746886f41f7d8bf225 拓扑排序 5 topological-sort

--description--

给定项目之间的映射以及它们所依赖的项目, 拓扑排序会对项目进行排序 ,以使项目不在其所依赖的项目之前。

VHDL语言编译库有一个限制,即必须在它依赖的库之后编译库。

任务:

编写一个函数该函数将从其依赖项返回VHDL库的有效编译顺序。

假设库名称是单个单词。仅作为家属提及的项目没有自己的家属,但必须给出他们的编制顺序。任何自我依赖都应该被忽略。应忽略任何不可订购的依赖项。

使用以下数据作为示例:

图书馆图书馆依赖
======= ====================
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
新思

注意:如果将dw04添加到dw01的依赖项列表中,则上述数据将无法订购。

CF卡
 <a href="http://rosettacode.org/wiki/Topological sort/Extracted top item" title="Topological sort/Extracted top item">Topological sort/Extracted top item</a>. 

拓扑排序有两种流行的算法:

Kahn的1962拓扑排序和深度优先搜索 拓扑排序

Jason Sachs “十个小算法,第四部分:拓扑排序”

--hints--

topologicalSort是一个函数。

assert(typeof topologicalSort === 'function');

topologicalSort必须返回正确的库顺序..

assert.deepEqual(topologicalSort(libsSimple), ['bbb', 'aaa']);

topologicalSort必须返回正确的库顺序..

assert.deepEqual(topologicalSort(libsVHDL), solutionVHDL);

topologicalSort必须返回正确的库顺序..

assert.deepEqual(topologicalSort(libsCustom), solutionCustom);

topologicalSort必须忽略不可共享的依赖项。

assert.deepEqual(topologicalSort(libsUnorderable), solutionUnorderable);

--seed--

--after-user-code--

const libsSimple =
  `aaa bbb
  bbb`;

const libsVHDL =
  `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`;

const solutionVHDL = [
  'ieee', 'std_cell_lib', 'gtech', 'dware', 'dw07', 'dw06',
  'dw05', 'dw02', 'dw01', 'dw04', 'std', 'ramlib', 'synopsys',
  'dw03', 'des_system_lib'
];

const libsCustom =
  `a b c d
  b c d
  d c
  c base
  base`;
const solutionCustom = ['base', 'c', 'd', 'b', 'a'];

const libsUnorderable =
  `TestLib Base MainLib
  MainLib TestLib
  Base`;

const solutionUnorderable = ['Base'];

--seed-contents--

function topologicalSort(libs) {

  return true;
}

--solutions--

function topologicalSort(libs) {
  // 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(ep => ep !== ''))
    .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);
      }
    });
  }

  return S;
}