Project Euler : Problem 39 in Ruby
I had an easy time with this one, which makes me feel a lot better about all the ones I had problems with!
No fancy-pants recursion or math short-cuts here, just a straight forward logic problem. The only "trick" here is to realize that since a <e; b < c, we only need to check values of a and b up to 499.
I'm sure you could whittle that number down by crunching the numbers, but it's good enough for me!
For which value of p 1000, is the number of solutions maximised?
counts = {}
counts.default = 0
(1..499).each do |a|
(a..499).each do |b|
break if a + b > 500
c = Math.sqrt(a**2 + b**2)
next unless c.denominator == 1
counts[a + b + c] += 1
end
end
sorted = counts.sort { |a, b| a[1] <=> b[1] }
puts sorted.last[0]
Project Euler : Problem 38 in Ruby
40 problems down, 10 more till level 2!
The real trick here is to cut down on the numbers you check. Since the problem gives you 918273645 as an example we know the answer must be greater than or equal to it...meaning we only need to check digits that start with 9!
I don't actually do it because I couldn't figure out an elegant way to do, but it runs in just a few milliseconds so it's fast enough in my book.
Another important factor to note is that you only need to check numbers up to 9_876 since this is the first 'half' of the largest pandigital possible.
Those two tricks will cut down the calculations you need to run to just a few thousand.
What is the largest 1 to 9 pandigital 9-digit number that can be formed as the concatenated product of an integer with (1,2, ... , n) where n 1?
def get_pandigital? n
nums = []
(1..9).each do |digit|
nums += (n * digit).to_s.split ''
return 0 if nums.size != nums.uniq.size || nums.include?('0')
return nums.join('').to_i if nums.size == 9
end
end
solution = 0
(9..9_876).each do |n|
# could do better by only looking at 9's!
result = get_pandigital? n
if result > solution
solution = result
end
end
puts solution
Check out all of my solutions on bitbucket!
Project Euler: Problem 37 in Ruby
It's been a while since I've done one of these, so I was afraid of being rusty but it worked out alright. I used the generator I made a while back to create the primes (pre-filled to the example given in the project) and used procs to take care of the truncation.
BAM!
The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.
Find the sum of the only eleven primes that are both truncatable from left to right and right to left.
load 'prime_generator.rb'
def prime? n, truncate
return false if !$primer.is_prime?(n)
return true if n < 10
prime? truncate.call(n), truncate
end
left = Proc.new { |n| n / 10 }
right = Proc.new { |n| n % 10**Math.log10(n).to_i }
$primer = Prime_Generator.new 3_797
n, sum, found = 0, 0, 0
while found < 11 do
if (n += 1) > 10 && prime?(n, left) && prime?(n, right)
found += 1
sum += n
end
end
puts sum
Also, I've finally moved my project euler solutions over to bitbucket. Long live Mercurial!
To uint, or not to uint
I like unsigned integers, always have. It's more correct, concise and expressive, you get more (positive) space out of it and you're preventing bugs by design. What's not to love?
Well...
I've been nooking CLR via C# and it's a fantastic read for anyone who wants to 'get serious' about .Net. The book's so crammed full of good information it's hard not to gush, but I digress.
I was nooking, you see, and I came across this recommendation:
"Use signed data types (such as Int32 and Int64 instead of unsigned numeric types such as UInt32 and UInt64) wherever possible."
Say it aint so!
Jeffrey Richter continues:
"This allows the compiler to detect more overflow/underflow errors. In addition, various parts of the class library (such as Array's and String's Length properties) are hard-coded to return signed values, and less casting is required as you move these values around in your code."
Casting is ugly, no argument there but I don't care much about the overflow/underflow errors. I generally don't enable overflow checking, there's no political statement here, it's just never come up.
And it still feels wrong for me to declare a value signed when I know that it shouldn't be.
(Richter recommends enabling checking for debug builds, and disabling for release. Sound advice!)
But here's real the kicker for me:
In addition, unsigned numeric types are not CLS-compliant.
Doh. I did a bit of searching to try and track down why it's not part of the CLS, and I found that Brad Abrams expresses it best in this post:
"The general feeling among many of us is that the vast majority of programming is done with signed types. Whenever you switch to unsigned types you force a mental model switch (and an ugly cast). In the worst cast you build up a whole parallel world of APIs that take unsigned types. The value of avoiding the '< 0' check is not worth the inclusion of generics in the CLS"
Alright, I give in. I'm apparently in the minority, these guys are way smarter than I am, and it is easier, if not more concise. So it goes.
Goodbye for now uint, you'll always hold a positive place in my heart.
Just like Weezer:
Project Euler: Problem 35 in Ruby
I used my prime generator from Problem 27 for this one. It would have been faster to build the rotation into my generator, but it ran fine without it.
How many circular primes are there below one million?
require 'prime_generator'
primer = Prime_Generator.new 1_000_000
def is_rot_prime? primer, chars
chars.size.times do |i|
chars = Array.new(chars.size) { |i| chars[i - 1] }
return false if !primer.is_prime?(chars.join("").to_i)
end
true
end
count = 0
primer.stack.each do |n|
count += 1 if is_rot_prime? primer, n.to_s.split("")
end
# subtract 1 because "1" doesn't count
puts count - 1
Speaking of the rotation, the ruby array initialize methods and negative indexers make it a cinch to rotate. How cool is this?
chars = Array.new(chars.size) { |i| chars[i - 1] }


























