You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.8 KiB
Dart

import 'package:aoc2020/aocbase.dart';
import 'package:aoc2020/model/readdata.dart';
typedef Validator = bool Function(String);
class AOC20201204 extends AOCBase {
static const List<String> eyeColors = ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth'];
// cid field is assume to be last
List<String> fields = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid', 'cid'];
Map<String, Validator> 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<String, Validator> 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<String, String> passport, Map<String, Validator> 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<String> input, Map<String, Validator> validatorFn}) {
var retval = 0;
var passport = <String, String>{};
for (var line in input) {
if (line.isEmpty) {
retval += validate(passport, validatorFn) ? 1 : 0;
passport = <String, String>{};
} 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<void> a({bool test}) async {
var mylist = await ReadData.readFile<String>(classString, test: test);
answerA = processList(input: mylist, validatorFn: valid1);
}
@override
Future<void> b({bool test}) async {
var mylist = await ReadData.readFile<String>(classString, test: test);
answerB = processList(input: mylist, validatorFn: valid2);
}
}