Hi, I saw this puzzle mentioned at
Does Visual studio Rot the Brain (linked to from slashdot today). The author solved it with c and I thought I'd give it a whack with perl. I didn't google around for solutions, on purpose, cause I wanted to do it myself.
My solution is below. It's been running for a bit, and still hasn't spit out an answer. I'm wondering if anybody out there has a faster way to do it, or if anyone would care to comment on my code.
One thought I had was, I don't really know threads but I wonder... could threads speed this up (obviously at the cost of using more computer resources).
I suspect there are other number theory tricks that could be applied here as well, but I don't know them either.
Well, Over and out monks :)
#What is the largest integer whose digits are all different (and do no
+t include 0) that is divisible by each of its individual digits?
#Requirements:
# -- Integer
# -- Digits all different (largest possible would be 987654321)
# -- Divisible by each of individual digits
# note:
# this integer cannot contain the digit 5 if it also contains any e
+ven digit,
# because then the number would be divisible by 10, and the last di
+git would be 0
# similarly, if the last digit is odd, it can't contain any other e
+ven digit.
use strict;
use warnings;
my $max_number = 987654321;
#my $max_number = 10000;
foreach ( 0 .. $max_number - 1 ) {
my $test_number = $max_number - $_;
print "number / 100000: " . $test_number/100000 . "\n" if $test_nu
+mber % 100000 == 0;
if ( passes($test_number) ) {
print "$test_number passes!\n";
die;
}
}
sub passes {
my $test_number = shift() || die "no test number";
my @digits = split("", $test_number);
my %seen;
my $last_digit;
#fail if see the same digit twice.
foreach ( @digits ) {
return 0 if $_ == 0; #fail if contains 0
return 0 if $seen{$_};
$seen{$_} = 1;
}
#set the last digit
$last_digit = $digits[$#digits];
#fail if contains 5, and any other digit is even
#or the last digit is 1, and any other digit is even
if ( $seen{5} || $last_digit % 2 == 1 ) {
for ( qw(2 4 6 8) ) {
return 0 if $seen{$_};
}
}
for ( keys %seen ) {
return 0 unless $test_number % $_ == 0 ;
}
return 1;
}
UPDATE: Re the answers I've gotten so far, let me just say, I'm awed. Back to work...
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.