import re
SS = str(13**100500)
print(len(SS))
SUB = '637036977498347229246'
TEMPLATE = "63@036@7749@347@29@46"
#time_start = time.monotonic()
#result = SS.find(SUB)
#time_end = time.monotonic()
#print(f"result: {result}, str search worktime: {1000 * (time_end - time_start):.3f}ms")
def check_pattern_3(s, template):
m_shifts = []
t_shift = 0
for substr in template.split('@'):
if substr:
m_shifts.append((t_shift, substr))
t_shift += len(substr) + 1
# special cases
if len(m_shifts) == 0:
return 0 if len(template) <= len(s) else -1
max_shift = len(s) - len(template)
curr_shift = 0
while curr_shift <= max_shift:
next_shift = curr_shift
for shift_substr, substr in m_shifts:
next_shift = s.find(substr, next_shift + shift_substr) - shift_substr
if next_shift < 0:
return -1
if next_shift == curr_shift:
return curr_shift
else:
curr_shift = next_shift
return -1
def check_pattern_re(s, template):
res = re.findall(template.replace('@', '.'), s)
return s.find(res[0]) if res else -1
def run_tests(func, name='no name'):
is_fail = False
test_cases = [
('', '', 0),
('0011223344', '', 0),
('0011223344', '@', 0),
('00', '@@', 0),
('00', '@@@', -1),
('0123', '0123', 0),
('0123', '@1', 0),
('0123', '@0', -1),
('0123', '@3', 2),
('0123', '@4', -1),
('0123', '@0@', -1),
('0123', '@1@', 0),
('0123', '@2@', 1),
('0123', '@3@', -1),
('0000111', '@0011@', 1),
('xxxaaabbbcccxxx', 'aa@bb@cc', 3),
('xxxaaabbbcccxxx', 'aa@bb@@cc', 3),
('xxxaaabbbcccxxx', 'aa@bb@@@cc', -1),
]
for test_str, test_template, test_expected in test_cases:
ret = func(test_str, test_template)
if ret != test_expected:
is_fail = True
print(f"[{name}] Test fail", test_str, test_template, ret, test_expected)
run_tests(check_pattern_re, 'version re')
run_tests(check_pattern_3, 'version 3')
time_start
= time.
monotonic()result = check_pattern_3(SS, TEMPLATE)
time_end
= time.
monotonic()
worktime = 1000 * (time_end - time_start)
print(f"result: {result}, worktime: {worktime:.3f}ms")
aW1wb3J0IHJlCmltcG9ydCB0aW1lCgpTUyA9IHN0cigxMyoqMTAwNTAwKQpwcmludChsZW4oU1MpKQpTVUIgPSAnNjM3MDM2OTc3NDk4MzQ3MjI5MjQ2JwpURU1QTEFURSA9ICI2M0AwMzZANzc0OUAzNDdAMjlANDYiCgojdGltZV9zdGFydCA9IHRpbWUubW9ub3RvbmljKCkKI3Jlc3VsdCA9IFNTLmZpbmQoU1VCKQojdGltZV9lbmQgPSB0aW1lLm1vbm90b25pYygpCiNwcmludChmInJlc3VsdDoge3Jlc3VsdH0sIHN0ciBzZWFyY2ggd29ya3RpbWU6IHsxMDAwICogKHRpbWVfZW5kIC0gdGltZV9zdGFydCk6LjNmfW1zIikKCgpkZWYgY2hlY2tfcGF0dGVybl8zKHMsIHRlbXBsYXRlKToKICAgIG1fc2hpZnRzID0gW10KICAgIHRfc2hpZnQgPSAwCiAgICBmb3Igc3Vic3RyIGluIHRlbXBsYXRlLnNwbGl0KCdAJyk6CiAgICAgICAgaWYgc3Vic3RyOgogICAgICAgICAgICBtX3NoaWZ0cy5hcHBlbmQoKHRfc2hpZnQsIHN1YnN0cikpCiAgICAgICAgdF9zaGlmdCArPSBsZW4oc3Vic3RyKSArIDEKCiAgICAjIHNwZWNpYWwgY2FzZXMKICAgIGlmIGxlbihtX3NoaWZ0cykgPT0gMDoKICAgICAgICByZXR1cm4gMCBpZiBsZW4odGVtcGxhdGUpIDw9IGxlbihzKSBlbHNlIC0xCgogICAgbWF4X3NoaWZ0ID0gbGVuKHMpIC0gbGVuKHRlbXBsYXRlKQogICAgY3Vycl9zaGlmdCA9IDAKICAgIHdoaWxlIGN1cnJfc2hpZnQgPD0gbWF4X3NoaWZ0OgogICAgICAgIG5leHRfc2hpZnQgPSBjdXJyX3NoaWZ0CiAgICAgICAgZm9yIHNoaWZ0X3N1YnN0ciwgc3Vic3RyIGluIG1fc2hpZnRzOgogICAgICAgICAgICBuZXh0X3NoaWZ0ID0gcy5maW5kKHN1YnN0ciwgbmV4dF9zaGlmdCArIHNoaWZ0X3N1YnN0cikgLSBzaGlmdF9zdWJzdHIKICAgICAgICAgICAgaWYgbmV4dF9zaGlmdCA8IDA6CiAgICAgICAgICAgICAgICByZXR1cm4gLTEKICAgICAgICBpZiBuZXh0X3NoaWZ0ID09IGN1cnJfc2hpZnQ6CiAgICAgICAgICAgIHJldHVybiBjdXJyX3NoaWZ0CiAgICAgICAgZWxzZToKICAgICAgICAgICAgY3Vycl9zaGlmdCA9IG5leHRfc2hpZnQKICAgIHJldHVybiAtMQoKCmRlZiBjaGVja19wYXR0ZXJuX3JlKHMsIHRlbXBsYXRlKToKICAgIHJlcyA9IHJlLmZpbmRhbGwodGVtcGxhdGUucmVwbGFjZSgnQCcsICcuJyksIHMpCiAgICByZXR1cm4gcy5maW5kKHJlc1swXSkgaWYgcmVzIGVsc2UgLTEKCmRlZiBydW5fdGVzdHMoZnVuYywgbmFtZT0nbm8gbmFtZScpOgogICAgaXNfZmFpbCA9IEZhbHNlCiAgICB0ZXN0X2Nhc2VzID0gWwogICAgICAgICgnJywgJycsIDApLAogICAgICAgICgnMDAxMTIyMzM0NCcsICcnLCAwKSwKICAgICAgICAoJzAwMTEyMjMzNDQnLCAnQCcsIDApLAogICAgICAgICgnMDAnLCAnQEAnLCAwKSwKICAgICAgICAoJzAwJywgJ0BAQCcsIC0xKSwKICAgICAgICAoJzAxMjMnLCAnMDEyMycsIDApLAogICAgICAgICgnMDEyMycsICdAMScsIDApLAogICAgICAgICgnMDEyMycsICdAMCcsIC0xKSwKICAgICAgICAoJzAxMjMnLCAnQDMnLCAyKSwKICAgICAgICAoJzAxMjMnLCAnQDQnLCAtMSksCiAgICAgICAgKCcwMTIzJywgJ0AwQCcsIC0xKSwKICAgICAgICAoJzAxMjMnLCAnQDFAJywgMCksCiAgICAgICAgKCcwMTIzJywgJ0AyQCcsIDEpLAogICAgICAgICgnMDEyMycsICdAM0AnLCAtMSksCiAgICAgICAgKCcwMDAwMTExJywgJ0AwMDExQCcsIDEpLAogICAgICAgICgneHh4YWFhYmJiY2NjeHh4JywgJ2FhQGJiQGNjJywgMyksCiAgICAgICAgKCd4eHhhYWFiYmJjY2N4eHgnLCAnYWFAYmJAQGNjJywgMyksCiAgICAgICAgKCd4eHhhYWFiYmJjY2N4eHgnLCAnYWFAYmJAQEBjYycsIC0xKSwKICAgIF0KICAgIGZvciB0ZXN0X3N0ciwgdGVzdF90ZW1wbGF0ZSwgdGVzdF9leHBlY3RlZCBpbiB0ZXN0X2Nhc2VzOgogICAgICAgIHJldCA9IGZ1bmModGVzdF9zdHIsIHRlc3RfdGVtcGxhdGUpCiAgICAgICAgaWYgcmV0ICE9IHRlc3RfZXhwZWN0ZWQ6CiAgICAgICAgICAgIGlzX2ZhaWwgPSBUcnVlCiAgICAgICAgICAgIHByaW50KGYiW3tuYW1lfV0gVGVzdCBmYWlsIiwgdGVzdF9zdHIsIHRlc3RfdGVtcGxhdGUsIHJldCwgdGVzdF9leHBlY3RlZCkKCiAgICBhc3NlcnQgaXNfZmFpbCA9PSBGYWxzZQoKcnVuX3Rlc3RzKGNoZWNrX3BhdHRlcm5fcmUsICd2ZXJzaW9uIHJlJykKcnVuX3Rlc3RzKGNoZWNrX3BhdHRlcm5fMywgJ3ZlcnNpb24gMycpCgp0aW1lX3N0YXJ0ID0gdGltZS5tb25vdG9uaWMoKQpyZXN1bHQgPSBjaGVja19wYXR0ZXJuXzMoU1MsIFRFTVBMQVRFKQp0aW1lX2VuZCA9IHRpbWUubW9ub3RvbmljKCkKCndvcmt0aW1lID0gMTAwMCAqICh0aW1lX2VuZCAtIHRpbWVfc3RhcnQpCnByaW50KGYicmVzdWx0OiB7cmVzdWx0fSwgd29ya3RpbWU6IHt3b3JrdGltZTouM2Z9bXMiKQo=