Shiny Donkey!
Shiny Donkey! Shiny Donkey! Shiny Donkey!
                  Fake Banner Ads!  Mini-Sites!  
    New Shiny Donkey Posts  more >>
* BREAKING NEWS *  9 out of 10 commandments recommend traveling back in time to prevent your own birth instead of shinydonkey.com

.NET None
[reply]   

08/23/05 11:24 PM EST
posted by jake

I originally came to post an interesting algorithm problem, then I saw I was getting trashed: sorry for not responding sooner. First the fun problem:

"find the largest integer where each pair of consecutive digits is a distinct prime number"

For example, the number 6137 has consecutive digits 61;13;37... all of which are distinct primes.

Now some quick responses:

On loop unrolling:
these discussions were always centered around vector processing techniques.So referances

AMD:AMD64
http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25112.PDF
pg.156 Pretty well explained. As I stated before, this is a chip specific optimization.And there are diminishing returns at a point.

IBM: Power PC
http://www.jot.fm/issues/issue_2005_03/column3 
http://www-128.ibm.com/developerworks/power/library/pa-unrollav3/
specific use of the vector register

Intel:
http://www.intel.com/software/products/compilers/flin/docs/main_for/mergedprojects/optaps_for/common/optaps_hlo_unrl.htm
generic loop unroll statement.

On predefined functions in C:
#define P printf
is a style choice. Although I long believed it was more. Over the past 8 months I've learned better. However
#if (_MIPS_SZLONG == 64) || defined(__x87) || defined(__ia64)
#define Tt(t,x) ((x)<<((((t>>1)&1)+3)&3))
#else
#define Tt(t,x) ((x)<<(t+2&3))

is an optimization,albeit specific.Another use is loop invariant code motion either in header files when possible or just outside the loop for a performance boost. However I've seen this technique used for defining pointer chasing routines as similar subexpressions in Arthur's A+ code: wether it's style or not:is still unclear.

http://www.cs.utexas.edu/users/hunt/class/2003-fall/cs352/lectures/class10.ppt#352,9,Machine-Independent Opts. (Cont.)
good generic optimization article

On Javascript:
The conversation is a bit off, but not too bad. The problem lies in my poor choice of language. Javascript is interpreted, when I said compiled I mean the english code has to turn into an instruction set. When I said "it [the browser] has an embedded JVM", I was referring to an interpreter engine: and it does.(google Gecko or Rhino). Why would unrolling loops work for javascript, same reason it does for C. Ultimately everything passes across the chip,and the more you can do to help the interpreter (or compiler) the better.

Most, if not all, of these things are abstracted in .NET (and Java). They are handled for you by the compiler. But the compiler is not perfect: it will not unroll your loops all the time, so if you have a repetitive function: help it [the compiler] out. The compiler will not catch every loop invariant code motion: so when possible move it outside the loop. .NET does a good job of vectorizing code and IBM built HotSpot for Java to work as well if not better. The point of all this was not to be an a s s (although I clearly play the role well) but rather bring some other strategies to the table.

 


[reply]   

08/23/05 11:42 PM EST
posted by jake

I was just reading through the posts here:

1.)the comment on unrolling the javascript loop would result in larger code set to transfer to the browser makes perfect sense. Good point.

2.)Performance is not the main focus for good code: I agree. Readability,maintinence, management,security ect ect are certainly more important. However, sometimes those things are set aside for performance, although rarely. For example, in finance when you are analyzing streaming data on a wire feed and building correlation matricies for the portfolio VaR.... accuracy is most important,followed by performance,everything else is irrelevant. But in these rare cases, you wouldn't use a language like C# and especially not javascript (maybe is you had some crazy streaming RIA it would matter). 

3.) Thought I'd give a hint on the algorithm problem: the largest int is not really important, there exists a number which is uses the most number (count) of distinct 2 digit primes. So no need to get caught up in questions like unsigned int? Long long int? int? ect.

 


[reply]   

08/25/05 04:03 PM EST
posted by JER email web

Ah, glad to see you've joined the fray, Jake.  I'm on vacation in NC this week but I have an internet connection for one day.  Anyway, I hope we can all actually discuss this topic rather than resorting to a flame war -- but Jonny will be Jonny...

As for the biggest prime consec int question, the way you first posed it (verbally, not on Shiny D) ended with "and write it in your favorite language."  I think that makes the question either too easy or too hard.  Extra checks would have to be made that the current value is not approaching the max val or, conversely, it could be written in "bob++" that has a max int value of 6.  However, if that part of the question is removed and there are no language-induced size boundaries, it seems that the easiest thing to do would be to write something that loops from 99 to 01, taking each value modded by 2, 3, 5 & 7.  If all 4 comparisons fail to give a 0 result, the current number is prime and can either be appended to the front of a string or added to a counter that is constantly increasing by 100^(n) where n is the number of elements already noted as "prime."  For increased optimization, one could easily change the start and end points to the highest and lowest known primes in that range.

