We're looking at a list of "IPv7" addresses and need to find those that contain specific sequences of repeated characters.
I used two different methods. For part 1 - the obvious way, regular expressions with backreferences. I hate them, though I seem to be getting better at them.
But I couldn't write the right regexp for part 2. Instead, I found it easier to do some C-style coding in Python: process string as a character array and use a very simple state machine (with just 2 states: inside and outside the square brackets). I'm looking for all ABA blocks, store them in two sets (actually I just store AB), separately for inside and outside square brackets. Then it's just checking if the two sets have any elements in common. The important thing is to reverse characters for one of the sets.
#!/usr/bin/python3
import re
INPUTFILE="07-input.txt"
rx1=re.compile(r"(\w)(\w)\2\1") # check for reversed pair, eg. abba, but will also catch aaaa
rx2=re.compile(r"\[\w*(\w)(\w)\2\1\w*]") # check for reversed pair in square brackets
rx3=re.compile(r"(\w)\1{3}") # check for "reversed pair" of same characters
def check_tls(line):
if rx2.search(line):
return False
if rx3.search(line):
return False
if rx1.search(line):
return True
return False
def check_ssl(line):
in_hyper_block=False
hyper_matches=set()
no_hyper_matches=set()
for i in range(len(line)-2): # we're looking 2 characters ahead from current index
if line[i]=="[":
in_hyper_block=True
elif line[i]=="]":
in_hyper_block=False
elif line[i]==line[i+2] and line[i]!=line[i+1]: # found aba block
if in_hyper_block:
hyper_matches.add(line[i]+line[i+1])
else:
no_hyper_matches.add(line[i+1]+line[i]) # reverse block
if hyper_matches & no_hyper_matches:
return True
return False
tlscount=0
sslcount=0
with open(INPUTFILE) as f:
for line in f:
line=line.strip()
if check_tls(line):
tlscount+=1
if check_ssl(line):
sslcount+=1
print("Part 1, TLS addresses: ", tlscount)
print("Part 2, SSL addresses: ", sslcount)