Extract some code from day 4.
This commit is contained in:
parent
15128fbddf
commit
1a2f18b316
38
day4.cr
38
day4.cr
|
@ -1,20 +1,6 @@
|
||||||
|
require "./passports.cr"
|
||||||
INPUT = File.read("day4.txt")
|
INPUT = File.read("day4.txt")
|
||||||
|
|
||||||
def parse_passport(string)
|
|
||||||
new_hash = {} of String => String
|
|
||||||
string.split(" ").each do |field|
|
|
||||||
k,v = field.split(":")
|
|
||||||
new_hash[k] = v
|
|
||||||
end
|
|
||||||
new_hash
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse_passports(lines)
|
|
||||||
lines.split(/\n\n/).map do |s|
|
|
||||||
parse_passport(s.chomp.gsub(/\n/, " "))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def part1
|
def part1
|
||||||
input = INPUT.clone
|
input = INPUT.clone
|
||||||
passports = parse_passports(input)
|
passports = parse_passports(input)
|
||||||
|
@ -26,31 +12,11 @@ def part1
|
||||||
puts total
|
puts total
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_range(range)
|
|
||||||
->(s : String) { s.to_i32?.try { |i| range.includes? i } }
|
|
||||||
end
|
|
||||||
|
|
||||||
def validate_regex(regex)
|
|
||||||
->(s : String) { s.matches?(regex) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def part2
|
def part2
|
||||||
input = INPUT.clone
|
input = INPUT.clone
|
||||||
passports = parse_passports(input)
|
passports = parse_passports(input)
|
||||||
validators = {
|
|
||||||
"byr" => validate_range(1920..2002),
|
|
||||||
"iyr" => validate_range(2010..2020),
|
|
||||||
"eyr" => validate_range(2020..2030),
|
|
||||||
"hgt" => ->(s : String) {
|
|
||||||
return false unless s.match(/^(\d+)(cm|in)$/)
|
|
||||||
validate_range($~[2] == "cm" ? (150..193) : (59..76)).call($~[1])
|
|
||||||
},
|
|
||||||
"hcl" => validate_regex(/^#[0-9a-f]{6}$/),
|
|
||||||
"ecl" => ->(s : String) { "amb blu brn gry grn hzl oth".split(" ").includes? s },
|
|
||||||
"pid" => ->(s : String) { s =~ /^[0-9]{9}$/ },
|
|
||||||
}
|
|
||||||
total = passports.count do |passport|
|
total = passports.count do |passport|
|
||||||
validators.all? do |k, v|
|
DEFAULT_VALIDATORS.all? do |k, v|
|
||||||
passport[k]?.try { |s| v.call(s) }
|
passport[k]?.try { |s| v.call(s) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
39
passports.cr
Normal file
39
passports.cr
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
def parse_passport(string)
|
||||||
|
new_hash = {} of String => String
|
||||||
|
string.split(" ").each do |field|
|
||||||
|
k,v = field.split(":")
|
||||||
|
new_hash[k] = v
|
||||||
|
end
|
||||||
|
new_hash
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_passports(lines)
|
||||||
|
lines.split(/\n\n/).map do |s|
|
||||||
|
parse_passport(s.chomp.gsub(/\n/, " "))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_range(range)
|
||||||
|
->(s : String) { s.to_i32?.try { |i| range.includes? i } }
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_regex(regex)
|
||||||
|
->(s : String) { s.matches?(regex) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_unit_range(unit_ranges)
|
||||||
|
->(s : String) {
|
||||||
|
return false unless s.match(/^(\d+)([a-zA-Z]+)$/)
|
||||||
|
unit_ranges[$~[2]]?.try { |rng| validate_range(rng).call($~[1]) }
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
DEFAULT_VALIDATORS = {
|
||||||
|
"byr" => validate_range(1920..2002),
|
||||||
|
"iyr" => validate_range(2010..2020),
|
||||||
|
"eyr" => validate_range(2020..2030),
|
||||||
|
"hgt" => validate_unit_range({"cm" => (150..193), "in" => (59..76)}),
|
||||||
|
"hcl" => validate_regex(/^#[0-9a-f]{6}$/),
|
||||||
|
"ecl" => ->(s : String) { "amb blu brn gry grn hzl oth".split(" ").includes? s },
|
||||||
|
"pid" => ->(s : String) { s =~ /^[0-9]{9}$/ },
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user