Friday, February 06, 2009

Project Euler - Problem 3

Problem 3 reads as follows:

"The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143 ?"


This one is easy, thanks to Ruby's mathn library and the prime_division method. You can read more about it and even see the source code for the method at the documentation site.

All we have to do is require the mathn library, which comes with Ruby by default. I checked on my Windows and Mac OSX machines. Then call the prime_division method on the integer. That creates a multidimensional array.

For each item in the array, there are 2 numbers. The first is the actual prime number and the second relates how many times that prime number can be factored out. So, for the number 9, you would end up with [3,2].

Lastly, we grab the last prime number in the array for the answer.

require 'mathn'
primeArray = 600851475143.prime_division
puts primeArray[primeArray.length - 1][0]

Monday, February 02, 2009

Calling XSLT templates with predicates..

This is just a mental note for me, so hopefully I won't forget it in the future.

If you have an XSLT template that limits the result set with a predicate, you must call that template with the predicate intact. Here's an example:

Wrong:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="Items">
<xsl:apply-templates select="Item" />
</xsl:template>

<xsl:template match="Item[status='archived']">
<xsl:element name="title">
<xsl:value-of select="title" />
</xsl:element>
</xsl:template>

</xsl:stylesheet>


Right:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="Items">
<xsl:apply-templates select="Item[status='archived']" />
</xsl:template>

<xsl:template match="Item[status='archived']">
<xsl:element name="title">
<xsl:value-of select="title" />
</xsl:element>
</xsl:template>

</xsl:stylesheet>


I am ashamed at how long it took me to figure out what I was doing wrong. ;)

Friday, January 30, 2009

Project Euler - Problem 2

Alright, on to problem 2. "Find the sum of all the even-valued terms in the [Fibonacci] sequence which do not exceed four million." This one is pretty easy. Just loop through all the numbers in the Fibonacci sequence up to four million. The largest actual number in the sequence that does not exceed 4 million is 3,524,578. Here's is my humble attempt at a solution:

x1,x2 = 0, 1
ans = 0

# While x1 is less than or equal to 4 million
while(x1 <= 4000000)

# Find the next number in the Fibonacci sequence
x1+=x2
x1,x2= x2,x1

# If that number is even, then add it to the running sum.
if(x1%2 == 0) then ans += x1 end
end

puts ans

Tuesday, January 27, 2009

Ruby FTP Scanner

I was recently given the task to recursively scan an ftp directory and generate a list of all the files in all the folders in that directory. Here's a little ruby script that I wrote to accomplish the scan.

require 'net/ftp'

# The scanDir function searches through the directory that is passed in as an argument. If that directory has any sub directories,
# then the function calls itself to handle them.
def scanDir(ftp, dir)

ftp.chdir(dir)
puts ftp.pwd + "/."

entries = ftp.list('*')

entries.each do |entry|

if entry.split[2] == "<dir>" then
# If this is a directory then call scanDir to scan it.
scanDir(ftp, entry.split.last)
else
# else, print out the name of the file.
puts ftp.pwd + "/" + entry.split.last
end

end

# Since we dipped down a level to scan this directory, lets go back to the parent so we can scan the next directory.
ftp.chdir('..')
end

# Determine if the user is asking for help.
helpArgs = ["h", "-h", "/h", "?", "-?", "/?"]
if helpArgs.index(ARGV[0]) != nil || ARGV.length == 0 then

puts "FTPSCAN:"
puts " The ftpscan script recursively scans an ftp directory and returns a list of all the files and directories contained therein."
puts
puts " USAGE:"
puts " ruby ftpscan.rb [ftpserver] [username] [password]"
puts
puts " EXAMPLE:"
puts " ruby ftpscan.rb tsftp.turner.com steveo stevepass"
puts

else

# Get the command line arguments
server, user, pass = ARGV

# Connect to the FTP Server
ftp = Net::FTP.new(server)

# Login to the FTP account
ftp.login(user, pass)

# Recursively scan the directories.
scanDir(ftp, '')

# Close the FTP connection.
ftp.close

end


Enjoy!

Friday, January 23, 2009

Project Euler - Problem 1

I found a great site called Project Euler. The site explains it best:

"Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems.

The motivation for starting Project Euler, and its continuation, is to provide a platform for the inquiring mind to delve into unfamiliar areas and learn new concepts in a fun and recreational context."

I've been using Ruby as an alternative to PowerShell, since it runs on the miriad of systems that I am exposed to in my current position. I figured that this would be a good way to increase my Ruby coding skills and have a little fun solving some puzzles at the same time. From time to time, I'll post my solution to a problem. I'm still learning, so if you have suggestions, I would love to hear your constructive criticism.

Problem 1:
Find the sum of all the multiples of 3 or 5 below 1000.

Solution:

ans=0

(1...1000).each{ |i|
  if( i%3 == 0 || i%5 == 0 ) then
    ans += i
  end
}

puts ans


I doesn't seem very "Ruby-ish" but it works.