Starz has asked for the wisdom of the Perl Monks concerning the following question:

A family member passed away. I need to try and get the pin code for a safe. The pin uses the numbers 0123456789. I can’t recall the code but I do remember the last digit is 1 and there are no repeat numbers within the code. Can you please help me figure out how to solve this? Thank you

Replies are listed 'Best First'.
Re: Pin code
by Athanasius (Cardinal) on Sep 12, 2018 at 04:12 UTC
Re: Pin code
by FloydATC (Deacon) on Sep 12, 2018 at 10:33 UTC

    Smells like a homework assignment but here's a solution without any dependencies:

    #!/usr/bin/perl use strict; use warnings; PIN: foreach my $pin ("0000" .. "9999") { # Last digit is a 1 next unless $pin =~ /1$/; # No repeating digits my %count = (); foreach my $digit (split(//, $pin)) { $count{$digit}++; next PIN if $count{$digit} > 1; } print $pin . "\n"; }
    -- FloydATC

    I got 99 problems, most of them have to do with printers.

Re: Pin code
by johngg (Canon) on Sep 12, 2018 at 15:11 UTC

    You could use glob to generate the numbers and grep to filter out repeats.

    johngg@shiraz:~/perl/Monks$ perl -Mstrict -Mwarnings -E ' my @notOnes = ( 0, 2 .. 9 ); my $globStr = ( q|{| . join( q{,}, @notOnes ) . q|}| ) x 3 . q{1}; say for grep { ! m{(.).*\1} } glob $globStr;' | wc -l 504

    I hope this is helpful.

    Update: Adding a line to show what the string passed to glob looks like.

    johngg@shiraz:~/perl/Monks$ perl -Mstrict -Mwarnings -E ' my @notOnes = ( 0, 2 .. 9 ); my $globStr = ( q|{| . join( q{,}, @notOnes ) . q|}| ) x 3 . q{1}; warn qq{$globStr\n}; say for grep { ! m{(.).*\1} } glob $globStr;' | wc -l {0,2,3,4,5,6,7,8,9}{0,2,3,4,5,6,7,8,9}{0,2,3,4,5,6,7,8,9}1 504

    Cheers,

    JohnGG

Re: Pin code
by marto (Cardinal) on Sep 12, 2018 at 08:17 UTC

    As an aside, I wouldn't bother trying to brute force this by hand, I'd just feed the numbers into an Arduino driving 10 solenoids to press the buttons for me. Boring repetitive tasks are error prone in my (fat fingered) experience.

      That's exactly why I'd use an angle grinder ...


      holli

      You can lead your users to water, but alas, you cannot drown them.

        I don't have one, but do have plenty of the other stuff :) It's also easier to injure yourself with an angle grinder, plus it's pretty noisy and messy :P If we assume the safe operates in a reasonable fashion, that it can deal with 4 key presses a second it'd be possible to exhaust the combinations in less than 9 minutes. This also has the added advantage of not destroying the safe :) I've not seen a digital safe intended for home use that rate limits unlock attempts.