Last active
March 18, 2021 15:34
-
-
Save ecamellini/980068028ab8457ca733a477c638d935 to your computer and use it in GitHub Desktop.
Solving the Simple Text Editor challenge as fast as possible. See challenge here: https://www.hackerrank.com/challenges/simple-text-editor/problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Challenge: https://www.hackerrank.com/challenges/simple-text-editor/problem | |
# Trying to solve it as fast as possible! | |
import sys | |
from collections import namedtuple | |
import re | |
# Inizializing global variables (I don't like global vars, it's faster like this...) | |
output = False # If False, output of print operations is disabled | |
SHistory = [] | |
S = "" | |
WTotLen = 0 | |
kSum = 0 | |
### Functions to manage global vars ### | |
def resetGlobalVars(): | |
global SHistory | |
global S | |
global WTotLen | |
global kSum | |
SHistory = [] | |
S = "" | |
WTotLen = 0 | |
kSum = 0 | |
def toggleOutput(): | |
global output | |
output = not(output) | |
### Functions to check constraints ### | |
def checkIndex(k): | |
# Checking constraint 2 | |
global S | |
if (k < 1 or k > len(S)): | |
raise IndexError("Index parameter k must be so that: 1 <= k <= len(S)") | |
def checkWTotLen(W): | |
# Checking constraint 3 | |
global WTotLen | |
WTotLen = WTotLen + len(W) | |
if (WTotLen > pow(10, 6)): | |
raise ValueError( | |
"The sum of the lengths of all W in the input must be <= 10ˆ6") | |
### Functions to execute operations ### | |
def appendString(W): | |
global S | |
checkWTotLen(W) | |
SHistory.append(S) | |
S = S + W | |
def deleteLastChars(k): | |
global S | |
global kSum | |
kSum = kSum + k | |
# Checking constraint 4 | |
if (kSum > 2*pow(10, 6)): | |
raise ValueError( | |
"The sum of of all k over all delete operations must be <= 2*10ˆ6" | |
) | |
checkIndex(k) | |
SHistory.append(S) | |
S = S[0:len(S)-k] | |
def printChar(k): | |
global S | |
checkIndex(k) | |
if output: | |
print(S[k - 1]) | |
def undo(): | |
global S | |
S = SHistory.pop() | |
Operation = namedtuple('Operation', 'function args originalLine') | |
operations = [] | |
### Main execution ### | |
input = sys.stdin.readlines() | |
# Checking constraint 1 | |
opsCount = int(input[0]) | |
if (opsCount < 1 or opsCount > pow(10, 6)): | |
sys.exit("Unsupported numer of operations (Q): 1 <= Q <= 10ˆ6") | |
for line in input[1:opsCount+1]: | |
if (line[-1] != "\n"): | |
line = line + '\n' | |
def extractParam(): | |
return line[2:].replace("\n", "") | |
def unsupportedOperation(): | |
print("Unsupported operation: %s" % line) | |
if (line[0] == "1"): | |
# Checking constraint 5 | |
if not re.match(r"^1 ([a-z])+\n$", line): | |
unsupportedOperation() | |
sys.exit( | |
"Append operation usage: 1 string\nExample: 1 asd\nAll input characters must be lowercase English letters." | |
) | |
operations.append( | |
Operation(appendString, [extractParam()], line)) | |
elif(line[0] == "2"): | |
if not re.match(r"^2 (\d)+\n$", line): | |
unsupportedOperation() | |
sys.exit("Delete operation usage: 2 number\nExample: 2 2") | |
operations.append( | |
Operation(deleteLastChars, [int(extractParam())], line)) | |
elif(line[0] == "3"): | |
if not re.match(r"^3 (\d)+\n$", line): | |
unsupportedOperation() | |
sys.exit("Print operation usage: 3 number\nExample: 3 2") | |
operations.append(Operation(printChar, [int(extractParam())], line)) | |
elif(line[0] == "4"): | |
if line != "4\n": | |
unsupportedOperation() | |
sys.exit("Undo operation usage: 4\nNo parameters, no trailing space.") | |
operations.append(Operation(undo, [], line)) | |
else: | |
unsupportedOperation() | |
sys.exit() | |
# Checking constraint 6: executing operations and checking if there are exceptions | |
for idx, operation in enumerate(operations): | |
try: | |
operation.function(*operation.args) | |
except: | |
print( | |
"The sequence of operations given as input cannot be performed." | |
) | |
print( | |
"The operation that triggered the error is: %s (Operation number %d)" | |
% (operation.originalLine, idx) | |
) | |
e = sys.exc_info() | |
sys.exit("Error: %s" % str(e)) | |
# Resetting everything, enabling input, executing operations again... | |
# For sure there is a better method to do it :) | |
toggleOutput() | |
resetGlobalVars() | |
for operation in operations: | |
operation.function(*operation.args) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Testing that it works with the sample input: