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
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);
|
|
}
|
|
}
|