- 论坛徽章:
- 7
|
perl- my ( $K, $N ) = ( 5, 2060 ); # 0.011s
- my ( $K, $N ) = ( 5, 100 ); # 0.01s
- my ( $K, $N ) = ( 15223, 30000000 ); # 0.23s
- my ( $K, $N ) = ( 555555, 10000000 ); # 1.1s
- my ( $K, $N ) = ( 555555, 123456789 ); # 9.6s
- my ( $K, $N ) = ( 12345, 100000000000 ); # 9.97s
- my ( $K, $N ) = ( 543210, 1005006700 ); # 2.65s
- my ( $K, $N ) = ( 2000000, 100000000000000 ); # 18.6s
- my ( $K, $N ) = ( 1230000, 12300000000000 ); # 9.0s
- my ( $K, $N ) = ( 999999, 10000000 ); # 0.38s
- my ( $K, $N ) = ( 9999999999999, 10000000000000 ); # 0.018s
- my ( $K, $N ) = ( 123456781, 123456789 ); # 8.9s
复制代码- #!/usr/bin/perl
- my ( $K, $N ) = ( 15223, 30000000 ); # 0.24s
- #my ( $K, $N ) = ( 125711, 3436783320 ); # 7.5s
- sub tellen {
- my ( $getal, $doorgaan, $serie, $staart ) = @_;
- if ( @_ == 1 ) {
- return (1) x $getal if $getal < 10;
- $getal = [ map int, split //, $getal ];
- $doorgaan = @$getal - 2;
- $serie = [ (1) x 9 ];
- }
- my ( $kleine, $grote, @tweeling, @schaduw ) = ( 0, 0 );
- my @tien =
- ( $serie, map [ (0) x ( $_ - 1 ), 1, @$serie ], 1 .. 9 );
- if ( $getal->[$doorgaan] ) {
- $kleine += $getal->[$_] for 0 .. $doorgaan - 1;
- $grote = $getal->[$doorgaan] - 1 + $kleine;
- $kleine += 1 if not $doorgaan;
- @tweeling =
- map [ (0) x ( $_ - 1 ), 1, @$serie ], $kleine .. $grote;
- my $einde = @tweeling ? $#{ $tweeling[-1] } : -1;
- @schaduw = map {
- my ( $i, $toevoeging ) = $_;
- $toevoeging += $tweeling[$_][$i] || 0 for 0 .. $#tweeling;
- $toevoeging
- } 0 .. $einde;
- $staart->[$_] += $schaduw[$_] for 0 .. $#schaduw;
- }
- if ( not $doorgaan ) {
- my $i = -1;
- $i += $getal->[$_] for 0 .. $#{$getal} - 1;
- $serie->[$_] += $staart->[$_] for 0 .. $#{$staart};
- $serie->[$_] += 1 for $i .. $i + $getal->[-1];
- return @$serie;
- }
- $serie = [
- map {
- my ( $i, $toevoeging ) = $_;
- $toevoeging += $tien[$_][$i] || 0 for 0 .. 9;
- $toevoeging
- } 0 .. $#{ $tien[-1] }
- ];
- tellen( $getal, --$doorgaan, $serie, $staart );
- }
- sub rekenen {
- my ( $pionier, $tal, $limiet ) = @_;
- if ( $pionier == 1 ) {
- return 0 if $tal > 9;
- return $limiet ? $tal <= $limiet->[0] ? 1 : 0 : 1;
- }
- my $voorsp = $pionier - 1;
- my $kleine = $tal - $voorsp * 9;
- my $grote = $tal > 9 ? 9 : $tal;
- my @mij;
- $kleine = 0 if $kleine < 0;
- if ($limiet) {
- my $maximale = shift @$limiet;
- $grote = $maximale if $grote > $maximale;
- @mij = ( (undef) x ( $grote - $kleine ), $limiet );
- }
- my $aantal = 0;
- $aantal += rekenen( $voorsp, $tal - $_, shift @mij )
- for $kleine .. $grote;
- return $aantal;
- }
- sub genereren {
- my ( $pionier, $tal, $limiet ) = @_;
- if ( $pionier == 1 ) {
- return if $tal > 9;
- return $limiet ? $tal <= $limiet->[0] ? $tal : () : $tal;
- }
- my $voorsp = $pionier - 1;
- my $kleine = $tal - $voorsp * 9;
- my $grote = $tal > 9 ? 9 : $tal;
- my @mij;
- $kleine = 0 if $kleine < 0;
- if ($limiet) {
- my $maximale = shift @$limiet;
- $grote = $maximale if $grote > $maximale;
- @mij = ( (undef) x ( $grote - $kleine ), $limiet );
- }
- map {
- my $deze = $_;
- map 10**$voorsp * $deze + $_,
- genereren( $voorsp, $tal - $deze, shift @mij )
- } $kleine .. $grote;
- }
- printf "%20s = %s\n", 'N', $N;
- printf "%20s = %s\n", 'K', $K;
- my ( $plaats, $aantal ) = ( 0, 0 );
- my @K = split //, $K;
- my @N = map int, split //, $N;
- my $pionier = @N;
- my @element = tellen $N;
- my $groei = 0;
- $aantal += $_ for @K;
- $plaats += $_ for @element[ 0 .. $aantal - 2 ];
- for my $i ( 1 .. $K[0] ) {
- my $I = $i == $N[0] ? [ @N[ 1 .. $#N ] ] : undef;
- my $tal = $aantal - $i;
- if ( $i < $K[0] ) {
- my @serie = map { rekenen( $_, $tal ) } 1 .. @N - 2;
- push @serie, rekenen( $#N, $tal, $I ) if $i <= $N[0];
- $plaats += $_ for @serie;
- $plaats += 1 if $aantal == $i;
- }
- else {
- my @serie = map {
- my $p = $_;
- map { $i * 10**$p + $_ } genereren( $_, $tal )
- } 1 .. @N - 2;
- push @serie, map { $i * 10**$#N + $_ } genereren( $#N, $tal, $I )
- if $i <= $N[0];
- unshift @serie, $aantal if $aantal == $i;
- $plaats += @serie;
- for my $k ( sort @serie ) {
- $K == $k ? ( $plaats -= @serie ) && last : $plaats++;
- }
- }
- }
- $aantal = 1;
- ( $groei += $_ ) > $K ? last : $aantal++ for @element;
- $groei -= $element[ $aantal - 1 ];
- deze: for my $i ( 1 .. 9 ) {
- my @serie = map { rekenen( $_, $aantal - $i ) } 1 .. @N - 2;
- if ( $i <= $N[0] ) {
- my $I = $i == $N[0] ? [ @N[ 1 .. $#N ] ] : undef;
- push @serie, rekenen( $#N, $aantal - $i, $I );
- }
- my $serie = 0;
- $serie += $_ for @serie;
- $serie += 1 if $aantal == $i;
- next if ( $groei += $serie ) < $K;
- $groei -= $serie;
- @serie = map {
- my $p = $_;
- map { $i * 10**$p + $_ } genereren( $_, $aantal - $i )
- } 1 .. @N - 2;
- if ( $i <= $N[0] ) {
- my $I = $i == $N[0] ? [ @N[ 1 .. $#N ] ] : undef;
- push @serie,
- map { $i * 10**$#N + $_ } genereren( $#N, $aantal - $i, $I );
- }
- unshift @serie, $aantal if $aantal == $i;
- for my $k ( sort @serie ) {
- ( $groei = $k ) && last deze if $K == $groei++;
- }
- }
- printf "%20s = %s\n", "index [ $plaats ]", $K;
- printf "%20s = %s\n", "index [ $K ]", $groei;
复制代码 |
|