Python

Project Euler: Problem 6

After a nice vacation, the obsession continues.

The sum of the squares of the first ten natural numbers is,
12 + 22 + ... + 102 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)2 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 385 = 2640. Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

Haskell:

  1. module Main where
  2.  
  3. main :: IO ()
  4. main = do
  5. let x = [1..100]
  6. let sum2 = sum $ map (^2) x
  7. let sum1 = (sum x) ^2
  8. print (sum1 - sum2)

Python:
  1. #!/usr/bin/python3
  2. """Project Euler solution using generators."""
  3.  
  4. sum1 = 0
  5. sum2 = 0
  6.  
  7. for i in ((x,x ** 2) for x in range(1,100+1)):
  8. sum1 += i[0]
  9. sum2 += i[-1]
  10.  
  11. print(sum1 ** 2 - sum2)

PERL:
  1. #!/usr/bin/perl
  2.  
  3. my $sum1 = 0;
  4. my $sum2 = 0;
  5.  
  6. for (1..100)
  7. {
  8. $sum1 += $_;
  9. $sum2 += $_ **2;
  10. }
  11.  
  12. print ($sum1 **2 - $sum2);

Java:
  1. public class problem6
  2. {
  3. public static void main( String[] args)
  4. {
  5. int sum1 = 0;
  6. int sum2 = 0;
  7.  
  8. for( int i = 0; i < 100; i++)
  9. {
  10. sum1 += i;
  11. sum2 += i ^ 2;
  12. }
  13.  
  14. System.out.println(sum1 ^ 2 - sum2);
  15. }
  16. }

I admit writing a solution for Java is kind of a cheat. It's exactly the same as the PERL solution, minus some language differences. But since I started playing around with Android, I've started to spend more time working with Java and it has just bled into this project.

Run time comparison:

Because Java has to be compiled, I'm now using posting the time for the compiled version of the Haskell solution.
Haskell: 0.004s
Python: 0.285s
Perl: 0.005s
Java: 0.625s

I'll refrain from insulting the speed of Java if you do. ;)

Discussion:

Because of the simplicity of the solution, I tried to play around with the answers between Haskell and Python. Originally my Python solution looked more like my Haskell one, but after learning about generators I decided I would use one for the Python solution. All in all I think it would out rather well.

Questions, comments, insults?? (And not about me, about the code... I know what you people are thinking!)

Project Euler: Problem 5

It's that time again. ;)

Question five reads:
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?

And here are my solutions (which I hope are correct this time).

Haskell:

  1. module Main where
  2.  
  3. import Data.List
  4.  
  5. divisible_11_to_20 number = 10 == (length $ unfoldr(\x -> if (snd $ quotRem number x) /= 0 || x < 11
  6. then Nothing
  7. else Just(x,x - 1)) 20)
  8.  
  9. -- solved this by the help on this URL:
  10. -- (http)basildoncoder.com/blog/2008/06/10/project-euler-problem-5/
  11. -- by increaing the loop from 2 to 2520, problem solves in seconds
  12. main :: IO ()
  13. main = print $ until (divisible_11_to_20) (+2520) 2520

As a quick note, yes I know that I could do this much quicker and cleaner with a list comprehension. I decided to use unfoldr because I wanted the experience of working with it. If it wasn't for this little desire my answer would have looked a lot more like my Python answer.

Python:

  1. #!/usr/bin/python
  2.  
  3. def div_11_to_20(divided):
  4. return all([not bool(divided % x) for x in xrange(11,20+1)])
  5.  
  6. if __name__ == "__main__":
  7. count = 2520
  8. while div_11_to_20(count) == False:
  9. count += 2520
  10.  
  11. print "%s" % count

And finally my Perl solution:

  1. #!/usr/bin/perl
  2.  
  3. sub divide_11_to_20
  4. {
  5. my ( $divided ) = @_;
  6.  
  7. foreach (11..20)
  8. {
  9. return 0 if ($divided % $_);
  10. }
  11.  
  12. return 1;
  13. }
  14.  
  15. my $main_count = 2520;
  16. while ( !divide_11_to_20($main_count) )
  17. {
  18. $main_count += 2520;
  19. }
  20.  
  21. print $main_count;

Run Times:
Haskell: 0m1.302s
Python: 0m0.769s
Perl: 0m0.223s

Observations:
It doesn't surprise me that the Perl solution ends up being the fastest on these run times. I say this because per iteration the Perl solutions has less calculations. Both the Haskell and Python solutions perform 10 divisions per iteration, where as the Perl solution only performs 10 divisions when the correct number is is being divided. Its one of those things where the difference is very small, but will become larger as the number of iterations increases.

