From 124d47e39061cf480f23037f2ec9e5c2e3832a40 Mon Sep 17 00:00:00 2001 From: Flavio Poletti Date: Wed, 17 May 2023 00:07:56 +0200 Subject: Fix bug detected by E. Choroba --- challenge-216/polettix/perl/ch-2.pl | 26 ++++++++++++++++---------- challenge-216/polettix/raku/ch-2.raku | 22 +++++++++++++--------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/challenge-216/polettix/perl/ch-2.pl b/challenge-216/polettix/perl/ch-2.pl index eb5445debf..90182c4843 100644 --- a/challenge-216/polettix/perl/ch-2.pl +++ b/challenge-216/polettix/perl/ch-2.pl @@ -4,7 +4,7 @@ use warnings; use experimental 'signatures'; use List::Util 'sum'; -say word_stickers(qw< ppeoknpp perlp raku python >); +say word_stickers(@ARGV); sub word_stickers ($word, @stickers) { my %needed = letters_histogram($word); @@ -25,7 +25,10 @@ sub word_stickers ($word, @stickers) { my $alternatives = $provided{$letter} or return 0; # no viable source if (scalar(keys($alternatives->%*)) == 1) { # one viable source only - my ($word, $amount) = $alternatives->%*; + my ($word, $units) = $alternatives->%*; + my $amount = int($needed{$letter} / $units) + + ($needed{$letter} % $units ? 1 : 0); + my $amount = $units; $minimum{$word} = $amount if (! exists($minimum{$word})) || ($minimum{$word} < $amount); } @@ -53,16 +56,19 @@ sub complete_minimum ($minimum, $needed, $provided) { my $frame = shift(@queue); my $needed = $frame->{needed}; my $minimum = $frame->{minimum}; - for my $letter (keys($needed->%*)) { - for my $source (keys($provided->{$letter}->%*)) { - my %nmin = $minimum->%*; - $nmin{$source}++; - my %nneed = $needed->%*; - $nneed{$letter} -= $provided->{$letter}{$source}; + + my %words = map { $_ => 1 } + map { keys($provided->{$_}->%*) } keys($needed->%*); + for my $source (keys %words) { + my %nmin = $minimum->%*; + $nmin{$source}++; + my %nneed = $needed->%*; + for my $letter (keys(%nneed)) { + $nneed{$letter} -= $provided->{$letter}{$source} // 0; delete($nneed{$letter}) if $nneed{$letter} <= 0; - return %nmin if scalar(keys(%nneed)) == 0; - push @queue, {needed => \%nneed, minimum => \%nmin}; } + return %nmin if scalar(keys(%nneed)) == 0; + push @queue, {needed => \%nneed, minimum => \%nmin}; } } } diff --git a/challenge-216/polettix/raku/ch-2.raku b/challenge-216/polettix/raku/ch-2.raku index 71005bf561..ca326a9f9d 100644 --- a/challenge-216/polettix/raku/ch-2.raku +++ b/challenge-216/polettix/raku/ch-2.raku @@ -21,7 +21,9 @@ sub word-stickers ($word, @stickers) { my $alternatives = %provided{$letter} or return 0; # no viable source if ($alternatives.elems == 1) { # one viable source only - my ($word, $amount) = $alternatives.kv; + my ($word, $units) = $alternatives.kv; + my $amount = (%needed{$letter} div $units) + + ((%needed{$letter} % $units) ?? 1 !! 0); %minimum{$word} = $amount if %minimum{$word}:!exists || (%minimum{$word} < $amount); } @@ -56,16 +58,18 @@ sub complete-minimum (%minimum is copy, %needed is copy, %provided) { my $frame = @queue.shift; my $needed = $frame; my $minimum = $frame; - for $needed.keys -> $letter { - for %provided{$letter}.keys -> $source { - my %nmin = %$minimum; - %nmin{$source}++; - my %nneed = %$needed; - %nneed{$letter} -= %provided{$letter}{$source}; + + my %words = $needed.keys.map({ %provided{$_}.keys }).flat.map({ $_ => 1 }); + for %words.keys -> $source { + my %nmin = %$minimum; + %nmin{$source}++; + my %nneed = %$needed; + for %nneed.keys -> $letter { + %nneed{$letter} -= %provided{$letter}{$source} // 0; %nneed{$letter}:delete if %nneed{$letter} <= 0; - return %nmin if %nneed.keys.elems == 0; - @queue.push: {needed => %nneed, minimum => %nmin}; } + return %nmin if %nneed.keys.elems == 0; + @queue.push: {needed => %nneed, minimum => %nmin}; } } return (); -- cgit