uberInt total = 0;

for(int i = 99; i > 0; i--){
   if(i % 2 != 0 || i % 3 != 0 || i % 5 != 0 || i % 7 != 0){
      total = i + (total * 100^n);
      n++;
   }
}


Or perhaps with some unrolling...

uberInt total = 0;

for(int i = 99; i > 0; ){
   if(i % 2 != 0 || i % 3 != 0 || i % 5 != 0 || i % 7 != 0){
      total = i + (total * 100^n);
      n++;
   }
   i--;
   if(i % 2 != 0 || i % 3 != 0 || i % 5 != 0 || i % 7 != 0){
      total = i + (total * 100^n);
      n++;
   }
   i--;
   if(i % 2 != 0 || i % 3 != 0 || i % 5 != 0 || i % 7 != 0){
      total = i + (total * 100^n);
      n++;
   }
   i--;
   if(i % 2 != 0 || i % 3 != 0 || i % 5 != 0 || i % 7 != 0){
      total = i + (total * 100^n);
      n++;
   }
   i--;
}


I believe that solves it...  now back to my vacation...  I'll be back on Monday, so Bull is in charge while I'm gone...

 


[reply]   

08/29/05 05:20 AM EST
posted by JER email web

I was thinking about this over the weekend and

for(int i = 99; i > 0; i--){

could easily be replaced with

for(int i = 99; i > 0; i -= 2){

which would remove the need for the (i % 2 != 0) check, since no even numbers will ever be evaluated.

 


[reply]   

08/31/05 05:29 AM EST
posted by jake

you could do that, and brute force every combination of primes till you find one that works. That would take a long time. As I stated in email, but not here, assume that the word interger means a positive whole number. There is a better method.

The anwsers are:
The number that works forwards and backwards: (a->b and b->a)

19737131179


Largest forwards only (a -> b):

619737131179



 


[reply]   

08/31/05 08:46 AM EST
posted by ryan email web

heh. Ok - so I have played with "clever" solutions to no avail for long enough... here's a brute force implementation.  It takes around 30 seconds to process 2 million possibilities on a PM-2GHz, so it'd take roughly 215 days to get to the maximum value of 619737131179 - although this problem would be very straightforward to distribute to a multi-proc architecture.

So obviously this solves the problem, but it's certainly not fast.  Jake, you mind sharing the answer?

class Integer #let's extend integers a bit so they know if they're prime
def prime?
return false if self < 2
not (2..Math.sqrt(self).floor).find { |i| self % i == 0 }
end
end

class String #let a string determine if it's composed of pairs of primes
def each_pair_unique_prime?
used = []
1.upto(length - 1) do |i|
pair = self[i-1].chr + (self[i].chr)
if (pair.prime? && (not used.include? pair)) then
used << pair
else
return false
end
end
true
end

def prime?
self.to_i.prime?
end
end

max = 619737131179 #theoretical maximum result

101.step(max, 2) do |x|
xs = x.to_s
p 'currently at: ' + xs if x % 1000000 == 1
p 'FOUND: ' + xs if xs.each_pair_unique_prime?
end

 


[reply]   

08/31/05 11:34 AM EST
posted by JER email web

I thought you were asking for a huge number containing 2 digit primes, I didn't realize that each component had to form a new prime with the number next to it.  Let's try this again...

So using my prime? algorithm or Ryan's as a baseline, we can narrow our search to a limited number of possible 2 digit primes.  From that list of possible primes, some of those numbers will start with a value that violates our earlier mod rules (e.g. 23 is prime but it starts with a 2, which cannot be the final digit of a 2 digit prime number!).  Those numbers can be ignored for now.  Doing so narrows our list significantly, though I don't see a non-bruteforce way to take those numbers and build the biggest value.

In trying to find more info, I found this similar and more thorough explanation on Google, though they use "trial and error" in the final step:

The largest integer such that each pair of consecutive digits is a different prime is 619,737,131,179. There are 21 two-digit primes. However, eleven of these start with an even digit or a five and can, therefore, be only at the beginning of the number. This leaves ten primes (11, 13, 17, 19, 31, 37, 71, 73, 79, 97) that can occur elsewhere in the number. Obviously, the best we can do is to use all ten of these primes to form an eleven-digit number. A little trial and error quickly shows that 19,737,131,179 is the largest number that can be formed using all ten primes. The largest of the remaining two-digit primes that ends in 1 is 61, which, when appended to the front of this number, leads to the answer above.

 


[reply]   

08/31/05 12:24 PM EST
posted by alex email

Found this nifty little website that has things like this puzzle.  Its called PrimePuzzles.net

The statement requires that any two adjacent digits must be distinct primes. A two-digit prime must end in 1, 3, 7, or 9. There are only 10 two-digit primes using these numbers: 11 13 17 19 31 37 71 73 79 97. Arranging all these numbers into one will produce an 11-digit number, which could also be a 12-digit number if the leftmost digit and an even digit form a prime. Hence, the largest possible prime would have at most 12 digits.
http://www.primepuzzles.net/puzzles/puzz_253.htm

 


[reply]   

08/31/05 06:55 PM EST
posted by ryan email web

I'm still curious to know if there is a formula that solves this - seems like there's got to be a sequence or something which I am unaware of that can be used to arrive at this result.

 


[reply]   

09/01/05 12:54 PM EST
posted by JER email web

Ryan, here's the answer that Jake e-mailed to me.  Most of it is RJ45 to me, and I'm still not clear what forwards and backwards means, since 91 isn't prime.  I'm assuming "backwards" is a mathematical term meaning something else...?

After thinking about it (more), I realized the question has nothing to do
with the largest integer (Unsigned ect), but rather has only to do with the
consecutive pairs of prime. To begin, build a vector of 2 digit primes:


 * pn:{[n]&0,2=+/0={x!/:x}1+!n};P: pn 100;a:#P;P:$P(4+!(a-4)) *

* P *

*("11"*

* "13" *

* "17" *

* "19" *

* "23" *

* "29" *

* "31" *

* "37" *

* "41" *

* "43" *

* "47" *

* "53" *

* "59" *

* "61" *

* "67" *

* "71" *

* "73" *

* "79" *

* "83" *

* "89" *

* "97") *

* *

*Then matrix transpose the vector. Find all distinct values of the second
digit of the primes. This is 1 3 7 9. Return to a new vector all numbers
where the first digit is 1 3 7 or 9. This leaves the sucessors for each
node. *


* *

p:+P;a:?p[1];b:p[0];i:0;H:()

while[i<#a;

H:H,& a[i] ~' p[0]

i+:1]

P[H];R:+P[H]

R

("11"

"13"

"17"

"19"

"31"

"37"

"71"

"73"

"79"

"97")

* *

*Now build a 2 matricies, left and right with connectivity on the number.
See below *

  
 Lmx
 
R
 
Rmx
 
     71
 
31
 
("11"
 
13
 
17
 
19
 
  71
 
31
 
"13"
 
31
 
37
 
   71
 
31
 
"17"
 
71
 
73
 
79
 
  71
 
31
 
"19"
 
97
 
     73
 
13
 
"31"
 
11
 
13
 
17
 
19
 
73
 
13
 
"37"
 
71
 
73
 
79
 
  97
 
17
 
"71"
 
11
 
13
 
17
 
19
 
97
 
17
 
"73"
 
31
 
37
 
   97
 
17
 
"79"
 
97
 
      19
 
"97")
 
71
 
73
 
79
 
 * *

*From here it's pretty obvious, start from the tail which is the R value
where the length of Rmx=1*


* *

*.......................79*

* *

*Then fill in*

* *

*19 97 ................79*

* *

*Using recursive search (eliminate used fields) 2 nd iteration below each
time selecting max Rmx that hasn't be used.*


* *
  
 Lmx
 
R
 
Rmx
 
     71
 
31
 
("11"
 
13
 
17
 
19
 
  71
 
31
 
"13"
 
31
 
37
 
   71
 
31
 
"17"
 
71
 
73
 
79
 
  71
 
31
 
* "19"*
 
*97*
 
     73
 
13
 
"31"
 
11
 
13
 
17
 
19
 
73
 
13
 
"37"
 
71
 
73
 
79
 
  97
 
17
 
"71"
 
11
 
13
 
17
 
19
 
97
 
17
 
* "73"*
 
31
 
37
 
   97
 
17
 
* "79"*
 
*97*
 
     *79*
 
*19*
 
* "97")*
 
71
 
*73*
 
*79*
 
 * *

*Once you're done, you have the numbers *

* *

*19 97 73 37 71 13 31 17 19

*

*Select the and prime indices (2 removed) and you have *

* *

19737131179

 *This is the digit that works forwards and backwards. To just work forwards
add the largest value from the original prime vector where the second digit
is the 1 st digit of this number, or 61*


* *

619737131179

 


[reply]   

09/01/05 01:15 PM EST
posted by ryan email web

That's an interesting approach & appears to work. Very cool.

While discussing this with a coworker the idea came up to brute force it with just reasonable values: build a tree and traverse all branches until the one with the highest value is found (after exhausting all paths).  This came from a structure that I was playing with eariler which was a map of tens digits to all ones digits which would result in a prime for that ten.  Seems like that approach would work and should take far, far less processing time.

 

Name

 registered? log in!

E-mail (optional)

Website (optional)

  

To ensure security, this site requires unregistered users to enter a verification code:
 
Your code is:  
Enter Code:   

Note: Only registered ShinyDonkey.com users can post images. Only administrators can delete images.

  



"And remember, a shiny new donkey for whoever brings me the head of Colonel Montoya..."
e-mail webmaster