Project Euler: Problem 4

If you been following me the last three times I've done this, then you really don't need any introductions.

Problem four is as follows:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.

Find the largest palindrome made from the product of two 3-digit numbers.

And my results in the usual three languages are:
Hasekell:

  1. module Main where
  2.  
  3. import Data.List
  4.  
  5. --Stole numberToList code from:
  6. --http://www.rhinocerus.net/forum/lang-functional/95473-converting-number-list-haskell.html
  7. numberToList = reverse . unfoldr (\x -> if x == 0 then Nothing else let (a,b) = x `quotRem` 10 in Just (b,a))
  8.  
  9. is_palimdrome number = num_list == reverse num_list
  10. where
  11. num_list = numberToList number
  12.  
  13. main :: IO ()
  14. main = print . maximum . filter is_palimdrome $ zipWith (*) y z
  15. where y = [1000,999..100]
  16. z = [1000,999..100]

Python:

  1. #!/usr/bin/python
  2.  
  3. def int_to_list(number):
  4. return map(int, str(number))
  5.  
  6. def is_palindrome(number):
  7. local_list = int_to_list(number)
  8. return local_list == list(reversed(local_list))
  9.  
  10. if __name__ == "__main__":
  11. second_list = first_list = list(reversed(range(100,1000+1)))
  12. prod_set = map(lambda i,j: i*j, first_list, second_list)
  13.  
  14. print "%s" % max(filter(is_palindrome,prod_set))

