Advertisement
musifter

AoC 2024, day 23, part 2 (Perl)

Dec 23rd, 2024 (edited)
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 1.46 KB | Source Code | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use feature         qw(say);
  7. use List::Util      qw(reduce);
  8.  
  9. # Build undirected graph from input:
  10. my %graph;
  11. foreach my $conx (map {[m/(\w{2})-(\w{2})/]} <>) {
  12.     push( $graph{$conx->[0]}->@*, $conx->[1] );
  13.     push( $graph{$conx->[1]}->@*, $conx->[0] );
  14. }
  15.  
  16. # Quick and dirty intersection of two lists (ASSUME: sets, so no repeats):
  17. sub intersect ($$) {
  18.     my ($a, $b) = @_;
  19.     return (grep {my $av = $_; grep {$_ eq $av} @$b} @$a);
  20. }
  21.  
  22. # Find cliques (complete subgraphs) using Bron-Kerbosch
  23. sub recurse_bk {
  24.     my ($r, $p, $x) = @_;                           # result, possibles, excludes
  25.     my @ret;
  26.  
  27.     return ([@$r]) if (!@$p and !@$x);              # P and X both empty => clique
  28.  
  29.     # Try each possible vertex:
  30.     foreach my $v (@$p) {
  31.         my @ruv  = (@$r, $v);                       # Union of R with v
  32.         my @pnNv = intersect( $p, $graph{$v} );     # Intersect of P with Neighbours of v
  33.         my @xnNv = intersect( $x, $graph{$v} );     # Intersect of X with Neighbours of v
  34.  
  35.         push( @ret, &recurse_bk(\@ruv, \@pnNv, \@xnNv) );   # recurse and collect
  36.  
  37.         @$p = grep {$_ ne $v} @$p;                  # symmetric difference: P \ v
  38.         @$x = (@$x, $v);                            # Union v into eXcludes
  39.     }
  40.  
  41.     return (@ret);
  42. }
  43.  
  44. my $max_clique = reduce {(@$b > @$a) ? $b : $a} &recurse_bk([], [keys %graph], []);
  45.  
  46. say "Part 2: ", join( ',', sort @$max_clique );
  47.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement