Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use strict;
- use warnings;
- use feature qw(say);
- use List::Util qw(product);
- # Paragraph mode, array of sections
- $/ = '';
- my @section = map {[split /\n/]} <>;
- # Read in rules:
- my %Rules;
- foreach ($section[0]->@*) {
- my ($flow, $str) = m#(\w+)\{(.*)\}#g;
- my @rules;
- foreach my $rule (split( /,/, $str )) {
- if ($rule =~ m#([xmas])([<>])(\d+):(\w+)#) {
- push( @rules, [$1, $2, $3, $4] );
- } else {
- push( @rules, [$rule] );
- }
- }
- $Rules{$flow} = \@rules;
- }
- # Perform workflow, returning number of range combinations that accept
- sub recurse_flow {
- my ($flow, $ranges) = @_;
- my $ret = 0;
- return (0) if ($flow eq 'R');
- return (product map {$_->[1] - $_->[0] + 1} values %$ranges) if ($flow eq 'A');
- RULE:
- foreach my $rule ($Rules{$flow}->@*) {
- # No rule: A, R, or jump to workflow (only at end of rules?)
- if (@$rule == 1) {
- $ret += &recurse_flow( $rule->[0], $ranges );
- next RULE;
- }
- # ASSERT: We have a rule, @$rule == 4
- my ($cat, $op, $val, $next) = @$rule;
- my $succ;
- my $fail;
- # Three basic cases: val is either before, after, or inside the range.
- # In the first two, one of succ/fail = range, the other is empty.
- # In the last, the range is partitioned.
- if ($val < $ranges->{$cat}[0]) {
- $succ = $ranges->{$cat} if ($op eq '>');
- $fail = $ranges->{$cat} if ($op eq '<');
- } elsif ($val > $ranges->{$cat}[1]) {
- $succ = $ranges->{$cat} if ($op eq '<');
- $fail = $ranges->{$cat} if ($op eq '>');
- } else {
- my $less = [$ranges->{$cat}[0], $val - ($op eq '<')];
- my $great = [$val + ($op eq '>'), $ranges->{$cat}[1]];
- $succ = ($op eq '<') ? $less : $great;
- $fail = ($op eq '<') ? $great : $less;
- }
- # If we have a success range, recurse (otherwise, don't bother)
- if (defined $succ) {
- my %new_ranges = %$ranges;
- $new_ranges{$cat} = $succ;
- $ret += &recurse_flow( $next, \%new_ranges );
- }
- # Preparing for next rule: if the fail range is invalid that means
- # that category will contribute a 0 to the product, so we're done.
- # Otherwise, update to mark the new range from the failed rule.
- last RULE if (!defined $fail);
- $ranges->{$cat} = $fail;
- }
- return ($ret);
- }
- say "Part 2: ", &recurse_flow( 'in', {map { $_ => [1, 4000] } qw(x m a s)} );
Advertisement
Comments
-
- This Perl script appears to be a solution for a specific problem, likely related to parsing and processing rules for a workflow. It defines rules for different categories ('x', 'm', 'a', 's') and performs recursive flow to determine the number of range combinations that accept. The script seems well-structured and efficient.
- website:https://simplified.com/ai-ads-generator/single-image-ads
Add Comment
Please, Sign In to add comment
Advertisement