fork(4) download
  1. #Change the CODE and OUTPUT strings to test your program
  2.  
  3. CODE = r'''abb1'''
  4.  
  5. OUTPUT = r'''My source has 4 characters.
  6. 1 is "a"
  7. 2 are "b"
  8. 1 is "1"
  9. Besides unquoted numbers, my output has 383 characters.
  10. 34 are "
  11. "
  12. 79 are " "
  13. 63 are """
  14. 2 are "'"
  15. 2 are ","
  16. 4 are "."
  17. 2 are "1"
  18. 2 are "B"
  19. 2 are "I"
  20. 2 are "M"
  21. 39 are "a"
  22. 4 are "b"
  23. 6 are "c"
  24. 4 are "d"
  25. 38 are "e"
  26. 3 are "g"
  27. 5 are "h"
  28. 4 are "i"
  29. 4 are "m"
  30. 3 are "n"
  31. 8 are "o"
  32. 3 are "p"
  33. 2 are "q"
  34. 38 are "r"
  35. 12 are "s"
  36. 8 are "t"
  37. 7 are "u"
  38. 3 are "y"
  39. It's good to be a program.'''
  40.  
  41. #######################################################
  42.  
  43. import re
  44.  
  45. amountPattern = r'(\d+) (is|are) "(.)"\n'
  46.  
  47. class IntrospectionException(Exception):
  48. pass
  49.  
  50. def getClaimedAmounts(string, errorOnIs):
  51. groups = re.findall(amountPattern, string, re.DOTALL)
  52.  
  53. for amount, verb, char in groups:
  54. if verb == 'is':
  55. if errorOnIs:
  56. raise IntrospectionException('\'1 is "%s"\' is unnecessary' % char)
  57. elif amount != '1':
  58. raise IntrospectionException('At "%s", %s must use "are"' % (char, amount))
  59. elif verb == 'are' and amount == '1':
  60. raise IntrospectionException('At "%s", 1 must use "is"' % char)
  61.  
  62. amounts = {}
  63. for amount, verb, char in groups:
  64. if char in amounts:
  65. raise IntrospectionException('Duplicate "%s" found' % char)
  66. amounts[char] = int(amount)
  67. return amounts
  68.  
  69. def getActualAmounts(string):
  70. amounts = {}
  71. for char in string:
  72. if char in amounts:
  73. amounts[char] += 1
  74. else:
  75. amounts[char] = 1
  76. return amounts
  77.  
  78. def compareAmounts(claimed, actual):
  79. for char in actual:
  80. if char not in claimed:
  81. raise IntrospectionException('The amounts list is missing "%s"' % char)
  82. for char in actual: #loop separately so missing character errors are all found first
  83. if claimed[char] != actual[char]:
  84. raise IntrospectionException('The amount of "%s" characters is %d, not %d' % (char, actual[char], claimed[char]))
  85. if claimed != actual:
  86. raise IntrospectionException('The amounts are somehow incorrect')
  87.  
  88. def isCorrect(code, output):
  89. p1 = r'^My source has (\d+) characters\.\n'
  90. p2 = r'Besides unquoted numbers, my output has (\d+) characters\.\n'
  91. p3 = r"It's good to be a program\.$"
  92. p4 = '%s(%s)*%s(%s)*%s' % (p1, amountPattern, p2, amountPattern, p3)
  93.  
  94. for p in [p1, p2, p3, p4]:
  95. if re.search(p, output, re.DOTALL) == None:
  96. raise IntrospectionException('Did not match the regex "%s"' % p)
  97.  
  98. claimedCodeSize = int(re.search(p1, output).groups()[0])
  99. actualCodeSize = len(code)
  100. if claimedCodeSize != actualCodeSize:
  101. raise IntrospectionException('The code length is %d, not %d' % (actualCodeSize, claimedCodeSize))
  102.  
  103. filteredOutput = re.sub(r'([^"])\d+([^"])', r'\1\2', output)
  104.  
  105. claimedOutputSize = int(re.search(p2, output).groups()[0])
  106. actualOutputSize = len(filteredOutput)
  107. if claimedOutputSize != actualOutputSize:
  108. raise IntrospectionException('The output length (excluding unquoted numbers) is %d, not %d' % (actualOutputSize, claimedOutputSize))
  109.  
  110. splitIndex = re.search(p2, output).start()
  111.  
  112. claimedCodeAmounts = getClaimedAmounts(output[:splitIndex], False)
  113. actualCodeAmounts = getActualAmounts(code)
  114. compareAmounts(claimedCodeAmounts, actualCodeAmounts)
  115.  
  116. claimedOutputAmounts = getClaimedAmounts(output[splitIndex:], True)
  117. actualOutputAmounts = getActualAmounts(filteredOutput)
  118. compareAmounts(claimedOutputAmounts, actualOutputAmounts)
  119.  
  120. def checkCorrectness():
  121. try:
  122. isCorrect(CODE, OUTPUT)
  123. print 'Everything is correct!'
  124. except IntrospectionException as e:
  125. print 'Failed: %s.' % e
  126.  
  127. checkCorrectness()
Success #stdin #stdout 0.01s 7852KB
stdin
Standard input is empty
stdout
Everything is correct!