@@ -106,68 +106,52 @@ def words(s: str):
106106
107107# -------------------------------- Actual code execution ----------------------------- #
108108
109- required_fields = ["byr" ,"iyr" ,"eyr" ,"hgt" ,"hcl" ,"ecl" ,"pid" ]
109+
110+ class Passport :
111+ required_fields = ["byr" ,"iyr" ,"eyr" ,"hgt" ,"hcl" ,"ecl" ,"pid" ]
112+
113+ validations = {
114+ "byr" :lambda year :year in range (1920 ,2002 + 1 ),
115+ "iyr" :lambda year :year in range (2010 ,2020 + 1 ),
116+ "eyr" :lambda year :year in range (2020 ,2030 + 1 ),
117+ "hgt" :lambda data : (
118+ data [- 2 :]== "cm" and int (data [:- 2 ])in range (150 ,193 + 1 )
119+ )
120+ or (data [- 2 :]== "in" and int (data [:- 2 ])in range (59 ,76 + 1 )),
121+ "hcl" :lambda data :re .match ("^#[0-9a-f]{6}$" ,data ),
122+ "ecl" :lambda data :data in ["amb" ,"blu" ,"brn" ,"gry" ,"grn" ,"hzl" ,"oth" ],
123+ "pid" :lambda data :re .match ("^[0-9]{9}$" ,data ),
124+ }
125+
126+ def __init__ (self ,data ):
127+ self .fields = defaultdict (str )
128+ for element in data .split ():
129+ if element [:3 ]in ("byr" ,"iyr" ,"eyr" ):
130+ try :
131+ self .fields [element [:3 ]]= int (element [4 :])
132+ except :
133+ self .fields [element [:3 ]]= element [4 :]
134+ else :
135+ self .fields [element [:3 ]]= element [4 :]
136+
137+ def has_required_data (self ):
138+ return all ([x in self .fields for x in self .required_fields ])
139+
140+ def is_valid (self ):
141+ return all ([self .validations [x ](self .fields [x ])for x in self .required_fields ])
142+
110143
111144passports = []
112- i = 0
113- for string in puzzle_input .split ("\n " ):
114- if len (passports )>= i :
115- passports .append ("" )
116- if string == "" :
117- i = i + 1
118- else :
119- passports [i ]= passports [i ]+ " " + string
145+ for string in puzzle_input .split ("\n \n " ):
146+ passports .append (Passport (string ))
120147
121148valid_passports = 0
122149
123150if part_to_test == 1 :
124- for passport in passports :
125- if all ([x + ":" in passport for x in required_fields ]):
126- valid_passports = valid_passports + 1
127-
151+ valid_passports = sum ([1 for x in passports if x .has_required_data ()])
128152
129153else :
130- for passport in passports :
131- if all ([x + ":" in passport for x in required_fields ]):
132- fields = passport .split (" " )
133- score = 0
134- for field in fields :
135- data = field .split (":" )
136- if data [0 ]== "byr" :
137- year = int (data [1 ])
138- if year >= 1920 and year <= 2002 :
139- score = score + 1
140- elif data [0 ]== "iyr" :
141- year = int (data [1 ])
142- if year >= 2010 and year <= 2020 :
143- score = score + 1
144- elif data [0 ]== "eyr" :
145- year = int (data [1 ])
146- if year >= 2020 and year <= 2030 :
147- score = score + 1
148- elif data [0 ]== "hgt" :
149- size = ints (data [1 ])[0 ]
150- if data [1 ][- 2 :]== "cm" :
151- if size >= 150 and size <= 193 :
152- score = score + 1
153- elif data [1 ][- 2 :]== "in" :
154- if size >= 59 and size <= 76 :
155- score = score + 1
156- elif data [0 ]== "hcl" :
157- if re .match ("#[0-9a-f]{6}" ,data [1 ])and len (data [1 ])== 7 :
158- score = score + 1
159- print (data [0 ],passport )
160- elif data [0 ]== "ecl" :
161- if data [1 ]in ["amb" ,"blu" ,"brn" ,"gry" ,"grn" ,"hzl" ,"oth" ]:
162- score = score + 1
163- print (data [0 ],passport )
164- elif data [0 ]== "pid" :
165- if re .match ("[0-9]{9}" ,data [1 ])and len (data [1 ])== 9 :
166- score = score + 1
167- print (data [0 ],passport )
168- print (passport ,score )
169- if score == 7 :
170- valid_passports = valid_passports + 1
154+ valid_passports = sum ([1 for x in passports if x .is_valid ()])
171155
172156puzzle_actual_result = valid_passports
173157