And finally, Perl:

  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5. use List::MoreUtils qw(pairwise);
  6.  
  7. sub is_palimdrone
  8. {
  9. my ($number) = @_;
  10.  
  11. my @digits = split(//, $number);
  12. my @reversed_digits = reverse(@digits);
  13.  
  14. for (my $i = 0; $i < @digits; $i++)
  15. {
  16. return 0 if $digits[$i] != $reversed_digits[$i];
  17. }
  18.  
  19. return 1;
  20. }
  21.  
  22. my @two = my @one = reverse((1..1000));
  23.  
  24. my @join = pairwise { $a * $b } @one, @two;
  25.  
  26. foreach(@join)
  27. {
  28. if ( is_palimdrone($_))
  29. {
  30. print "$_\n";
  31. last;
  32. }
  33. }

Run Times
Haskell: 0m0.034s
Python: 0m0.060s
Perl: 0m0.166s

For anyone that is not aware, haskell should win this statistic every time. Out of the three languages its the only one that is compiled. If anyone knows of a way to run haskell interpretively, and without using ghci, please let me know. I've tried looking on the internets for this piece of information, but have come up short.

I am still open to code suggestions or improvements. I have found these to be very helpful and useful. So thank you to everyone that has said something before.

UPDATE
So here is the new code that fixes the problem of my algo before. I'm leaving the old up just to future readers aren't confused.

Thanks goes out to Jeremiah, Tom.B, Juster, and Guillaume for the code ideas used to fix the mistakes in the code above. Thanks guys!

Haskell:

  1. module Main where
  2.  
  3. import Data.List
  4.  
  5. --Stole numberToList code from:
  6. --http://www.rhinocerus.net/forum/lang-functional/95473-converting-number-list-haskell.html
  7. numberToList = reverse . unfoldr (\x -> if x == 0 then Nothing else let (a,b) = x `quotRem` 10 in Just (b,a))
  8.  
  9. is_palimdrome number = num_list == reverse num_list
  10. where
  11. num_list = numberToList number
  12.  
  13. main :: IO ()
  14. main = print . maximum $ [ x * y | x <- nums, y <- nums, is_palimdrome (x * y)]
  15. where nums = [1000,999..100]

Python:
  1. #!/usr/bin/python
  2.  
  3. def int_to_list(number):
  4. return map(int, str(number))
  5.  
  6. def is_palindrome(number):
  7. local_list = int_to_list(number)
  8. return local_list == list(reversed(local_list))
  9.  
  10. if __name__ == "__main__":
  11. print "%s" % max([x * y for x in range(1000,100, -1) \
  12. for y in range(1000,100,-1) \
  13. if is_palindrome(x * y)])

Perl:
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5. use List::Util qw(max);
  6.  
  7. sub is_palimdrone
  8. {
  9. my ($number) = @_;
  10.  
  11. my @digits = split(//, $number);
  12. my @reversed_digits = reverse(@digits);
  13.  
  14. for (my $i = 0; $i < @digits; $i++)
  15. {
  16. return 0 if $digits[$i] != $reversed_digits[$i];
  17. }
  18.  
  19. return 1;
  20. }
  21.  
  22. my @two = my @one = reverse((100..999));
  23. my @three;
  24.  
  25. for my $one (@one)
  26. {
  27. for my $two (@two)
  28. {
  29. my $three = $two * $one;
  30. next unless is_palimdrone($three);
  31. push @three, $three;
  32. }
  33. }
  34.  
  35. print max(@three);

Project Euler: Problem 3

OK, next installment of this. :)

The problem is stated as such:
The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143 ?

Haskell:

  1. module Main where
  2.  
  3. factors count top_number
  4. | count >= top_number = []
  5. | zero_mod count = count : new_top: factors (count + 2) new_top
  6. | otherwise = factors (count + 2) top_number
  7. where new_top = round . fromIntegral $ top_number `div` count
  8.  
  9. zero_mod divisor
  10. | divide == 0 = True
  11. | otherwise = False
  12. where divide = mod 600851475143 divisor
  13.  
  14. --prime :: Integer -> Integral -> Bool
  15. prime divisor divided
  16. | divided == 1 = True
  17. | divisor >= sqrt_divided = True
  18. | mod divided divisor == 0 = False
  19. | otherwise = next_prime
  20. where next_prime = prime (divisor + 2) divided
  21. sqrt_divided = round . sqrt . fromIntegral $ divided
  22.  
  23. is_prime :: Integer -> Bool
  24. is_prime input = prime 3 input
  25.  
  26. main :: IO ()
  27. main = do
  28. let x = factors 3 600851475143
  29. let y = map is_prime x
  30. putStrLn $ show $ snd $ maximum ( zip y x)

Getting that sqrt function to work took me longer to figure out than I want to admit. I was having the hardest time getting the numeric types to play nice. I finally broke down and asked the haskell-beginners email list to get the answer.

Python:

  1. #!/usr/bin/python
  2.  
  3. import math
  4.  
  5. top_number = 600851475143
  6.  
  7. def zero_mod(divisor):
  8. if top_number % divisor == 0:
  9. return True
  10. else:
  11. return False
  12.  
  13. def is_prime(divided):
  14. divisor = 3
  15. sqrt_divided = math.sqrt(divided)
  16. if divided == 1:
  17. return True
  18. else:
  19. while divisor <= sqrt_divided:
  20. if divided == divisor:
  21. return True
  22. elif divided % divisor == 0:
  23. return False
  24. else:
  25. divisor += 2
  26. return True
  27.  
  28. def main():
  29. count = 3
  30. go_to = top_number
  31.  
  32. first_list =[]
  33.  
  34. while count <= go_to:
  35. if zero_mod(count):
  36. first_list.append(count)
  37. go_to = top_number / count
  38. first_list.append(go_to)
  39.  
  40. count += 2
  41.  
  42. second_list = map(is_prime, first_list)
  43. print "%s" % max(zip(second_list, first_list))[-1]
  44.  
  45.  
  46. if __name__ == "__main__":
  47. main()

And finally Perl:

  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. my $top_number = 600851475143;
  7.  
  8. sub is_prime
  9. {
  10. my ($divided) = @_;
  11. return 1 if ($divided == 1);
  12.  
  13. my $divisor = 3;
  14. my $sqrt_divided = sqrt($divided);
  15.  
  16. while($divisor <= $sqrt_divided)
  17. {
  18. return 0 unless ($divided % $divisor);
  19. $divisor += 2;
  20. }
  21.  
  22. 1;
  23. }
  24.  
  25. my @f;
  26. my $new_top = $top_number;
  27.  
  28. for(my $i = 3; $i <= $new_top; $i += 2)
  29. {
  30. unless ($top_number % $i)
  31. {
  32. if (is_prime($i))
  33. {
  34. push @f, $i;
  35. }
  36. }
  37. $new_top = $top_number / $i;
  38. }
  39.  
  40. print $f[-1];

Props goes out to zloyrusski who helped me figure out a major hang up with Perl on this one. The for loop idea was his,though I really diverted from his answer. Goes to show you how much two people really can think differently. Hey Zloyrusski, is this Perl code looking better? ;) As always, I'm open to constructive criticism.

--UPDATES--
1) Code has been redone to fix the error talked about by agf. I find it a little amusing that I still get the same answer though.
2) I gotta start using less languages to do this in. If I make a mistake I've gotta change & test three different versions.
3) Times ( as requested by Caleb):
Haskell: 0.004s
Python: 0.205s
Perl : 0.136s
4) More props for zloyrusski for the division algorithm.

Syndicate content