import 'package:aoc2020/aocbase.dart'; import 'package:aoc2020/model/readdata.dart'; typedef Validator = bool Function(String); class AOC20201204 extends AOCBase { static const List eyeColors = ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth']; // cid field is assume to be last List fields = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid', 'cid']; Map valid1 = { 'byr': (val) => true, 'iyr': (val) => true, 'eyr': (val) => true, 'hgt': (val) => true, 'hcl': (val) => true, 'ecl': (val) => true, 'pid': (val) => true, 'cid': (val) => true, }; Map valid2 = { 'byr': (val) => (val.length == 4 && int.parse(val) >= 1920 && int.parse(val) <= 2002), 'iyr': (val) => (val.length == 4 && int.parse(val) >= 2010 && int.parse(val) <= 2020), 'eyr': (val) => (val.length == 4 && int.parse(val) >= 2020 && int.parse(val) <= 2030), 'hgt': (val) { var units = val.substring(val.length - 2); var height = int.parse(val.substring(0, val.length - 2)); if (units == 'cm') { return height >= 150 && height <= 193; } else { return height >= 59 && height <= 76; } }, 'hcl': (val) { var regExp = RegExp(r'^#([a-fA-F0-9]{6})', caseSensitive: false, multiLine: false); return regExp.hasMatch(val); }, 'ecl': (val) => eyeColors.contains(val), 'pid': (val) { var regExp = RegExp(r'^([0-9]{9})$', caseSensitive: false, multiLine: false); return regExp.hasMatch(val); }, 'cid': (val) => true, }; bool validate(Map passport, Map validatorFn) { for (var field in fields) { if (field != fields.last && passport[field] == null) { return false; } else { if (!validatorFn[field](passport[field])) { return false; } } } return true; } int processList({List input, Map validatorFn}) { var retval = 0; var passport = {}; for (var line in input) { if (line.isEmpty) { retval += validate(passport, validatorFn) ? 1 : 0; passport = {}; } else { var fieldItems = line.split(' '); for (var item in fieldItems) { var itemSplit = item.split(':'); passport[itemSplit[0]] = itemSplit[1]; } } } retval += validate(passport, validatorFn) ? 1 : 0; return retval; } @override Future a({bool test}) async { var mylist = await ReadData.readFile(classString, test: test); answerA = processList(input: mylist, validatorFn: valid1); } @override Future b({bool test}) async { var mylist = await ReadData.readFile(classString, test: test); answerB = processList(input: mylist, validatorFn: valid2); } }