Archive for the ‘Ruby’ Category

Ruby: Watch a file for changes

Monday, December 28th, 2009

I was writing a script that does numerical differentiation, which required a lot of tweaking. I thought it would be quite cool to be able to see the results of the script automatically, whenever I made a change to the script, without having to run it again.

So I quickly wrote this up:

require 'digest/md5'
 
$md5 = ''
 
def watch(file, timeout, &cb)
  $md5 = Digest::MD5.hexdigest(File.read(file))
  loop do
    sleep timeout
    if ( temp = Digest::MD5.hexdigest(File.read(file)) ) != $md5
      $md5 = temp
      cb.call(file)
    end
  end
end

That is the main function. It will wait for a fixed amount of time, get a hash of the file and compare it with a previous version. If it has changed, then it executes the callback which you have specified.

Here is an example of how it can be used:

$num = 0
watch '../num_diff.rb', 1 do |file|
  puts "\e[31m MODIFIED: \e[0m \e[34m #{file} \e[0m (#{$num}, #{Time.now})"
  puts "\e[32m     -- EXECUTING -- \e[0m"
  puts
  puts `ruby #{file}`
  puts
  puts "\e[32m -- FINISHED EXECUTION -- \e[0m"
  puts
  $num += 1
end

This is what the output looks like:
Screenshot

Implementation of Octave’s diag in Ruby

Sunday, December 13th, 2009

GNU Octave has a diag function which behaves like this:

octave> diag([1,2,3])
ans =
 
Diagonal Matrix
 
   1   0   0
   0   2   0
   0   0   3

To be more clear,
 diag \left( \begin{array}{ccc} 1 & 2 & 3 \end{array} \right) = \left(   \begin{array}{ccc}  1 & 0 & 0 \\ 0 & 2 & 0 \\ 0 & 0 & 3    \end{array}    \right)

Here is an implementation of the diag function in Ruby:

# Create a diagonal matrix given a vector (or an array), 
# placing the entries of the vector on the diagonal of 
# the matrix.
# For example, diag([1,2,3]) would give:
# [ 1 0 0 ]
# [ 0 2 0 ]
# [ 0 0 3 ]
# That would actually be a 2D matrix like this 
#  [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
# The array returned has to be converted to a matrix by doing 
#  Matrix[ *diag(vector) ]
def diag(vector)
  n = vector.size
  matrix = []
  n.times do |i|
    matrix << Array.new(n) { |x| (x == i) ? vector[x] : 0 }
  end
  matrix
end

You can also get the code in this gist; use it as you wish.

Project Euler Problem 40

Thursday, October 29th, 2009

Project Euler Problem 40

In my opinion, this was the easiest problem so far. The brute-force method is easy to implement and runs very fast.

This is the code:

$fraction = ''
 
1.upto(1000000) do |i|
  $fraction << i.to_s
end
 
def d_(n)
  $fraction[n-1].to_i
end
 
puts d_(1) * d_(10) * d_(100) * d_(1000) * d_(10000) * d_(100000) * d_(1000000)

It runs in slightly lesser than one second.

The last line isn’t very Ruby-ish because I copied it from the problem description page, because I’m too lazy to write it myself. That’s also why I have a d_(n) function.

Project Euler Problem 21 (Ruby)

Thursday, September 24th, 2009

If you intend to solve the problem on your own, I wouldn’t recommend reading any further.

Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).
If d(a) = b and d(b) = a, where a \neq b, then a and b are an amicable pair and each of a and b are called amicable numbers.

For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.

Evaluate the sum of all the amicable numbers under 10000.

(Problem 21 – Project Euler)

def d(n)
  total = 0
  1.upto n/2 do |i|
    if (n % i) == 0
      total += i
    end  
  end
  total
end
 
amicable_sum = 0
 
10000.times do |a|
  b = d(a)
  if d(b) == a && b > a
    amicable_sum += a + b
  end
end
 
puts amicable_sum

My version of d(n) isn’t as efficient as the one in the PDF you get after solving the problem, but it gets the job done.

Running it takes around 8.5 seconds on my machine. That’s not too bad for ~20 lines of code.

Zenity.rb

Tuesday, May 12th, 2009

Zenity is a command line based tool that helps shell scripts display GTK dialog boxes as a more interactive way to display error messages, get user input and other stuff like that. (more…)

Getting a Method to Accept an Arbitrary Number of Arguments in Ruby

Saturday, May 9th, 2009

(more…)

Very Simple Metronome in Ruby

Thursday, April 23rd, 2009

A metronome is basically something that beeps periodically, indicating the exact tempo of some music. I wanted one for my guitar practice, but the only one in Ubuntu’s repos (GTick) wouldn’t work, so I wrote this up. (more…)

Implemeting HQ9+ in 10 lines of Ruby

Friday, April 3rd, 2009

HQ9+ is a excessively simple esoteric programming language. It has only four commands:
H: Print “Hello, World!”
Q: Prints the contents of the program onto the screen
9: Print the canonical lyrics of the song, “99 bottles of beer”.
+: Increment the accumulator

Here’s the entire implementation:

1
2
3
4
5
6
7
8
9
10
def hq9(src)
  src.downcase.split('').each do |i|
    case i
      when 'h'; puts "Hello, World!"
      when 'q'; puts src
      when '9'; 99.downto(0) { |b| puts "#{b==0?'No more b':"#{b} B"}ottle#{'s'if b!=1} of beer on the wall, #{b==0?'No more':b} bottle#{'s'if b!=1} of beer.#{b==0?"nGo to the store and buy some more, 99 bottles of beer on the wall.":"nTake one down and pass it around, #{b-1} bottle#{'s'if b!=2} of beer on the wall.nn"}" }
      when '+'; $i = $i ? $i + 1 : 0;
    end
  end
end

Note: I got the lyric printing code from here.

Project Euler #48 in Ruby

Thursday, April 2nd, 2009

Note: Don’t look at the code if you intend to solve the problem later.

Problem 48 – Project Euler

I was surprised at how easy this turned out to be. It is really, really simple because with Ruby, the only limit on how big an integer can get is how much memory you have available. Here’s my solution:

# Project Euler, 48
start = Time.now
 
n = 1
sum = 0
 
1000.times do
  sum += n**n
  n += 1
end
 
puts sum.to_s[-10..-1]
puts "Time taken: #{Time.now-start}"

It takes a fifth of a second on my laptop running Ruby 1.9.1.

Ruby Style Blocks in Javascript

Monday, February 23rd, 2009

Javascript is a really great language when it comes to flexibility. It is possible to pass code to a function the way you can do with Ruby, albeit a bit more verbose. This is made possible by the fact that javascript allows you to pass a function as one of the parameters of a function. (more…)