diff --git a/2016/11/1.pl b/2016/11/1.pl index 0b3f633..0b417ac 100644 --- a/2016/11/1.pl +++ b/2016/11/1.pl @@ -1,86 +1,57 @@ use 5.20.0; use JSON 'to_json'; -use List::AllUtils qw/ all min part uniq pairgrep any /; +use List::AllUtils qw/ all any uniq min part uniq pairgrep any max /; my %state = ( E => 1, - TG => 1, - TM => 1, - PG => 1, - SG => 1, - PM => 2, - SM => 2, - WG => 3, - WM => 3, - RG => 3, - RM => 3, + HM => 1, + LM => 1, + HG => 2, + LG => 3, ); sub freeze { to_json( { @_ }, { canonical => 1 } ) } -my %history = ( - 0 => freeze(%state), -); - use DDP; -p %history; -my @next = ( [ 0, %state ] ); +my $max = 1E99; -while( my $n = shift @next ) { - search( @$n ); -} +search( 0, \%state, freeze(%state) ); + +say $max; sub search { - my( $steps, %state ) = @_; + my( $steps, $state, @history ) = @_; - say "size: ", scalar @next; - say $steps; -# p $steps; -# p %state; + say "steps: ", $steps; - if( all { $_ == 4 } values %state ) { - say "woohoo, found it: $steps"; - die; - } - - my $f = freeze(%state); - - if( $history{$f}++ ) { - return say "seen it"; - } - - if( britzle(%state) ) { -# say "we fried something"; + if( all { $_ == 4 } values %$state ) { + $max = min $max, $steps; + say "woohoo, found it: $steps, $max"; return; } + return if $steps + 1 >= $max; - my $level = $state{E}; - my @things = grep { $_ ne 'E' and $state{$_} == $level } keys %state; + my $level = $state->{E}; + my @things = grep { $_ ne 'E' and $state->{$_} == $level } keys %$state; - for my $thing ( @things ) { - for my $next_level ( grep { $_ >= 1 and $_ <= 4 } $level + 1, $level - 1 ) { - push @next, [ - $steps + 1, - %state, - E => $next_level, - $thing => $next_level, - ]; - } - } + use Algorithm::Combinatorics qw(combinations); - if ( @things >=2 ) { - use Algorithm::Combinatorics qw(combinations); - my $combs = combinations( \@things, 2 ); + $steps++; + + for my $group (2,1) { + next if @things < $group; + + my $combs = combinations( \@things, $group ); while( my $c = $combs->next ) { - for my $next_level ( grep { $_ >= 1 and $_ <= 4 } $level + 1, $level - 1 ) { - push @next, [ - $steps + 1, - %state, - map { $_ => $next_level } 'E', @$c - ]; + I: for my $next_level ( grep { $_ >= 1 and $_ <= 4 } $level + 1, $level - 1 ) { + my %new_state = ( %$state, map { $_ => $next_level } 'E', @$c ); + my $f = freeze(%new_state); + if ( any { $_ eq $f } @history ) { next I }; + if ( britzle(%new_state) ) { next I; }; + search( $steps, \%new_state, $f, @history ) } } } diff --git a/2016/11/2.pl b/2016/11/2.pl index 24a95e8..18e2991 100644 --- a/2016/11/2.pl +++ b/2016/11/2.pl @@ -23,68 +23,45 @@ my %state = ( sub freeze { to_json( { @_ }, { canonical => 1 } ) } -my %history = ( - 0 => freeze(%state), -); - use DDP; -p %history; -my @next = ( [ 0, %state ] ); +my $max = 55; -while( my $n = shift @next ) { - search( @$n ); -} +search( 0, \%state, freeze(%state) ); + +say $max; sub search { - my( $steps, %state ) = @_; + my( $steps, $state, @history ) = @_; - say "size: ", scalar @next; - say $steps; -# p $steps; -# p %state; +# say "steps: ", $steps; - if( all { $_ == 4 } values %state ) { - say "woohoo, found it: $steps"; - die; - } - - my $f = freeze(%state); - - if( $history{$f}++ ) { - return say "seen it"; - } - - if( britzle(%state) ) { -# say "we fried something"; + if( all { $_ == 4 } values %$state ) { + $max = min $max, $steps; + say "woohoo, found it: $steps, $max"; return; } + return if $steps + 1 >= $max; - my $level = $state{E}; - my @things = grep { $_ ne 'E' and $state{$_} == $level } keys %state; + my $level = $state->{E}; + my @things = grep { $_ ne 'E' and $state->{$_} == $level } keys %$state; - for my $thing ( @things ) { - for my $next_level ( grep { $_ >= 1 and $_ <= 4 } $level + 1, $level - 1 ) { - push @next, [ - $steps + 1, - %state, - E => $next_level, - $thing => $next_level, - ]; - } - } + use Algorithm::Combinatorics qw(combinations); - if ( @things >=2 ) { - use Algorithm::Combinatorics qw(combinations); - my $combs = combinations( \@things, 2 ); + $steps++; + + for my $group (2,1) { + next if @things < $group; + + my $combs = combinations( \@things, $group ); while( my $c = $combs->next ) { - for my $next_level ( grep { $_ >= 1 and $_ <= 4 } $level + 1, $level - 1 ) { - push @next, [ - $steps + 1, - %state, - map { $_ => $next_level } 'E', @$c - ]; + I: for my $next_level ( grep { $_ >= 1 and $_ <= 4 } $level + 1, $level - 1 ) { + my %new_state = ( %$state, map { $_ => $next_level } 'E', @$c ); + my $f = freeze(%new_state); + if ( any { $_ eq $f } @history ) { next I }; + if ( britzle(%new_state) ) { next I; }; + search( $steps, \%new_state, $f, @history ) } } }