Golfing with prime factors

Dirk-Jan reminded me of the Perl Golf and Code Golf contests, both of which have the aim of solving a simple programming task in as few characters of source code as possible. See his post for a stunning example.

One of the open challenges is to work out the prime factors of a given number. To make things a little more difficult, the output must be printed in a specific format:

7000: 2^3 5^3 7
123456789: 3^2 3607 3803

Here is one of my attempts at a Ruby implementation, which is 97 bytes after removing the final trailing newline:

print”#{n=gets.to_i}: ”
(2..n).each{|x|i=0;n,i=n/x,i+1while n%x<1
print x,i<2?’ ‘:”^#{i} “if i>0}

Then we switched to Perl, and together Dirk-Jan and I managed to come up with a version which is just 82 bytes after removing all the newlines (just pipe it through “perl -pe chomp“).

print$n=pop,’:';for(2..$n){
$i=0;$n/=$_,$i++until$n%$_;
print” $_”.”^$i”x($i>1)if$i}

(Be aware that the Ruby version takes its input from stdin, while the Perl program looks at its first command-line argument.)

That’s pretty compact, right? Algorithmically, the code is actually fairly straightforward; probably the most evil trick we use is to employ the ‘x‘ operator, which does string concatenation a given number of times, in combination with the fact that any Boolean expression can be treated as a numeric value of either 0 or 1, as in C (but not in Ruby).

Unfortunately, both of the versions given above are horrendously slow. They have a running time of O(n), while any self-respecting factorization algorithm should be at most proportional with the largest prime factor of n. It took my Pentium-4 system almost 45 minutes to calculate the factors of 2,000,000,000, which a reasonably intelligent high school student could probably have done in half a minute or so. Here is a version which can do it in a fraction of a second, but at the cost of being a whole 10 bytes larger:

print$n=pop,’:';
for($x=2;$n>1;$x++){
$i=0;$n/=$x,$i++until$n%$x;
print” $x”.”^$i”x($i>1)if$i}

So, how are we doing in the contest? Well, we’re not even competing. The leader is currently at an astonishing 76 bytes! I have no idea how they do that. The winning programs are all in Perl, which tends to do very well in this type of contest despite the fact that all variable names are at least two characters. The best Ruby program is 82 bytes, with Python coming in at 100 and PHP at 122.

Another task in Code Golf is to write a program which can solve the famous Towers of Hanoi puzzle, given a random starting position with up to nine disks. The input consists of three lines of text, each giving the sequence of disks for one of the three pegs. For example:

975
864
321

The goal is to print the series of moves needed to get all disks together on peg C, the third one, following the usual rule that at no time may a larger disk be on top of (to the right of) a smaller one. Here is a very simple example run with only three disks:

$ cat simple.txt
31

2

$ ruby hanoi.rb simple.txt
2 to B
1 to B
3 to C
1 to A
2 to C
1 to C

We haven’t spent as much time yet on this one as on the prime factorization problem. Here is my best effort so far:

T,D=[],[:A,:B,:C]
D.each{|t|gets.chomp.each_byte{|x|T[x-48]=t}}
def m s,t
if s>0
m s-1,(D-[t,T[s]])[0]
puts”#{s} to #{t}”
m s-1,T[s]=t
end
end
m T.size-1,:C

This is an embarassing 157 bytes. In the actual contest participants, Ruby is leading the pack this time, with 104 bytes, while the best Perl entry so far is a whole six bytes larger. Go Ruby!

The Code Golf contest is open to participants using Ruby, Perl, Python and PHP. Nonetheless, Jeroen, Jeroen and Raimond, I look forward to you trying to beat the above programs in Java or C#..  :-P

Tags: , , , , , , , ,

5 Responses to “Golfing with prime factors”

  1. [...] rest is here:  Golfing with prime factors Posted in PHP | Tags: 3607-3803, a-given-number-, attempts, few-characters, have-the-aim, [...]

  2. Well since a little bit of Java code which reads input already weighs in at 130 bytes, why bother trying. ;)
    “class A {public static void main(String[] a) {for (String i=System.console().readLine();i!=null;i=System.console().readLine()){}}}”

  3. Thanks for the very interesting post Martin. I look forward to reading more from you in the future.

  4. accident lawyer says:

    Long time lurker, thought I would say hello! I really dont post much but thanks for the good times I have here. Love this place..

    When I was hurt in that motorcar accident my life would be changed eternally. Sadly that driver had no car insurance and I was going to be in pain for ever.

    This was not time for me to start and guess what to do. I had to find a good attorney to help me get what I needed. After all, my family was counting on me.

    How awful was it? I has bedridden for 6 months, I had to have constant care and my clinic bills went through the roof!

    Luckily, I found a good referral site to help me.

    I will post more later this month to tell you more about what I have been going through.

    Anwyas thanks for the good work keep it up!

    In practice, legal jurisdictions exercise their right to determine who is recognized as being a lawyer; as a result, the meaning of the term “lawyer” may vary from place to place.]

    * In Australia the word “lawyer” is used to refer to both barristers and solicitors (whether in private practice or practising as corporate in-house counsel).
    * In Canada, the word “lawyer” only refers to individuals who have been called to the bar or have qualified as civil law notaries in the province of Quebec. Common law lawyers in Canada may also be known as “barristers and solicitors”, but should not be referred to as “attorneys”, since that term has a different meaning in Canadian usage. However, in Quebec, civil law advocates (or avocats in French) often call themselves “attorney” and sometimes “barrister and solicitor”.
    * In England and Wales, “lawyer” is used loosely to refer to a broad variety of law-trained persons. It includes practitioners such as barristers, solicitors, legal executives and licensed conveyancers; and people who are involved with the law but do not practise it on behalf of individual clients, such as judges, court clerks, and drafters of legislation.
    * In India, the term “lawyer” is often colloquially used, but the official term is “advocate” as prescribed under the Advocates Act, 1961.]
    * In Scotland, the word “lawyer” refers to a more specific group of legally trained people. It specifically includes advocates and solicitors. In a generic sense, it may also include judges and law-trained support staff.
    * In the United States, the term generally refers to attorneys who may practice law; it is never used to refer to patent agents] or paralegals.]
    * Other nations tend to have comparable terms for the analogous concept.

  5. [...] Eco-Friendly Earth Golf Ball Backed By Green Recycling Program | ParkHowell.comHow Golf Distance Is Achieved | Golf Tips Insider Blog Golf is Life, so tee it up – Generation J.D.Shoulder Anatomy | Golf Fitness Training Programs at Body Balance for PerformanceA Modest Proposal for a Rebol Code Golf DialectVirginia Satir Personality Categories | The Golf HypnotistMartin Wolf's weblog [...]

Leave a Reply