Mercurial > repos > other > adventofcode2023
changeset 28:5ba34a851816
Implement Day 19 workflows, skip part 2
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Wed, 03 Jan 2024 11:34:54 +0000 |
parents | 6b58ddfaed38 |
children | 739415015d27 |
files | day19.rb day19.txt |
diffstat | 2 files changed, 105 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/day19.rb Wed Jan 03 11:34:54 2024 +0000 @@ -0,0 +1,60 @@ +#! /usr/bin/env ruby + +if ARGV.length != 1 + abort("Incorrect arguments - needs input file") +elsif not File.exist? (ARGV[0]) + abort("File #{ARGV[0]} did not exist") +end + +file = ARGV[0] + +workflows = Hash.new +Workflow = Struct.new(:name, :rules) +Rule = Struct.new(:filter, :next) +Filter = Struct.new(:field, :comparison, :value) +objects = Array.new +Object = Struct.new(:x, :m, :a, :s) + +File.open(file, "r").each_line(chomp: true) do |line| + if line == "" + next + end + bracket_pos = line.index("{") + if bracket_pos == 0 + # Parse an object + match = line.match("\{x=([0-9]+),m=([0-9]+),a=([0-9]+),s=([0-9]+)\}") + objects << Object.new(x=match[1].to_i, m=match[2].to_i, a=match[3].to_i, s=match[4].to_i) + else + # Parse a workflow + workflow_name = line[0,bracket_pos] + rules = line[(bracket_pos+1)..-2].split(",").map do |rule| + rule_parts = rule.split(":") + if rule_parts.length > 1 + rule, next_workflow = rule_parts + filter = Filter.new(rule[0].to_sym, rule[1].to_sym, rule[2..-1].to_i) + Rule.new(filter, next_workflow) + else + Rule.new(Filter.new(:a, ">".to_sym, -1), rule_parts[0]) + end + end + workflows[workflow_name] = Workflow.new(name=workflow_name, rules=rules) + end +end + +filtered_objects = objects.map do |obj| + workflow_name = "in" + while workflow_name != "R" and workflow_name != "A" + workflow = workflows[workflow_name] + workflow.rules.each do |rule| + puts rule + filter = rule.filter + if obj.public_send(filter.field).public_send(filter.comparison, filter.value) + workflow_name = rule.next + break + end + end + end + obj if workflow_name == "A" +end.reject(&:nil?) +puts "#{filtered_objects.to_a}" +puts "#{filtered_objects.reduce(0) {|accum, obj| accum + obj.x + obj.m + obj.a + obj.s}}" \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/day19.txt Wed Jan 03 11:34:54 2024 +0000 @@ -0,0 +1,45 @@ +--- Day 19: Aplenty --- + +Objects have three values - x, m, a and s. + +There are a number of workflows, which have a name and a set of rules. +Each rule specifies a condition and the name of the next step. +The first step is "in". The last steps are "A" (accepted) and "R" (rejected). +Once it matches a rule in a workflow, no further rules in the workflow are evaluated. + +The input is a set of workflows, a blank line, and a set of objects. + +px{a<2006:qkq,m>2090:A,rfg} +pv{a>1716:R,A} +lnx{m>1548:A,A} +rfg{s<537:gd,x>2440:R,A} +qs{s>3448:A,lnx} +qkq{x<1416:A,crn} +crn{x>2662:A,R} +in{s<1351:px,qqz} +qqz{s>2770:qs,m<1801:hdj,R} +gd{a>3333:R,R} +hdj{m>838:A,pv} + +{x=787,m=2655,a=1222,s=2876} +{x=1679,m=44,a=2067,s=496} +{x=2036,m=264,a=79,s=2244} +{x=2461,m=1339,a=466,s=291} +{x=2127,m=1623,a=2188,s=1013} + + +These five parts would go: + + {x=787,m=2655,a=1222,s=2876}: in -> qqz -> qs -> lnx -> A + {x=1679,m=44,a=2067,s=496}: in -> px -> rfg -> gd -> R + {x=2036,m=264,a=79,s=2244}: in -> qqz -> hdj -> pv -> A + {x=2461,m=1339,a=466,s=291}: in -> px -> qkq -> crn -> R + {x=2127,m=1623,a=2188,s=1013}: in -> px -> rfg -> A + +The sum of the sum of the x, m, a and s scores for the accepted parts is 19114. + +--- Part Two --- + +Each value can be in the range 1 to 4000. In the example input, +there are 167409079868000 combinations of values that would be accepted. +No information is given about what this means or how it is calculated. \ No newline at end of file