├── LICENSE ├── README.md ├── converter.py ├── fastio.py ├── functions.cpp └── struct.cpp /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Bernardo Flores Salmeron 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fast I/O Code Optimizer 2 | A tool developed in Python to optimize execution time of C++ codes by replacing methods of reading and writing variables. The program is focused on Competitive Programming and could be used to help to solve problems with a tight time limit. This optimizer replaces all cin/cout methods to faster approaches which can optimize until 30% the execution time of the code. 3 | 4 | ## Motivation 5 | Some competitive programming problems have a tight time limit. Then, when someone submits a solution, even with the expected complexity, it may get a time limit exceeded verdict. Occasionally, the problem requires Fast I/O methods to speed up the execution time and is very hard to get accepted verdict without making this type of optimization. Consequently, it is needed to replace all default C++ reading and writing methods (cin/cout) to faster approaches. This tool makes very easy the task of replacing the way of reading and writing variables, and it uses very fast methods which would take very long to type and wouldn't be so efficient. 6 | 7 | ## How to use 8 | 9 | ### Website: [fastio.pythonanywhere.com/](http://fastio.pythonanywhere.com/) 10 | After accessing the website, it is needed to insert the code to be optimized in the text field from the left, then click the button Optimize it and it's done, the optimized code will be pasted in the text field from the right. 11 | 12 | ### Offline tool 13 | Download the project and execute the file in terminal. To execute it just type the following. 14 | ```shell 15 | python3 fastio.py nameOfFile.cpp 16 | ``` 17 | After that, it will be generated a new file named `FastIO-nameOfFile.cpp` in project's directory and the converted code will be printed in terminal. 18 | If the user do not want to create a new file or print the code in terminal, he only needs to go to fastio.py file and modify the variables printInTerminal and printInFile. 19 | 20 | ## Functions and Commands 21 | 22 | ### To Be Replaced 23 | * cin 24 | * cout 25 | * cin.ignore() - 0 parameter 26 | * getline() - Any number of parameters 27 | * cout << setpresision() - 1 parameter and at most 1 call 28 | 29 | ### To Be Deleted 30 | * cout << fixed 31 | * ios_base::sync_with_stdio() 32 | * ios::sync_with_stdio() 33 | 34 | ## Important Restrictions and Warnings 35 | * This tool doesn't work with multiple calls of setprecision function. 36 | * Multiline statements are not supported. 37 | * Custom istream is not supported. 38 | * C++ (g++ 4.3.2) and past versions are not supported. 39 | * This tool only supports cin/cout commands. 40 | * C++11 is faster than newer versions. 41 | 42 | ## Implementation 43 | In order to optimize the code performance, text replacing was the approach chosen. This tool finds all occurrences of cin/cout commands and replaces them with functions. Important auxiliaries commands also are supported and will be described later. Most of the implementation consists of finding patterns in text using regular expressions, and this is very useful to avoid blank characters. Because of the best compatibility with methods applied, Python was the language chosen. There are other approaches available to make the same optimization, but this one was chosen by reason of it is possible to modify easier all commands without creating some specific modification to a certain command. Besides that, it is possible to add support to a big range of things like the use of different namespaces. 44 | 45 | ### Reading Variables 46 | 47 | All cin calls are replaced by READ_VAR function. It is a boolean funcion. It returns 0 if it reads EOF or returns 1 if it reads some content. 48 | 49 | #### - Reading Integers 50 | Cin is replaced by getchar() function which is responsible to read each number as a character and convert it to a number. 51 | 52 | #### - Reading Strings and Characters 53 | Cin is replaced by getchar() function which is responsible to read the string, char by char. 54 | 55 | #### - Reading Floating Numbers 56 | Cin is replaced by a scanf function. 57 | 58 | #### - Reading Booleans and Bitsets 59 | Cin is replaced by getchar() function which is responsible to read each bit as a character and convert it to a bit. 60 | 61 | ### Writing Variables 62 | 63 | All cout calls are replaced by WRITE_VAR function. It is a void function. 64 | 65 | #### - Writing Integers 66 | Cout is replaced by putchar() function which is responsible to write each number as a character. 67 | 68 | #### - Writing Strings and Characters 69 | Cout is replaced by putchar() function which is responsible to write each character, char by char. 70 | 71 | #### - Writing Floating Numbers 72 | Cout is replaced by a printf function. If setprecision(number) method is called, all floating numbers will be written with "number" decimal places. However, this tool only supports one call of setprecision method. 73 | 74 | #### - Writing Booleans and Bitsets 75 | Cout is replaced by putchar() function which is responsible to write each bit as a character. 76 | 77 | \* The usage of std:: before a call and the usage of blank characters like tabs and spaces are supported. 78 | 79 | 80 | ## Tests and Comparisons 81 | 82 | | | C++ | C++ (FAST IO) | C++11 | C++11 (FAST IO) | C++14 | C++14 (FAST IO) | C++17 | C++17 (FAST IO) | 83 | |:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:| 84 | | [Codeforces - Cloud of Hashtags](https://codeforces.com/problemset/problem/777/D) | - | - | [264 ms](https://codeforces.com/contest/777/submission/50989538) | [62 ms](https://codeforces.com/contest/777/submission/50989575) |[124 ms](https://codeforces.com/contest/777/submission/50989550) | [202 ms](https://codeforces.com/contest/777/submission/50989582) | [140 ms](https://codeforces.com/contest/777/submission/50989556) | [187 ms](https://codeforces.com/contest/777/submission/50989597) | 85 | | [Codeforces - Stars Drawing (Hard Edition)](https://codeforces.com/contest/1015/problem/E2) | - | - | [1606 ms](https://codeforces.com/contest/1015/submission/50987913) | [467 ms](https://codeforces.com/contest/1015/submission/50987973) | [733 ms](https://codeforces.com/contest/1015/submission/50988087) | [998 ms](https://codeforces.com/contest/1015/submission/50988176) | [702 ms](https://codeforces.com/contest/1015/submission/50988090) | [1014 ms](https://codeforces.com/contest/1015/submission/50988172) | 86 | | [URI - Man, Elephant and Mouse](https://www.urionlinejudge.com.br/judge/en/problems/view/1477) | - | - | 912 ms | 660 ms | - | - | 944 ms | 728 ms | 87 | | [URI - Plantation](https://www.urionlinejudge.com.br/judge/en/problems/view/2772) | - | - | 700 ms | 680 ms | - | - | 916 ms | 896 ms | 88 | | [SPOJ - Binary search](https://www.spoj.com/problems/BSEARCH1/) | TLE | 110 ms | - | - | TLE | 110 ms | - | - | 89 | -------------------------------------------------------------------------------- /converter.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | warningBackslashMessage = ''' 4 | /* 5 | ....................... WARNING ....................... 6 | .. It was found a \\ (Backslash) symbol in your file ... 7 | .... This software doesn\'t support multiline code ..... 8 | ............. and may not work as expected ............ 9 | ....................................................... 10 | */ 11 | 12 | ''' 13 | # if you do not want to print backslash warning in code 14 | # uncomment the line below 15 | # warningBackslashMessage = '' 16 | 17 | warningSetPrecisionMessage = ''' 18 | /* 19 | ....................... WARNING ........................ 20 | .. It was found multiple setprecision occurrences in ... 21 | .. your code. This software doesn\'t support multiple ... 22 | ....... occurrences and may not work as expected ....... 23 | ........................................................ 24 | */ 25 | 26 | ''' 27 | 28 | # if you do not want to print setprecision warning in code 29 | # uncomment the line below 30 | # warningSetPrecisionMessage = '' 31 | 32 | 33 | 34 | definedStrings = {} 35 | 36 | def joinTuple(tuple): 37 | return ''.join(tuple) 38 | 39 | def coverStrings(text): 40 | r = [] 41 | r += re.findall(r'[^\\]\"(?:(?![^\\]\").)*[^\\]\"', text) 42 | r += re.findall(r'[^\\]\'(?:(?![^\\]\').)*[^\\]\'', text) 43 | for i in range(len(r)): 44 | r[i] = r[i][1:] 45 | definedStrings[i] = r[i] 46 | text = text.replace(r[i], '¿¿¿¿¿' + str(i) + '¿¿¿¿¿') 47 | 48 | return text 49 | 50 | def uncoverStrings(text): 51 | for key, value in definedStrings.items(): 52 | text = text.replace('¿¿¿¿¿' + str(key) + '¿¿¿¿¿', value) 53 | 54 | return text 55 | 56 | def removeEnter(text): 57 | s = str(chr(13)) 58 | text = text.replace(s, '') 59 | return text 60 | 61 | def customSplit(text, div): 62 | l = [] 63 | bra, par = 0, 0 64 | acc, i = '', 0 65 | while i < len(text): 66 | if i + len(div) <= len(text): 67 | if text[i : i + len(div)] == div and par == 0 and bra == 0: 68 | l.append(acc) 69 | acc = '' 70 | i += len(div) 71 | continue 72 | if text[i] == '(': 73 | par += 1 74 | elif text[i] == ')': 75 | par -= 1 76 | elif text[i] == '[': 77 | bra += 1 78 | elif text[i] == ']': 79 | bra -= 1 80 | acc += text[i] 81 | i += 1 82 | l.append(acc) 83 | return l 84 | 85 | 86 | def removeSpacesFromVar(name): 87 | 88 | i = 0 89 | while name[i] in ['\t', ' ', '\n']: 90 | i += 1 91 | 92 | j = len(name) - 1 93 | while name[j] in ['\t', ' ', '\n']: 94 | j -= 1 95 | 96 | return name[i : j + 1] 97 | 98 | def getCinEntries(text): 99 | r = re.findall(r'[\s\t\n,;()]*(std[\s\t]*::[\s\t]*|)(cin[\s\t\n]*>>[^;{}\n]*[;{}\n])', text) 100 | ret = [] 101 | for pattern in r: 102 | pattern = joinTuple(pattern) 103 | iter = re.finditer(r"([\s\t\n,;()]*)(std[\s\t]*::[\s\t]*|)(cin)", pattern) 104 | indices = [m.start(0) for m in iter] 105 | for i in indices: 106 | while pattern[i] != 'c' and pattern[i] != 's': 107 | i += 1 108 | s = pattern[i] 109 | # variable to check if brackets are balanced at that moment 110 | bra = 0 111 | # variable to check if parenthesis are balanced at that moment 112 | par = 0 113 | while (not pattern[i] in [',', ';', '&', '|', '\n']) or (par != 0) or (bra != 0): 114 | if pattern[i] == '(': 115 | par += 1 116 | elif pattern[i] == ')': 117 | par -= 1 118 | if par < 0: 119 | break 120 | elif pattern[i] == '[': 121 | bra += 1 122 | elif pattern[i] == ']': 123 | bra -= 1 124 | if bra < 0: 125 | break 126 | 127 | i += 1 128 | s += pattern[i] 129 | ret.append(s) 130 | return ret 131 | 132 | def replaceInput(text, cinEntries): 133 | for pattern in cinEntries: 134 | aux = '' 135 | last = pattern[-1] 136 | # delete special characters like semicolon (;) or comma (,) from line 137 | x = pattern[:-1] 138 | l = x.split('>>') 139 | # delete cin from list 140 | l.pop(0) 141 | for y in l: 142 | aux += '__FIO__.READ_VAR(' + removeSpacesFromVar(y) + ')' + ', ' 143 | aux = aux[:-2] + last 144 | text = text.replace(pattern, aux) 145 | return text 146 | 147 | def getCoutEntries(text): 148 | r = re.findall(r'[\s\t\n,;()]*(std[\s\t]*::[\s\t]*|)(cout[\s\t\n]*<<[^;{}\n]*[;{}\n])', text) 149 | ret = [] 150 | for pattern in r: 151 | pattern = joinTuple(pattern) 152 | iter = re.finditer(r"([\s\t\n,;()]*)(std[\s\t]*::[\s\t]*|)(cout)", pattern) 153 | indices = [m.start(0) for m in iter] 154 | for i in indices: 155 | while pattern[i] != 'c' and pattern[i] != 's': 156 | i += 1 157 | s = pattern[i] 158 | # variable to check if brackets are balanced at that moment 159 | bra = 0 160 | # variable to check if parenthesis are balanced at that moment 161 | par = 0 162 | while (not pattern[i] in [',', ';', '&', '|', '\n']) or (par != 0) or (bra != 0): 163 | if pattern[i] == '(': 164 | par += 1 165 | elif pattern[i] == ')': 166 | par -= 1 167 | if par < 0: 168 | break 169 | elif pattern[i] == '[': 170 | bra += 1 171 | elif pattern[i] == ']': 172 | bra -= 1 173 | if bra < 0: 174 | break 175 | 176 | i += 1 177 | s += pattern[i] 178 | ret.append(s) 179 | return ret 180 | 181 | def replaceOutput(text, coutEntries): 182 | for pattern in coutEntries: 183 | aux = '' 184 | last = pattern[-1] 185 | # delete semicolon (;) or comma (,) from line 186 | x = pattern[:-1] 187 | l = customSplit(x, '<<') 188 | # delete cout from list 189 | l.pop(0) 190 | # print (pattern) 191 | for y in l: 192 | aux += '__FIO__.WRITE_VAR(' + removeSpacesFromVar(y) + ')' + ', ' 193 | aux = aux[:-2] + last 194 | text = text.replace(pattern, aux) 195 | 196 | return text 197 | 198 | 199 | def removeDeSync(text): 200 | r = [] 201 | # remove all desync 202 | r += re.findall(r'(std[\s\t]*::[\s\t]*|)(ios[\t\s]*::|ios_base[\t\s]*::)([\t\s]*sync_with_stdio[\t\s]*\([\t\s]*)([^\)]*)([\t\s]*\)[\t\s]*[,;\n])', text) 203 | r += re.findall(r'(std[\s\t]*::[\s\t]*|)(cin|cout)([\s\t]*\.[\s\t]*tie[\s\t]*\([\s\t]*)([^\)]*)([\s\t]*\)[\s\t]*[;,\n])', text) 204 | 205 | # replace desync with 0 206 | for pattern in r: 207 | pattern = joinTuple(pattern) 208 | last = pattern[-1] 209 | pattern = pattern[:-1] 210 | text = text.replace(pattern + last, '0' + last) 211 | 212 | return text 213 | 214 | 215 | def getGetlineEntriesAndReplace(text): 216 | r = re.findall(r'getline[\s\t]*\([^;{}\n]*[;{}\n]', text) 217 | for pattern in r: 218 | iter = re.finditer(r"[\s\t\n,;()]*getline", pattern) 219 | indices = [m.start(0) for m in iter] 220 | for i in indices: 221 | while pattern[i] != 'g': 222 | i += 1 223 | i += 8 224 | s = 'getline(' 225 | # variable to check if brackets are balanced at that moment 226 | bra = 0 227 | # variable to check if parenthesis are balanced at that moment 228 | par = 0 229 | while (pattern[i] != ',') or (par != 0) or (bra != 0): 230 | if pattern[i] == '(': 231 | par += 1 232 | elif pattern[i] == ')': 233 | par -= 1 234 | if par < 0: 235 | break 236 | elif pattern[i] == '[': 237 | bra += 1 238 | elif pattern[i] == ']': 239 | bra -= 1 240 | if bra < 0: 241 | break 242 | s += pattern[i]; 243 | i += 1 244 | s += ','; 245 | i += 1 246 | var = '' 247 | while (pattern[i] != ')') or (par != 0) or (bra != 0): 248 | if pattern[i] == '(': 249 | par += 1 250 | elif pattern[i] == ')': 251 | par -= 1 252 | if par < 0: 253 | break 254 | elif pattern[i] == '[': 255 | bra += 1 256 | elif pattern[i] == ']': 257 | bra -= 1 258 | if bra < 0: 259 | break 260 | 261 | s += pattern[i] 262 | var += pattern[i] 263 | i += 1 264 | s += ')' 265 | var = re.sub(' ', '', var) 266 | text = text.replace(s, '__FIO__.READ_GETLINE(' + var + ')') 267 | return text 268 | 269 | def undefMacros(text): 270 | 271 | r = [] 272 | r += re.findall(r'#[\s\t]*define[\s\t]+[^\s\t]+\([^\n\)]*\)', text) 273 | r += re.findall(r'#[\s\t]*define[\s\t]+[^\s\t\(]*', text) 274 | 275 | undefs = '\n\n' 276 | for pattern in r: 277 | pattern = re.sub(r'#[\s\t]*define', '#undef', pattern) 278 | pattern = re.sub(r'\([^\)]*\)', '', pattern) 279 | pattern += '\n' 280 | undefs += pattern 281 | 282 | text += undefs 283 | 284 | return text 285 | 286 | def replaceCinIgnore(text): 287 | r = re.findall(r'(std[\s\t]*::[\s\t]*|)(cin[\s\t]*\.[\s\t]*ignore[\s\t]*\([\s\t]*\))', text) 288 | for pattern in r: 289 | pattern = joinTuple(pattern) 290 | text = text.replace(pattern, '__FIO__.ignore()') 291 | return text 292 | 293 | def replaceOstream(text): 294 | # replace cout.flush() 295 | text = re.sub(r'(std[\s\t]*::[\s\t]*|)(cout[\s\t]*\.[\s\t]*flush[\s\t]*\([\s\t]*\))', '__FIO__.flush()', text) 296 | 297 | #replace cout << flush 298 | text = re.sub(r'(__FIO__.WRITE_VAR\()(std[\s\t]*::[\s\t]*|)(flush\))', '__FIO__.flush()', text) 299 | 300 | #replace cout << endl 301 | text = re.sub(r'(__FIO__.WRITE_VAR\()(std[\s\t]*::[\s\t]*|)(endl\))', "__FIO__.WRITE_VAR(endl)", text) 302 | text = text.replace('__FIO__.WRITE_VAR(endl)', "putchar('\\n')") 303 | 304 | return text 305 | 306 | def getAndSetPrecision(text): 307 | 308 | # remove cout << fixed 309 | text = re.sub(r'(__FIO__.WRITE_VAR\()(std[\s\t]*::[\s\t]*|)([\s\t]*fixed[\s\t]*)(\))', '0', text) 310 | 311 | r = re.findall(r'(__FIO__.WRITE_VAR\()(std[\s\t]*::[\s\t]*|)([\s\t]*setprecision[\s\t]*\([\s\t]*)([0-9]*)([\s\t]*\)\))', text) 312 | precision = '' 313 | pattern = '' 314 | if r: 315 | pattern = joinTuple(r[0]) 316 | precision = r[0][3] 317 | text = text.replace(pattern, '0') 318 | text = text.replace('printf(\"%f\", x);', 'printf(\"%.' + precision +'f\", x);') 319 | text = text.replace('printf(\"%lf\", (double)x);', 'printf(\"%.' + precision + 'lf\", (double)x);') 320 | 321 | if len(r) > 1: 322 | text = warningSetPrecisionMessage + text + warningSetPrecisionMessage 323 | 324 | return text 325 | 326 | def findBackslash(text): 327 | r = re.findall(r'[\s\n\t]\\[\s\n\t]', text) 328 | if r: 329 | text = warningBackslashMessage + text + warningBackslashMessage 330 | 331 | return text 332 | 333 | # Function below copied from StackOverflow 334 | # Link to original question: https://stackoverflow.com/questions/241327/python-snippet-to-remove-c-and-c-comments 335 | # Author of the question: TomZ (https://stackoverflow.com/users/26251/tomz) 336 | # Author of the answer: Markus Jarderot (https://stackoverflow.com/users/22364/markus-jarderot) 337 | def comment_remover(text): 338 | def replacer(match): 339 | s = match.group(0) 340 | if s.startswith('/'): 341 | return " " # note: a space and not an empty string 342 | else: 343 | return s 344 | pattern = re.compile( 345 | r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', 346 | re.DOTALL | re.MULTILINE 347 | ) 348 | return re.sub(pattern, replacer, text) 349 | 350 | def convertToFastIO(code): 351 | 352 | code = comment_remover(code) 353 | code = removeEnter(code) 354 | code = coverStrings(code) 355 | code = removeDeSync(code) 356 | code = undefMacros(code) 357 | code = getGetlineEntriesAndReplace(code) 358 | code = replaceCinIgnore(code) 359 | 360 | x = getCinEntries(code) 361 | code = (replaceInput(code, x)) 362 | 363 | x = getCoutEntries(code) 364 | code = (replaceOutput(code, x)) 365 | 366 | code = replaceOstream(code) 367 | 368 | struct = (open("struct.cpp", "r")).read() 369 | code = struct + code 370 | code = "#include \n" + code 371 | code += (open("functions.cpp", "r")).read() 372 | 373 | code = findBackslash(code) 374 | code = getAndSetPrecision(code) 375 | 376 | code = uncoverStrings(code) 377 | 378 | return code 379 | 380 | -------------------------------------------------------------------------------- /fastio.py: -------------------------------------------------------------------------------- 1 | import converter 2 | import sys 3 | 4 | # if you do not want to print the code in terminal set 5 | # the variable to false 6 | printInTerminal = True 7 | 8 | # if you do not want to print the code in a new file 9 | # set the variable below to false 10 | printInFile = True 11 | 12 | fileName = '' 13 | if len(sys.argv) == 2: 14 | fileName = sys.argv[1] 15 | else: 16 | fileName = input('Type the name of the file\n') 17 | 18 | while True: 19 | try: 20 | code = open(fileName, "r").read() 21 | break 22 | except: 23 | fileName = input('File not found, try again\n') 24 | 25 | code = converter.convertToFastIO(code) 26 | 27 | if printInFile: 28 | r = fileName.split('/') 29 | newName = 'FastIO-' + r[-1] 30 | file = open(newName, 'w') 31 | file.write(code) 32 | file.close() 33 | 34 | if printInTerminal: 35 | print (code) 36 | -------------------------------------------------------------------------------- /functions.cpp: -------------------------------------------------------------------------------- 1 | 2 | inline void FASTIO::ignore() { 3 | if(REMAINING_CHARACTER == true) REMAINING_CHARACTER = false; else READ_CHARACTER = getchar(); 4 | } 5 | 6 | inline void FASTIO::flush() { 7 | fflush(stdout); 8 | } 9 | 10 | // cin modifications 11 | 12 | template 13 | inline bool FASTIO::READ_INT(T &x) { 14 | x = 0; T sig = 1; 15 | if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false; 16 | while (!isdigit(READ_CHARACTER) && READ_CHARACTER != EOF) sig = (READ_CHARACTER == '-' ? -sig : sig), READ_CHARACTER = getchar(); 17 | if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false; 18 | while (isdigit(READ_CHARACTER)) x = x * 10 + READ_CHARACTER - '0', READ_CHARACTER = getchar(); 19 | x *= sig; REMAINING_CHARACTER = true; 20 | return true; 21 | } 22 | 23 | template 24 | inline bool FASTIO::READ_STRING(T &x) { 25 | x = ""; 26 | if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false; 27 | while ((READ_CHARACTER == '\n' || READ_CHARACTER == '\t' || READ_CHARACTER == ' ')) READ_CHARACTER = getchar(); 28 | if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false; 29 | while ((READ_CHARACTER != '\n' && READ_CHARACTER != '\t' && READ_CHARACTER != ' ' && READ_CHARACTER != EOF)) x += READ_CHARACTER, READ_CHARACTER = getchar(); 30 | REMAINING_CHARACTER = true; 31 | return true; 32 | } 33 | 34 | inline bool FASTIO::READ_GETLINE(std::string &x) { 35 | x = ""; 36 | if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false; 37 | if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false; 38 | while ((READ_CHARACTER != '\n' && READ_CHARACTER != EOF)) x += READ_CHARACTER, READ_CHARACTER = getchar(); 39 | REMAINING_CHARACTER = false; 40 | return true; 41 | } 42 | 43 | template 44 | inline bool FASTIO::READ_CHAR(T &x) { 45 | if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false; 46 | if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false; 47 | while ((READ_CHARACTER == '\n' || READ_CHARACTER == '\t' || READ_CHARACTER == ' ')) READ_CHARACTER = getchar(); 48 | x = READ_CHARACTER; REMAINING_CHARACTER = false; 49 | return true; 50 | } 51 | 52 | 53 | template 54 | inline bool FASTIO::READ_CHAR_ARRAY(char (&x)[N]) { 55 | if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false; 56 | while ((READ_CHARACTER == '\n' || READ_CHARACTER == '\t' || READ_CHARACTER == ' ')) READ_CHARACTER = getchar(); 57 | if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false; 58 | char *ptr = &x[0]; 59 | while ((READ_CHARACTER != '\n' && READ_CHARACTER != '\t' && READ_CHARACTER != ' ' && READ_CHARACTER != EOF)) *ptr++ = READ_CHARACTER, READ_CHARACTER = getchar(); 60 | *ptr = '\0', REMAINING_CHARACTER = true; 61 | return true; 62 | } 63 | 64 | inline bool FASTIO::READ_CHAR_ARRAY(char*& x) { 65 | std::string y; 66 | if(READ_STRING(y) == false) 67 | return false; 68 | x = new char[(int)y.size() + 1]; 69 | strcpy(x, y.c_str()); 70 | return true; 71 | } 72 | 73 | template 74 | inline bool FASTIO::READ_FLOAT(T &x) { 75 | return (scanf("%f", &x) != EOF); 76 | } 77 | 78 | template 79 | inline bool FASTIO::READ_DOUBLE(T &x) { 80 | double y; 81 | if(scanf("%lf", &y) == EOF) return false; 82 | x = y; 83 | return true; 84 | } 85 | 86 | template 87 | inline bool FASTIO::READ_BITSET(std::bitset &x) { 88 | if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false; 89 | while ((READ_CHARACTER == '\n' || READ_CHARACTER == '\t' || READ_CHARACTER == ' ')) READ_CHARACTER = getchar(); 90 | if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false; 91 | int i = 0; REMAINING_CHARACTER = true; 92 | while (READ_CHARACTER == '0' || READ_CHARACTER == '1') x[i++] = READ_CHARACTER - '0', READ_CHARACTER = getchar(); 93 | return true; 94 | } 95 | 96 | inline bool FASTIO::READ_VAR(short int &x) { 97 | return READ_INT(x); 98 | } 99 | 100 | inline bool FASTIO::READ_VAR(int &x) { 101 | return READ_INT(x); 102 | } 103 | 104 | inline bool FASTIO::READ_VAR(long int &x) { 105 | return READ_INT(x); 106 | } 107 | 108 | inline bool FASTIO::READ_VAR(long long int &x) { 109 | return READ_INT(x); 110 | } 111 | 112 | inline bool FASTIO::READ_VAR(unsigned short int &x) { 113 | return READ_INT(x); 114 | } 115 | 116 | inline bool FASTIO::READ_VAR(unsigned int &x) { 117 | return READ_INT(x); 118 | } 119 | 120 | inline bool FASTIO::READ_VAR(unsigned long &x) { 121 | return READ_INT(x); 122 | } 123 | 124 | inline bool FASTIO::READ_VAR(unsigned long long &x) { 125 | return READ_INT(x); 126 | } 127 | 128 | inline bool FASTIO::READ_VAR(std::string &x) { 129 | return READ_STRING(x); 130 | } 131 | 132 | inline bool FASTIO::READ_VAR(char &x) { 133 | return READ_CHAR(x); 134 | } 135 | 136 | template 137 | inline bool FASTIO::READ_VAR(char (&x)[N]) { 138 | return READ_CHAR_ARRAY(x); 139 | } 140 | 141 | inline bool FASTIO::READ_VAR(char*& x) { 142 | return READ_CHAR_ARRAY(x); 143 | } 144 | 145 | inline bool FASTIO::READ_VAR(float &x) { 146 | return READ_FLOAT(x); 147 | } 148 | 149 | inline bool FASTIO::READ_VAR(double &x) { 150 | return READ_DOUBLE(x); 151 | } 152 | 153 | inline bool FASTIO::READ_VAR(long double &x) { 154 | return READ_DOUBLE(x); 155 | } 156 | 157 | template 158 | inline bool FASTIO::READ_VAR(std::bitset &x) { 159 | return READ_BITSET(x); 160 | } 161 | 162 | // cout modifications 163 | 164 | template 165 | inline void FASTIO::WRITE_INT(T x) { 166 | if (x < 0) {putchar('-'); x = -x; } 167 | char writeBuffer[20], *writePtr = writeBuffer; 168 | do { 169 | *writePtr++ = '0' + x % 10; 170 | x /= 10; 171 | } 172 | while (x); 173 | do { putchar(*--writePtr); } 174 | while (writePtr > writeBuffer); 175 | } 176 | 177 | inline void FASTIO::WRITE_CHAR(char x) { 178 | putchar(x); 179 | } 180 | 181 | inline void FASTIO::WRITE_CHAR_ARRAY(const char *x) { 182 | while(*x != '\0') 183 | putchar(*x++); 184 | } 185 | 186 | inline void FASTIO::WRITE_STRING(std::string &x) { 187 | for(char c: x) 188 | putchar(c); 189 | } 190 | 191 | inline void FASTIO::WRITE_FLOAT(float x) { 192 | printf("%f", x); 193 | } 194 | 195 | template 196 | inline void FASTIO::WRITE_DOUBLE(T x) { 197 | printf("%lf", (double)x); 198 | } 199 | 200 | template 201 | inline void FASTIO::WRITE_BITSET(std::bitset &x) { 202 | for(int i = (int)x.size() - 1; i >= 0; i--) 203 | putchar(x[i] + 48); 204 | } 205 | 206 | inline void FASTIO::WRITE_VAR(bool x) { 207 | WRITE_INT(x); 208 | } 209 | 210 | inline void FASTIO::WRITE_VAR(short int x) { 211 | WRITE_INT(x); 212 | } 213 | 214 | inline void FASTIO::WRITE_VAR(int x) { 215 | WRITE_INT(x); 216 | } 217 | 218 | inline void FASTIO::WRITE_VAR(long int x) { 219 | WRITE_INT(x); 220 | } 221 | 222 | inline void FASTIO::WRITE_VAR(long long int x) { 223 | WRITE_INT(x); 224 | } 225 | 226 | inline void FASTIO::WRITE_VAR(unsigned short int x) { 227 | WRITE_INT(x); 228 | } 229 | 230 | inline void FASTIO::WRITE_VAR(unsigned int x) { 231 | WRITE_INT(x); 232 | } 233 | 234 | inline void FASTIO::WRITE_VAR(unsigned long x) { 235 | WRITE_INT(x); 236 | } 237 | 238 | inline void FASTIO::WRITE_VAR(unsigned long long x) { 239 | WRITE_INT(x); 240 | } 241 | 242 | inline void FASTIO::WRITE_VAR(std::string &x) { 243 | WRITE_STRING(x); 244 | } 245 | 246 | inline void FASTIO::WRITE_VAR(char x) { 247 | WRITE_CHAR(x); 248 | } 249 | 250 | inline void FASTIO::WRITE_VAR(const char *x) { 251 | WRITE_CHAR_ARRAY(x); 252 | } 253 | 254 | inline void FASTIO::WRITE_VAR(float x) { 255 | WRITE_FLOAT(x); 256 | } 257 | 258 | inline void FASTIO::WRITE_VAR(double x) { 259 | WRITE_DOUBLE(x); 260 | } 261 | 262 | inline void FASTIO::WRITE_VAR(long double x) { 263 | WRITE_DOUBLE(x); 264 | } 265 | 266 | template 267 | inline void FASTIO::WRITE_VAR(std::bitset &x) { 268 | WRITE_BITSET(x); 269 | } 270 | 271 | 272 | -------------------------------------------------------------------------------- /struct.cpp: -------------------------------------------------------------------------------- 1 | 2 | static struct FASTIO { 3 | 4 | char READ_CHARACTER; bool REMAINING_CHARACTER = false; 5 | 6 | inline void ignore(); inline void flush(); 7 | 8 | template inline bool READ_INT(T &x); template inline bool READ_STRING(T &x); 9 | /* Fast I/O Code Optimizer */ 10 | template inline bool READ_CHAR_ARRAY(char (&x)[N]); template inline bool READ_VAR(char (&x)[N]); 11 | /* A tool to optimize execution time of C++ codes by replacing methods of reading and writing variables */ 12 | template inline bool READ_CHAR(T &x); inline bool READ_CHAR_ARRAY(char*& x); inline bool READ_GETLINE(std::string &x); 13 | /* Use it on fastio.pythonanywhere.com */ 14 | template inline bool READ_FLOAT(T &x); template inline bool READ_DOUBLE(T &x); 15 | /* Github Project: github.com/bfs07/Fast-IO-Code-Optimizer */ 16 | template inline bool READ_BITSET(std::bitset &bit); template inline bool READ_VAR(std::bitset &bit); 17 | inline bool READ_VAR(bool &x); inline bool READ_VAR(short int &x); inline bool READ_VAR(int &x); 18 | inline bool READ_VAR(long int &x); inline bool READ_VAR(long long int &x); inline bool READ_VAR(unsigned short int &x); 19 | inline bool READ_VAR(unsigned int &x); inline bool READ_VAR(unsigned long &x); inline bool READ_VAR(unsigned long long &x); 20 | inline bool READ_VAR(std::string &x); inline bool READ_VAR(char &x); inline bool READ_VAR(char*& x); inline bool READ_VAR(float &x); 21 | inline bool READ_VAR(double &x); inline bool READ_VAR(long double &x); template inline void WRITE_INT(T x); 22 | inline void WRITE_STRING(std::string &x); inline void WRITE_CHAR(char x); inline void WRITE_CHAR_ARRAY(const char *x); 23 | inline void WRITE_FLOAT(float x); template inline void WRITE_DOUBLE(T x); inline void WRITE_VAR(bool x); 24 | inline void WRITE_VAR(short int x); inline void WRITE_VAR(int x); inline void WRITE_VAR(long int x); inline void WRITE_VAR(long long int x); 25 | inline void WRITE_VAR(unsigned short int x); inline void WRITE_VAR(unsigned int x); inline void WRITE_VAR(unsigned long x); 26 | inline void WRITE_VAR(unsigned long long x); inline void WRITE_VAR(char x); inline void WRITE_VAR(const char *x); 27 | inline void WRITE_VAR(std::string &x); inline void WRITE_VAR(float x); inline void WRITE_VAR(double x); inline void WRITE_VAR(long double x); 28 | template inline void WRITE_VAR(std::bitset &bit); template inline void WRITE_BITSET(std::bitset &bit); 29 | 30 | } __FIO__; 31 | 32 | 33 | --------------------------------------------------------------------------------