in reply to Find duplicate digits

Hello Monks,

This is my first post, and I was delighted to find this thread, as it almost exactly addresses what I want to do, with the exception that I would like to narrow the numbers down even further in comparison to the OP's spec.

Thus, I want to take 0000 to 9999 and select only those that have one pair of duplicate digits.

For example:

I am a noob, and this has turned out to be a bit beyond my skill level at this time . . . I was going the grep + regex on Bash route, however, upon seeing the Perl solutions in this thread, I believe I will only use bash to admin my system on the command line from now on :)

Replies are listed 'Best First'.
Re^2: Find duplicate digits
by BrowserUk (Patriarch) on Apr 07, 2010 at 11:14 UTC
    perl -le"%h=(), undef @h{split'',$_}, keys %h == 3 and print for '0000 +'..'9999'"
      BrowserUk,

      Thank you for this.

      This is the message I got:

      syntax error at ns.pl line 1, near "-le" Execution of ns.pl aborted due to compilation errors.
      ?

        The solution I posted is a one-line perl command, to be run from a command shell prompt, not to be embedded within a perl source file.

        If you're running under *nix, then you'll have to exchange the quotes like so:

        perl -le'%h=(), undef @h{split"",$_}, keys %h == 3 and print for "0000 +".."9999"'

        The following will run as a script:

        #!/usr/bin/perl -lw use strict; for ( '0000'..'9999' ) { my %h; undef @h{split'',$_}; keys %h == 3 and print; }

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        perldoc perlrun
        $ perl -MO=Deparse -le"%h=(), undef @h{split'',$_}, keys %h == 3 and + print for '0000'..'9999'" BEGIN { $/ = "\n"; $\ = "\n"; } ; (%h) = (), undef @h{split(//, $_, 0)}, keys %h == 3 and print $_ forea +ch ('0000' .. '9999'); -e syntax OK
        $ indicates a command prompt (a shell, like bash/csh/cmd...)
Re^2: Find duplicate digits (non-filter)
by tye (Sage) on Apr 07, 2010 at 14:41 UTC

    This version directly generates the list of desired patterns rather than filtering through all 4-digit patterns, just to demonstrate another approach. It also works for any length of digit string.

    #/usr/bin/perl -w use strict; use Algorithm::Loops qw< NestedLoops NextPermute >; my( $uniq )= ( @ARGV, 3 ); # 3 unique digits plus one duplicate digit my $digs= NestedLoops( [ [0..9], ( sub { [1+$_..9] } ) x ($uniq-1) ], ); my @digs; while( @digs= $digs->() ) { do { for my $dup ( 0 .. $#digs ) { for my $after ( $dup .. $#digs ) { my @result= @digs; splice @result, 1+$after, 0, $digs[$dup]; print @result, $/; } } } while( NextPermute( @digs ) ); }

    - tye        

      Tye,

      Thank you, I will look into this one.

      Cheers,

      M.ROMAN
Re^2: Find duplicate digits
by Ratazong (Monsignor) on Apr 07, 2010 at 11:16 UTC

    You can try the following algorithm:

    1. pass through your input one digit per time
    2. use a hash to count how often each digit occurs
    3. once you are finished, pass through the hash (again) to see how many digits are ocuring two times
    4. print yes/no

    Once you have done this, think how to adapt the algorithm to handle the special case 1111....

    Have Fun! Rata

    PS.: it is good that you looked for an old thread! However you'll get more answers if you'd opened a new thread and just had provided a link to the old one! well, next time ;-)

      Ratazong,

      Thank you for your reply.

      (vigorously flapping noob wings)

      Argh! Can't fly that high as of yet . . .

      I will link to a thread instead next time however :)

      Cheers,

      M.Roman