Transaction Store With Rollback

Transaction Store With Rollback

Hard Python Error Handling 11 views
Explanation Complexity

Problem Statement

You will receive q commands: BEGIN, COMMIT, ROLLBACK, SET k v, GET k. Implement nested transactions. GET prints value or NOT FOUND. If COMMIT/ROLLBACK is invalid, output ERROR and stop.

Input Format

First line q. Next q lines commands.

Output Format

Outputs for GET or ERROR.

Example

9
SET a 1
BEGIN
SET a 2
GET a
ROLLBACK
GET a
COMMIT
BEGIN
COMMIT
2
1
ERROR

Constraints

q

Input / Output Format

Input Format
First line q. Next q lines commands.
Output Format
Outputs for GET or ERROR.
Constraints
q

Examples

Input:
9 SET a 1 BEGIN SET a 2 GET a ROLLBACK GET a COMMIT BEGIN COMMIT
Output:
2 1 ERROR

Example Solution (Public)

Python
import sys
lines=sys.stdin.read().splitlines()
if not lines: sys.exit(0)
q=int(lines[0].strip())
base={}
st=[]
out=[]
def getv(k):
  for layer in reversed(st):
    if k in layer:
      return layer[k]
  return base.get(k)
for i in range(1,1+q):
  parts=(lines[i] if i<len(lines) else '').split()
  if not parts:
    continue
  cmd=parts[0]
  if cmd=='BEGIN':
    st.append({})
  elif cmd=='COMMIT':
    if not st:
      sys.stdout.write('ERROR')
      raise SystemExit
    top=st.pop()
    if st:
      st[-1].update(top)
    else:
      base.update(top)
  elif cmd=='ROLLBACK':
    if not st:
      sys.stdout.write('ERROR')
      raise SystemExit
    st.pop()
  elif cmd=='SET':
    if len(parts)<3:
      sys.stdout.write('ERROR')
      raise SystemExit
    k=parts[1]
    v=parts[2]
    if st:
      st[-1][k]=v
    else:
      base[k]=v
  elif cmd=='GET':
    if len(parts)<2:
      sys.stdout.write('ERROR')
      raise SystemExit
    v=getv(parts[1])
    out.append(v if v is not None else 'NOT FOUND')
  else:
    sys.stdout.write('ERROR')
    raise SystemExit
sys.stdout.write('\
'.join(out))

Official Solution Code

import sys
lines=sys.stdin.read().splitlines()
if not lines: sys.exit(0)
q=int(lines[0].strip())
base={}
st=[]
out=[]
def getv(k):
  for layer in reversed(st):
    if k in layer:
      return layer[k]
  return base.get(k)
for i in range(1,1+q):
  parts=(lines[i] if i<len(lines) else '').split()
  if not parts:
    continue
  cmd=parts[0]
  if cmd=='BEGIN':
    st.append({})
  elif cmd=='COMMIT':
    if not st:
      sys.stdout.write('ERROR')
      raise SystemExit
    top=st.pop()
    if st:
      st[-1].update(top)
    else:
      base.update(top)
  elif cmd=='ROLLBACK':
    if not st:
      sys.stdout.write('ERROR')
      raise SystemExit
    st.pop()
  elif cmd=='SET':
    if len(parts)<3:
      sys.stdout.write('ERROR')
      raise SystemExit
    k=parts[1]
    v=parts[2]
    if st:
      st[-1][k]=v
    else:
      base[k]=v
  elif cmd=='GET':
    if len(parts)<2:
      sys.stdout.write('ERROR')
      raise SystemExit
    v=getv(parts[1])
    out.append(v if v is not None else 'NOT FOUND')
  else:
    sys.stdout.write('ERROR')
    raise SystemExit
sys.stdout.write('\
'.join(out))
Please login to submit solutions.
Editor
Output

                                        
Please login to submit solutions.