1
- // 根据 DAG 描述构建图
2
1
function buildGraph ( dag , nodeValueToLabel ) {
3
- const graph = { } ;
4
- const lines = dag . trim ( ) . split ( '\n' ) ;
5
-
6
- for ( const line of lines ) {
7
- const [ node , ...parents ] = line . split ( ':' ) . map ( item => item . trim ( ) ) ;
8
- const label = nodeValueToLabel [ node ] ;
9
- if ( parents . length === 0 || parents [ 0 ] === '' ) {
10
- graph [ label ] = [ ] ;
11
- } else {
12
- const validParents = parents . map ( parent => nodeValueToLabel [ parent ] ) . filter ( parent => parent !== '' ) ;
13
- graph [ label ] = validParents ;
14
- }
15
- }
16
-
17
- return graph ;
2
+ const graph = { } ;
3
+ const inDegree = { } ;
4
+
5
+ // initialize graph and in-degree
6
+ for ( const nodeLabel in nodeValueToLabel ) {
7
+ graph [ nodeLabel ] = [ ] ;
8
+ inDegree [ nodeLabel ] = 0 ;
18
9
}
19
-
20
- // 构建入度数组并初始化队列
21
- function initializeCounts ( graph ) {
22
- const inDegree = { } ;
23
- const queue = [ ] ;
24
-
25
- for ( const node in graph ) {
26
- inDegree [ node ] = graph [ node ] . length ;
27
- if ( inDegree [ node ] === 0 ) {
28
- queue . push ( node ) ;
10
+
11
+ // parse the DAG and build the graph
12
+ const lines = dag . split ( '\n' ) ;
13
+ for ( const line of lines ) {
14
+ const parts = line . split ( ':' ) . map ( part => part . trim ( ) ) ;
15
+ if ( parts . length === 2 ) {
16
+ const nodeLabel = parts [ 0 ] ;
17
+ const dependencies = parts [ 1 ] . split ( ' ' ) . filter ( label => label !== '' ) ;
18
+ for ( const dependency of dependencies ) {
19
+ if ( dependency !== '-1' && nodeValueToLabel [ nodeLabel ] !== undefined && nodeValueToLabel [ dependency ] !== undefined ) {
20
+ graph [ nodeLabel ] . push ( dependency ) ; // add dependency to the graph
21
+ inDegree [ dependency ] ++ ; // increment in-degree of the dependency
22
+ }
29
23
}
30
24
}
31
-
32
- return { inDegree, queue } ;
33
25
}
34
-
35
26
36
- function processSolution ( graph , inDegree , queue , solution , nodeValueToLabel ) {
37
- const visited = new Set ( ) ;
38
- if ( Array . isArray ( solution ) ) {
39
- solution = solution . join ( '\n' ) ;
40
- } else if ( typeof solution !== 'string' ) {
41
- throw new TypeError ( 'The solution must be a string or an array.' ) ;
42
- }
43
-
44
- const solutionNodes = solution . split ( '\n' ) . map ( line => line . trim ( ) ) ;
45
- const graphNodes = Object . keys ( graph ) . filter ( node => node !== '__root__' ) ; // 排除虚拟根节点
46
-
47
- console . log ( "Solution nodes:" , solutionNodes ) ;
48
- console . log ( "Graph nodes:" , graphNodes ) ;
49
-
50
- // 检查学生的解答中的项目数量是否与图中的节点数量匹配
51
- if ( solutionNodes . length !== graphNodes . length ) {
52
- throw new Error ( 'Number of items in student solution does not match the number of nodes in the graph.' ) ;
27
+ console . log ( "Graph:" , graph ) ;
28
+ console . log ( "In-degree:" , inDegree ) ;
29
+ return { graph, inDegree } ;
30
+ }
31
+
32
+
33
+ function processSolution ( solution , graph , inDegree , nodeValueToLabel ) {
34
+ console . log ( "processSolution:" , solution ) ;
35
+ console . log ( "processnodeValueToLabel:" , nodeValueToLabel ) ;
36
+ const visited = new Set ( ) ;
37
+
38
+ for ( const nodeText of solution ) {
39
+ const nodeLabel = Object . keys ( nodeValueToLabel ) . find (
40
+ ( label ) => nodeValueToLabel [ label ] === nodeText
41
+ ) ;
42
+
43
+ if ( nodeLabel === undefined ) {
44
+ console . log ( "Skipping node not found in nodeValueToLabel:" , nodeText ) ;
45
+ continue ; // jump to the next node
53
46
}
54
-
55
- for ( const node of solutionNodes ) { // 修改这里
56
- console . log ( "Current node:" , node ) ;
57
- console . log ( "Current queue:" , queue ) ;
58
-
59
- // 查找节点对应的标签
60
- const label = node ; // 修改这里
61
- if ( ! label ) {
62
- console . log ( "Node label not found, returning false" ) ;
63
- return false ;
64
- }
65
-
66
- // 如果当前节点的标签不在队列中,返回false
67
- if ( ! queue . includes ( label ) ) {
68
- console . log ( "Node label not in queue, returning false" ) ;
47
+
48
+ console . log ( 'Current label:' , nodeLabel ) ;
49
+ console . log ( 'Current node text:' , nodeText ) ;
50
+ console . log ( 'Node value to label mapping:' , nodeValueToLabel ) ;
51
+
52
+ visited . add ( nodeLabel ) ;
53
+
54
+ // check if the node has dependencies
55
+ for ( const dependencyLabel of graph [ nodeLabel ] ) {
56
+ if ( ! visited . has ( dependencyLabel ) ) {
57
+ console . error ( "Dependency not satisfied:" , nodeText , "depends on" , nodeValueToLabel [ dependencyLabel ] ) ;
69
58
return false ;
70
59
}
71
-
72
- // 将当前节点的标签从队列中移除
73
- queue . splice ( queue . indexOf ( label ) , 1 ) ;
74
- visited . add ( label ) ;
75
-
76
- // 更新相邻节点的入度,并将入度变为0的节点加入队列
77
- for ( const neighbor in graph ) {
78
- if ( graph [ neighbor ] . includes ( label ) ) {
79
- inDegree [ neighbor ] -- ;
80
- if ( inDegree [ neighbor ] === 0 ) {
81
- queue . push ( neighbor ) ;
82
- }
83
- }
84
- }
85
- console . log ( "Updated in-degree:" , inDegree ) ;
86
- console . log ( "Updated queue:" , queue ) ;
87
60
}
88
-
89
- // 如果所有节点都被访问过,返回true,否则返回false
90
- const allVisited = visited . size === Object . keys ( graph ) . length ;
91
- console . log ( "All nodes visited:" , allVisited ) ;
92
- return allVisited ;
93
61
}
62
+
63
+ // check if all nodes were visited
64
+ if ( visited . size !== Object . keys ( nodeValueToLabel ) . length ) {
65
+ console . error ( "Not all nodes in nodeValueToLabel were visited." ) ;
66
+ return false ;
67
+ }
68
+
69
+ console . log ( 'Visited nodes:' , Array . from ( visited ) ) ;
70
+ return true ;
71
+ }
72
+
73
+
74
+
94
75
95
- function processDAG ( dag , solution ) {
96
- const nodeValueToLabel = {
97
- "one" : "print('Hello')" ,
98
- "two" : "print('Parsons')" ,
99
- "three" : "print('Problems!')"
100
- } ;
101
-
102
- const graph = buildGraph ( dag , nodeValueToLabel ) ;
103
- const { inDegree, queue } = initializeCounts ( graph ) ;
104
- const result = processSolution ( graph , inDegree , queue , solution , nodeValueToLabel ) ;
105
- return result ;
76
+ function processDAG ( dag , solution , nodeValueToLabel ) {
77
+ console . log ( "DAG:" , dag ) ;
78
+ console . log ( "Node value to label mapping:" , nodeValueToLabel ) ;
79
+ const { graph, inDegree } = buildGraph ( dag , nodeValueToLabel ) ;
80
+ const result = processSolution ( solution , graph , inDegree , nodeValueToLabel ) ;
81
+ return result ;
82
+ }
83
+
84
+ function extractCode ( solution , nodeValueToLabel ) {
85
+ const code = [ ] ;
86
+ const newNodeValueToLabel = { } ;
87
+ for ( const nodeText of solution ) {
88
+ const nodeLabel = Object . keys ( nodeValueToLabel ) . find (
89
+ ( key ) => nodeValueToLabel [ key ] === nodeText
90
+ ) ;
91
+ if ( nodeLabel !== undefined ) {
92
+ code . push ( nodeText ) ;
93
+ newNodeValueToLabel [ nodeLabel ] = nodeText ;
94
+ }
95
+ }
96
+ return { code, newNodeValueToLabel } ;
106
97
}
0 commit comments