### Synchronising two directory trees - tree-sync 2.4

tree-sync.pl has had a little update thanks to a contribution from Dave Stafford.

• Added option 'diff' to view only changes

• Added option 'ignore' to exclude certain extensions

• Added option 'brief' to remove src/dest directories in report view to make cleaner output

In the 2.4 release I've also added the 'force' option to control read-only file handling.

tree-sync.pl is a bit of a geeky tool, suitable for cases where you want detailed control over a file-based copy/mirror/backup process from the command-line. There are many flashier solutions available these days, but if tree-sync scratches your itch - go for it!

tree-sync.pl continues to be available on CPAN, but from the 2.4 release I have moved the source to github. If you have changes to suggest or bugs to fix, please go ahead and join this project.

### Rolling Project Euler on Ruby

I first heard about Project Euler last week on the stackoverflow podcast. Michael Pryor (fogcreek co-founder) makes a quick side reference in discussion with Joel Spolsky, Jeff Atwood and the rest of the SO team.

Well I checked it out last week, got hooked and spent most of the weekend earning my "level 1" badge;-)

Aside from dusting off some long-forgotten and arcane knowledge from my youth, I found it a fantastic opportunity to stretch my fundamental ruby chops. In fact, I'd recommend a few questions at Project Euler as a right-of-passage whenever you are learning a new programming language.

I've only been using ruby for a year or so, and in that time thought I had picked up a fair bit. But I was still able to amaze myself at just how many of the problems were knocked over in just 1 or 2 lines with a bit of duck punching and liberal use of blocks with Enumerables.

I'm late to the Project Euler craze, so you will already find many people posting hints for specific questions if you just google. I thought I'd share some of the "common code" I've been building up as I go through the questions.

I put a recent copy of the source up on github for anyone who is interested (MyMath.rb), but what follows a sampling of some of the more interesting pieces.

First thing you will note is that I have written all these "common" routines as extensions to some of the fundamental classes in the ruby library: Integer, Array, String.

It doesn't have to be this way, and for less trivial activities you might be right to be concerned about messing with the behaviour of the standard classes. Maybe I'm still enjoying my ruby honeymoon period, but I do get a thrill out of being able to write things like

1551.palindrome?=> true

## Integer Extensions

It's just so easy to code up simple calculation and introspection routines..
class Integer  # @see project euler #15,20,34  def factorial    (2..self).inject(1) { |prod, n| prod * n }  end  # sum of digits in the number, expressed as a decimal  # @see project euler #16, 20  def sum_digits    self.to_s.split('').inject(0) { |memo, c| memo + c.to_i }  end  # num of digits in the number, expressed as a decimal  # @see project euler #25  def num_digits    self.to_s.length  end    # tests if all the base10 digits in the number are odd  # @see project euler #35  def all_digits_odd?    self.to_s.split('').inject(0) { |memo, s| memo + ( s.to_i%2==0 ? 1 : 0 ) } == 0  end    # generates triangle number for this integer  # http://en.wikipedia.org/wiki/Triangle_number  # @see project euler #42  def triangle    self * ( self + 1 ) / 2  endend

Prime numbers feature heavily on Project Euler, and I think calculating a prime series was my first lesson on why you can't brute-force everything;-) Enter the Sieve of Eratosthenes and related goodness..
class Integer   # http://en.wikipedia.org/wiki/Prime_factor  # @see project euler #12  def prime_factors    primes = Array.new    d = 2      n = self          while n > 1     if n%d==0        primes << d        n/=d      else        d+=1      end    end    primes  end    # http://en.wikipedia.org/wiki/Divisor_function  # @see project euler #12  def divisor_count    primes = self.prime_factors    primes.uniq.inject(1) { |memo, p| memo * ( ( primes.find_all {|i| i == p} ).length + 1) }  end    #  # @see project euler #12, 21, 23  def divisors    d = Array.new    (1..self-1).each { |n| d << n if self % n == 0 }    d  end  # @see project euler #  def prime?    divisors.length == 1 # this is a brute force check  end    # prime series up to this limit, using Sieve of Eratosthenes method  # http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes  # @see project euler #7, 10, 35  def prime_series    t = self    limit = Math.sqrt(t)    a = (2..t).to_a    n = 2    while (n < limit) do      x = n*2      begin        a[x-2]=2        x+=n      end until (x > t )      begin        n+=1      end until ( a[n-2] != 2 )    end    a.uniq!  end  # @see project euler #23  def perfect?    self == divisors.sum  end  # @see project euler #23  def deficient?    self > divisors.sum  end  # @see project euler #23  def abundant?    self < divisors.sum  endend

Next we visit the Collatz conjecture and an interesting routine to make numbers "speak english"..
class Integer       # http://en.wikipedia.org/wiki/Collatz_conjecture  # @see project euler #14  def collatz_series    a = Array.new    a << n = self    while n > 1      if n % 2 == 0        n /= 2      else        n = 3*n + 1      end      a << n    end    a    end  # express integer as an english phrase  # @see project euler #17  def speak    case    when self <20      ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",       "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" ][self]    when self > 19 && self < 100       a = ["twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"][self / 10 - 2]      r = self % 10      if r == 0        a      else        a + "-" + r.speak      end    when self > 99 && self < 1000      a = (self / 100).speak + " hundred"      r = self % 100      if r == 0        a      else        a + " and " + r.speak      end          when self > 999 && self < 10000      a = (self / 1000).speak + " thousand"      r = self % 1000      if r == 0        a      else        a + ( r <100 ? " and " : " " ) + r.speak      end          else      self    end  endend