├── .gitignore ├── README.md ├── diff.sh ├── package-lock.json ├── package.json ├── runall.sh ├── script.js └── template.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Live Demo 2 | Watch the YouTube video showing the live demo -> [here](https://www.youtube.com/watch?v=MXYmbJO4bqU) 3 | 4 | # Setup/Installation 5 | ```bash 6 | INSTALLATION_PATH=""; # also the dir where you will write solution 7 | cd $INSTALLATION_PATH 8 | git clone https://github.com/rachitiitr/CodeforcesContestBot.git 9 | cd CodeforcesContestBot 10 | npm install 11 | ``` 12 | 13 | # Usage 14 | ```bash 15 | export CF_CONTEST=https://codeforces.com/contest/1330 16 | node script.js 17 | # will parse all the problems of the contest 18 | # download their testcases 19 | # create multiple directories A B C D E depending on the number of problems in contest 20 | # each directory created will have 21 | # in0.txt out0.txt 22 | # in1.txt out1.txt and so on 23 | # which represent the testcases downloaded 24 | ``` 25 | 26 | # Running sol.cpp on multiple testcases and viewing output 27 | ```bash 28 | ./runall.sh A #if you want to test A/sol.cpp 29 | ./runall.sh D #if you want to test D/sol.cpp against your output vs sample output 30 | # this will run your code on downloaded test cases 31 | # and print to console your output vs expected output 32 | ``` 33 | -------------------------------------------------------------------------------- /diff.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo Running diff report 4 | cd $1 5 | echo $(pwd) 6 | mainoutfiles=(`ls out*.txt`) 7 | 8 | yourfiles=(`ls yout*.txt`) 9 | 10 | echo ${mainoutfiles[@]} ${yourfiles[@]} 11 | len=${#mainoutfiles[@]} 12 | 13 | # showing only success/fail status per testcase 14 | for((i=0; i<$len; i++)) do 15 | # ToDo: Handle blank lines at end and do file comparison in bash 16 | # cmp -s ${mainoutfiles[i]} ${yourfiles[i]} && echo "Test #$i passed" || echo "Test #$i failed" 17 | echo TestCase $i... 18 | echo =================== 19 | echo Expected Output 20 | cat ${mainoutfiles[i]} && echo 21 | echo Your Output 22 | cat ${yourfiles[i]} && echo 23 | echo =================== 24 | echo 25 | done 26 | 27 | # showing diff via vim 28 | # cmd="vim -c 'set diffopt=filler,vertical' -c 'edit ${mainoutfiles[0]}' -c 'diffsplit ${yourfiles[0]}' " 29 | # for((i=1; i<$len; i++)) do 30 | # cmd="${cmd} -c 'tabe ${mainoutfiles[i]}' -c 'diffsplit ${yourfiles[i]}' " 31 | # done 32 | 33 | # eval $cmd 34 | cd .. 35 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codeforces-contest-bot", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/node": { 8 | "version": "14.0.13", 9 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.13.tgz", 10 | "integrity": "sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA==" 11 | }, 12 | "axios": { 13 | "version": "0.19.2", 14 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", 15 | "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", 16 | "requires": { 17 | "follow-redirects": "1.5.10" 18 | } 19 | }, 20 | "boolbase": { 21 | "version": "1.0.0", 22 | "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", 23 | "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" 24 | }, 25 | "cheerio": { 26 | "version": "1.0.0-rc.3", 27 | "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", 28 | "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", 29 | "requires": { 30 | "css-select": "~1.2.0", 31 | "dom-serializer": "~0.1.1", 32 | "entities": "~1.1.1", 33 | "htmlparser2": "^3.9.1", 34 | "lodash": "^4.15.0", 35 | "parse5": "^3.0.1" 36 | } 37 | }, 38 | "css-select": { 39 | "version": "1.2.0", 40 | "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", 41 | "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", 42 | "requires": { 43 | "boolbase": "~1.0.0", 44 | "css-what": "2.1", 45 | "domutils": "1.5.1", 46 | "nth-check": "~1.0.1" 47 | } 48 | }, 49 | "css-what": { 50 | "version": "2.1.3", 51 | "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", 52 | "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" 53 | }, 54 | "debug": { 55 | "version": "3.1.0", 56 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 57 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 58 | "requires": { 59 | "ms": "2.0.0" 60 | } 61 | }, 62 | "dom-serializer": { 63 | "version": "0.1.1", 64 | "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", 65 | "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", 66 | "requires": { 67 | "domelementtype": "^1.3.0", 68 | "entities": "^1.1.1" 69 | } 70 | }, 71 | "domelementtype": { 72 | "version": "1.3.1", 73 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", 74 | "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" 75 | }, 76 | "domhandler": { 77 | "version": "2.4.2", 78 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", 79 | "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", 80 | "requires": { 81 | "domelementtype": "1" 82 | } 83 | }, 84 | "domutils": { 85 | "version": "1.5.1", 86 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", 87 | "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", 88 | "requires": { 89 | "dom-serializer": "0", 90 | "domelementtype": "1" 91 | } 92 | }, 93 | "entities": { 94 | "version": "1.1.2", 95 | "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", 96 | "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" 97 | }, 98 | "follow-redirects": { 99 | "version": "1.5.10", 100 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", 101 | "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", 102 | "requires": { 103 | "debug": "=3.1.0" 104 | } 105 | }, 106 | "htmlparser2": { 107 | "version": "3.10.1", 108 | "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", 109 | "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", 110 | "requires": { 111 | "domelementtype": "^1.3.1", 112 | "domhandler": "^2.3.0", 113 | "domutils": "^1.5.1", 114 | "entities": "^1.1.1", 115 | "inherits": "^2.0.1", 116 | "readable-stream": "^3.1.1" 117 | } 118 | }, 119 | "inherits": { 120 | "version": "2.0.4", 121 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 122 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 123 | }, 124 | "lodash": { 125 | "version": "4.17.19", 126 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", 127 | "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" 128 | }, 129 | "ms": { 130 | "version": "2.0.0", 131 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 132 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 133 | }, 134 | "nth-check": { 135 | "version": "1.0.2", 136 | "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", 137 | "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", 138 | "requires": { 139 | "boolbase": "~1.0.0" 140 | } 141 | }, 142 | "parse5": { 143 | "version": "3.0.3", 144 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", 145 | "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", 146 | "requires": { 147 | "@types/node": "*" 148 | } 149 | }, 150 | "readable-stream": { 151 | "version": "3.6.0", 152 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 153 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 154 | "requires": { 155 | "inherits": "^2.0.3", 156 | "string_decoder": "^1.1.1", 157 | "util-deprecate": "^1.0.1" 158 | } 159 | }, 160 | "safe-buffer": { 161 | "version": "5.2.1", 162 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 163 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 164 | }, 165 | "string_decoder": { 166 | "version": "1.3.0", 167 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 168 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 169 | "requires": { 170 | "safe-buffer": "~5.2.0" 171 | } 172 | }, 173 | "util-deprecate": { 174 | "version": "1.0.2", 175 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 176 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codeforces-contest-bot", 3 | "version": "1.0.0", 4 | "description": "Developed by rachitiitr", 5 | "main": "script.js", 6 | "dependencies": { 7 | "axios": "^0.19.2", 8 | "cheerio": "^1.0.0-rc.3" 9 | }, 10 | "devDependencies": {}, 11 | "scripts": { 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/rachitiitr/CodeforcesContestBot.git" 17 | }, 18 | "keywords": [ 19 | "competitive-programming", 20 | "javascript", 21 | "bot", 22 | "codeforces-bot", 23 | "rachitiitr" 24 | ], 25 | "author": "Rachit Jain", 26 | "license": "ISC", 27 | "bugs": { 28 | "url": "https://github.com/rachitiitr/CodeforcesContestBot/issues" 29 | }, 30 | "homepage": "https://github.com/rachitiitr/CodeforcesContestBot#readme" 31 | } 32 | -------------------------------------------------------------------------------- /runall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | problem=$1 3 | cd $problem 4 | echo $(pwd) 5 | 6 | g++ -std=c++17 sol.cpp -o solD || { echo "$problem/sol.cpp failed to build. Check for errors."; exit 1; } 7 | echo Compiled successfully... 8 | ls -l solD 9 | 10 | infiles=(`ls in*.txt`) 11 | # echo ${infiles[@]} 12 | for ((i=0; i<${#infiles[@]}; i++)); do 13 | ./solD < in$i.txt > yout$i.txt 14 | done 15 | 16 | cd .. 17 | ./diff.sh $problem 18 | cd .. 19 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | const cheerio = require('cheerio'); 3 | var fs = require('fs'); 4 | 5 | url = 'http://codeforces.com/contest/1256/problem/C' 6 | 7 | let getTestCaseFromProblemHtml = (dir, html) => { 8 | 9 | fs.copyFileSync(`${dir}/../template.cpp`, `${dir}/sol.cpp`); 10 | data = []; 11 | const $ = cheerio.load(html); 12 | $('div.input pre').each((i, elem) => { 13 | data[i] = { 14 | ...data[i], 15 | input: $(elem).text() 16 | }; 17 | }); 18 | $('div.output pre').each((i, elem) => { 19 | data[i] = ({ 20 | ...data[i], 21 | output: $(elem).text() 22 | }); 23 | }); 24 | console.log(data); 25 | data.forEach((test, i) => { 26 | fs.writeFile(`${dir}/in${i}.txt`, test.input, function(err) { 27 | if(err) { 28 | console.log(err); 29 | } 30 | console.log(`The file ${dir}/in${i}.txt was saved!`); 31 | }); 32 | fs.writeFile(`${dir}/out${i}.txt`, test.output, function(err) { 33 | if(err) { 34 | console.log(err); 35 | } 36 | console.log(`The file ${dir}/out${i}.txt was saved!`); 37 | }); 38 | }) 39 | console.log(data); 40 | } 41 | 42 | function getTestCaseFromProblemUrl(url) { 43 | var dir = `./${url.substring(url.lastIndexOf('/')+1)}`; 44 | 45 | if (!fs.existsSync(dir)){ 46 | fs.mkdirSync(dir); 47 | } 48 | 49 | axios.get(url) 50 | .then(response => { 51 | // console.log(response); 52 | getTestCaseFromProblemHtml(dir, response.data); 53 | } 54 | ) 55 | .catch(err => console.log(err)); 56 | } 57 | 58 | // getTestCaseFromProblemUrl(url); 59 | 60 | contest_url = 'http://codeforces.com/contest/1256'; 61 | 62 | // '' 63 | let getTotalProblemsFromContestHtml = (html) => { 64 | data = []; 65 | const $ = cheerio.load(html); 66 | console.log('parsing'); 67 | $('tr td.id a').each((i, elem) => { 68 | problem_url = 'https://codeforces.com/' + $(elem).attr('href') 69 | console.log(problem_url); 70 | getTestCaseFromProblemUrl(problem_url); 71 | }); 72 | } 73 | 74 | const contestUrl = process.argv[2]; 75 | 76 | axios.get(contestUrl) 77 | .then(response => { 78 | // console.log(response); 79 | getTotalProblemsFromContestHtml(response.data); 80 | }); 81 | -------------------------------------------------------------------------------- /template.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define gc getchar_unlocked 4 | #define fo(i,n) for(i=0;in;k