fork download
  1. import unittest
  2.  
  3.  
  4. def main():
  5. lines = [
  6. '1:>>2',
  7. '2:>>1',
  8. '3:>>1-3',
  9. '4:>>1,3',
  10. '5:>>1,2-4',
  11. ]
  12. nodes = []
  13.  
  14. for line in lines:
  15. line = line.strip()
  16. no, content = line.split(':')
  17. ancs = parse_anchor(content)
  18. nodes.append({
  19. 'no': no,
  20. 'content': content,
  21. 'ancs': ancs,
  22. 'count': 0,
  23. })
  24.  
  25. for n in nodes:
  26. for a in n['ancs']:
  27. if isinstance(a, tuple):
  28. for i in range(a[0] - 1, a[1]):
  29. nodes[i]['count'] += 1
  30. else:
  31. nodes[a - 1]['count'] += 1
  32.  
  33. for n in sorted(nodes, key=lambda n: n['count'], reverse=True):
  34. print(f'{n["no"]}:{n["count"]}')
  35.  
  36.  
  37. def parse_anchor(s):
  38. m = 'first'
  39. buf = ''
  40. fd = 0
  41. i = 0
  42. ancs = []
  43. s += ' '
  44.  
  45. while i < len(s):
  46. c = s[i]
  47. if m == 'first':
  48. if c == '>':
  49. m = 'found >'
  50. elif m == 'found >':
  51. if c == '>':
  52. m = 'anchor'
  53. else:
  54. m = 'first'
  55. elif m == 'anchor':
  56. if c.isdigit():
  57. buf += c
  58. m = 'read digit'
  59. elif c.isspace():
  60. ancs.append(int(buf))
  61. buf = ''
  62. elif m == 'read digit':
  63. if c.isdigit():
  64. buf += c
  65. elif c == ',':
  66. ancs.append(int(buf))
  67. buf = ''
  68. elif c == '-':
  69. fd = int(buf)
  70. buf = ''
  71. m = 'read second digit'
  72. elif c.isspace():
  73. ancs.append(int(buf))
  74. buf = ''
  75. else:
  76. ancs.append(int(buf))
  77. buf = ''
  78. m = 'first'
  79. elif m == 'read second digit':
  80. if c.isdigit():
  81. buf += c
  82. elif c == ',':
  83. ancs.append((fd, int(buf)))
  84. buf = ''
  85. m = 'anchor'
  86. elif c.isspace():
  87. ancs.append((fd, int(buf)))
  88. buf = ''
  89. else:
  90. ancs.append((fd, int(buf)))
  91. buf = ''
  92. m = 'first'
  93.  
  94. i += 1
  95.  
  96. return ancs
  97.  
  98.  
  99. main()
  100.  
  101.  
  102. class ParseAnchorTest(unittest.TestCase):
  103. def test_parse(self):
  104. self.assertEqual(str(parse_anchor('>')), '[]')
  105. self.assertEqual(str(parse_anchor('>,')), '[]')
  106. self.assertEqual(str(parse_anchor('>>1')), '[1]')
  107. self.assertEqual(str(parse_anchor('>>,1')), '[1]')
  108. self.assertEqual(str(parse_anchor('>>1,2')), '[1, 2]')
  109. self.assertEqual(str(parse_anchor('>>1,2,3')), '[1, 2, 3]')
  110. self.assertEqual(str(parse_anchor('>>1-2')), '[(1, 2)]')
  111. self.assertEqual(str(parse_anchor('>>1-2,3-4')), '[(1, 2), (3, 4)]')
  112. self.assertEqual(
  113. str(parse_anchor('text>>1-2,3-4text')), '[(1, 2), (3, 4)]')
  114. self.assertEqual(str(parse_anchor('abc>>1,2def')), '[1, 2]')
  115.  
Success #stdin #stdout 0.03s 11544KB
stdin
Standard input is empty
stdout
1:4
2:3
3:3
4:1
5:0