@@ -84,6 +84,7 @@ while i<len(q):
8484 a+=1
8585 i+=1
8686print(a)` ,
87+ "run.sh" : this . getRunShScript ( "580_c_kefa_and_park_5570" ) ,
8788 "tags.txt" : "dfs and similar\\ngraphs\\ntrees" ,
8889 "tests" : {
8990 "input_1.txt" : "7 1\\n1 0 1 1 0 0 0\\n1 2\\n1 3\\n2 4\\n2 5\\n3 6\\n3 7" ,
@@ -176,6 +177,7 @@ for i in range(n):
176177
177178
178179print(max([findDepth(a, i) for i in roots]))` ,
180+ "run.sh" : this . getRunShScript ( "116_c_party_7303" ) ,
179181 "tags.txt" : "dfs and similar\\ngraphs\\ntrees" ,
180182 "tests" : {
181183 "input_1.txt" : "5\\n-1\\n1\\n2\\n1\\n-1" ,
@@ -247,6 +249,7 @@ elif c1==n-1 and cs==1:
247249 print("star topology")
248250else:
249251 print("unknown topology")` ,
252+ "run.sh" : this . getRunShScript ( "292_b_network_topology_9930" ) ,
250253 "tags.txt" : "graphs\\nimplementation" ,
251254 "tests" : {
252255 "input_1.txt" : "4 3\\n1 2\\n2 3\\n3 4" ,
@@ -320,6 +323,7 @@ if __name__ == '__main__':
320323 exit()
321324
322325 print("Yes")` ,
326+ "run.sh" : this . getRunShScript ( "913_b_christmas_spruce_7977" ) ,
323327 "tags.txt" : "implementation\\ntrees" ,
324328 "tests" : {
325329 "input_1.txt" : "4\\n1\\n1\\n1" ,
@@ -402,6 +406,7 @@ threading.stack_size(10 ** 8)
402406t = threading.Thread(target=main)
403407t.start()
404408t.join()` ,
409+ "run.sh" : this . getRunShScript ( "982_c_cut_em_all_5275" ) ,
405410 "tags.txt" : "dfs and similar\\ndp\\ngraphs\\ngreedy\\ntrees" ,
406411 "tests" : {
407412 "input_1.txt" : "4\\n2 4\\n4 1\\n3 1" ,
@@ -580,6 +585,93 @@ t.join()`,
580585 return div . innerHTML ;
581586 }
582587
588+ getRunShScript ( problemId ) {
589+ return `#!/bin/bash
590+ # Test script for ${ problemId }
591+
592+ # Get the absolute path to the problem directory
593+ PROBLEM_DIR="\$(cd "\$(dirname "\\\${BASH_SOURCE[0]}")" && pwd)"
594+ CLUSTER_DIR="\$(cd "\\\$PROBLEM_DIR/.." && pwd)"
595+
596+ # Import paths - include both repo root and cluster directory
597+ # This allows importing from problems/cluster{i}/library.py with: from library import *
598+ export PYTHONPATH="\\\$CLUSTER_DIR:\\\$PYTHONPATH"
599+
600+ # Default to main.py if no specific file is provided
601+ SOLUTION_FILE=\\\${1:-"\\\$PROBLEM_DIR/main.py"}
602+
603+ # Function to run a test case
604+ run_test() {
605+ local test_num=\$1
606+ local input_file="\$PROBLEM_DIR/tests/input_\${test_num}.txt"
607+ local expected_file="\$PROBLEM_DIR/tests/output_\${test_num}.txt"
608+
609+ if [ ! -f "\$input_file" ]; then
610+ echo "Test #\$test_num: Input file not found!"
611+ return 1
612+ fi
613+
614+ if [ ! -f "\$expected_file" ]; then
615+ echo "Test #\$test_num: Expected output file not found!"
616+ return 1
617+ fi
618+
619+ echo "Running test #\$test_num..."
620+
621+ # Run the solution with the test input using python
622+ OUTPUT=\$(python "\$SOLUTION_FILE" < "\$input_file")
623+ EXIT_CODE=\$?
624+
625+ if [ \$EXIT_CODE -ne 0 ]; then
626+ echo "Test #\$test_num: Error running solution! Exit code: \$EXIT_CODE"
627+ return 1
628+ fi
629+
630+ # Read expected output
631+ EXPECTED=\$(cat "\$expected_file")
632+
633+ # Compare outputs (ignoring trailing whitespace)
634+ if [ "\$(echo "\$OUTPUT" | sed -e 's/[ \\t]*\$//')" = "\$(echo "\$EXPECTED" | sed -e 's/[ \\t]*\$//')" ]; then
635+ echo "Test #\$test_num: PASSED ✅"
636+ return 0
637+ else
638+ echo "Test #\$test_num: FAILED ❌"
639+ echo "Expected:"
640+ echo "\$EXPECTED"
641+ echo "Got:"
642+ echo "\$OUTPUT"
643+ return 1
644+ fi
645+ }
646+
647+ # Count test files
648+ NUM_TESTS=\$(ls "\$PROBLEM_DIR/tests/input_"*.txt 2>/dev/null | wc -l)
649+
650+ if [ \$NUM_TESTS -eq 0 ]; then
651+ echo "No test cases found!"
652+ exit 1
653+ fi
654+
655+ # Run all tests
656+ PASSED=0
657+ TOTAL=\$NUM_TESTS
658+
659+ for ((i=1; i<=\$NUM_TESTS; i++)); do
660+ if run_test \$i; then
661+ PASSED=\$((PASSED+1))
662+ fi
663+ done
664+
665+ echo "Results: \$PASSED/\$TOTAL tests passed"
666+ echo "\$PASSED/\$TOTAL" > \$PROBLEM_DIR/results.txt
667+
668+ if [ \$PASSED -eq \$TOTAL ]; then
669+ exit 0
670+ else
671+ exit 1
672+ fi` ;
673+ }
674+
583675 attachEventListeners ( ) {
584676 const pathSegments = this . container . querySelectorAll ( '.path-segment' ) ;
585677 pathSegments . forEach ( segment => {
0 commit comments