Author Archives: joe

About joe

.NET developer and board game geek located in the greater Atlanta region.

Project Euler: Problem 67 in Ruby

I guess my solution to #18 was good enough since it worked for #67 as well.

Problem #67

Find the maximum total from top to bottom of the triangle below:

input = # triangle goes here

tree = []
cache = []

input.split("n").each do |row|
  tree << []
  cache << []
  row.split("s").each do |i|
    tree.last << i.to_i
  end
end

def sum tree, cache, row, index, total

  if tree[row] == nil or tree[row][index] == nil
    return 0
  end

  if cache[row][index] != nil
    return total += cache[row][index]
  end
  
  left  = sum( tree, cache, row + 1, index, total )
  right = sum( tree, cache, row + 1, index + 1, total )

  cache[row][index] = [left, right].max + tree[row][index]

end

puts sum( tree, cache, 0, 0, 0 )

Ran pretty fast in 1.8.6

$ time ruby 18.rb
real	0m0.012s
user	0m0.008s
sys	0m0.004s

$ time ruby 67.rb
real	0m0.115s
user	0m0.104s
sys	0m0.012s

And a little worse in 1.9

$ time ruby1.9 18.rb
real	0m0.028s
user	0m0.016s
sys	0m0.008s

$ time ruby1.9 67.rb
real	0m0.116s
user	0m0.104s
sys	0m0.004s

Project Euler: Problem 18 in Ruby

I found this one to be very similar to problem #15, so it “clicked” pretty quickly. I basically just store the solutions so I don’t have to do any re-computing.

I saw a pretty slick method in the forums that made use of Ruby’s Enumerable module which I’ll have to give a go next time I run into something like this.

Problem #18

Find the maximum total from top to bottom of the triangle below:

input = # triangle goes here

tree = []
cache = []

input.split("n").each do |row|
  tree << []
  cache << []
  row.split("s").each do |i|
    tree.last << i.to_i
  end
end

def sum tree, cache, row, index, total

  if tree[row] == nil or tree[row][index] == nil
    return 0
  end

  if cache[row][index] != nil
    return total += cache[row][index]
  end
  
  left  = sum( tree, cache, row + 1, index, total )
  right = sum( tree, cache, row + 1, index + 1, total )

  cache[row][index] = [left, right].max + tree[row][index]

end

puts sum( tree, cache, 0, 0, 0 )

When is a Struct not a Struct?

I’ve run into an annoying problem trying to get some older java code working under ColdFusion 8. The problem method accepts two arguments, java.util.Hashmap and java.util.Vector, but the signature isn’t matching.

Here’s the set up:

<cfset classpath = [
  CreateObject( "java","java.net.URL" ).init( "file:#cfusion#" ),
  CreateObject( "java","java.net.URL" ).init( "file:#testfile#" )
] />

<cfset loader  = CreateObject( "java","java.net.URLClassLoader" ).Init(
  classpath
) />
<cfset example = loader.LoadClass( "ProblemExample" ).NewInstance() />

<cfset cfarray  = ArrayNew(1) />
<cfset cfstruct = StructNew() />

<cfdump var="#example#" />

My sample method looks good…

public void originalMethod(java.util.Hashtable h,java.util.Vector v){}

The dump looks greatdump

But I’m getting a “method was not found” error

I did a bit of googling, and found a great post about the differences between CF7 and CF8 structs and arrays. Perfect…right?

I wrote a little test method to accept a coldfusion.util.FastHashtable:

public void takeFastHashtable(coldfusion.util.FastHashtable fh){}
method was not found"

I wrote a little script, to see what I was dealing with:

<cfoutput>
  #cfstruct.getClass().getName()# == #example.inspect(cfstruct)#
  => #cfstruct.getClass().getName() EQ example.inspect(cfstruct)#
</cfoutput>

using

public String inspect( Object o ) {
  return o.getClass().getName();
}

And my output was as expected:
coldfusion.runtime.Struct == coldfusion.runtime.Struct => YES

So I wrote a up a simple test method for coldfusion.runtime.Struct:

public void testStruct(coldfusion.runtime.Struct s){}
<cfset example.testStruct(s) />

You guessed it:

"method was not found"

Okay….let’s try casting….

public coldfusion.runtime.Struct castAsStruct(Object o) {
  return (coldfusion.runtime.Struct) o;
}

This time the error’s a little different…

coldfusion.runtime.Struct cannot be cast to coldfusion.runtime.Struct
W T F

Granted, I’m trying to use underlying undocumented code, and I’m no Java expert, but there’s something here that’s not adding up. Is this a bug? Am I missing something stupid? At this point I’ll be moving on to alternative solutions, but any help would be still greatly appreciated.

You can download some sample code I’ve been using, just make sure to compile with the appropriate classpath for your environment.

Here’s my command

javac ProblemExample.java -classpath /opt/coldfusion8/lib/cfusion.jar

Project Euler: Problem 17 in Ruby

I overrode the Fixnum class, and there’s a teensy bit of recursion going on, but over all it was really simple. The hardest part was writing out all the unique numbers for my word hash.

Problem #17

If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?

words = {
  1 => "one",
  2 => "two",
  3 => "three",
  4 => "four",
  5 => "five",
  6 => "six",
  7 => "seven",
  8 => "eight",
  9 => "nine",
  10 => "ten",
  11 => "eleven",
  12 => "twelve",
  13 => "thirteen",
  14 => "fourteen",
  15 => "fifteen",
  16 => "sixteen",
  17 => "seventeen",
  18 => "eighteen",
  19 => "nineteen",
  20 => "twenty",
  30 => "thirty",
  40 => "forty",
  50 => "fifty",
  60 => "sixty",
  70 => "seventy",
  80 => "eighty",
  90 => "ninety"
}

class Fixnum

  def to_english words
    str = ""
    if self >= 100
      str = "#{words[(self / 100)]}hundred"
      if self % 100 > 0
        str = "#{str}and#{(self % 100).to_english(words)}"
      end
    elsif self > 20
      str = '#{words[(self / 10) * 10]}#{words[ self % 10 ]}'
    elsif self == 1000
      str = 'onethousand'
    else
      str = words[self]
    end
    str
  end

end

total = 0

(1..1000).each do |i|
  total += i.to_english(words).size
end

puts total

Project Euler: Problem 15 in Ruby

I spent a lot of time drawing this on paper trying to figure out an equation behind it before I gave up and went the recursive route. There was an obvious pattern behind it…but I’m not a mathematician. I could see from the traces that I could store information about exhausted routes to save a lot of cycles, so I’m happy with my solution.

Problem #15

How many routes are there through a 20 x 20 grid? (no backtracking)

def move grid, x, y
  size = grid.size - 1

  if x > size or y > size
    return 0
  end

  if x == size and y == size
    return 1
  end

  if grid[x][y] != nil
    return grid[x][y]
  end

  grid[x][y] = move(grid, x + 1, y) + move(grid, x, y + 1)
  
end

size = ARGV[0].to_i
grid = Array.new(size + 1) do |i|
  i = Array.new(size + 1)
end

puts move(grid, 0, 0)

Project Euler: Problem 14 in Ruby

Straight up brute force was too slow, so I would store the sequence counts for numbers I’d already seen in a hash table.

Problem #14

The following iterative sequence is defined for the set of positive integers:

n → n/2 (n is even)
n → 3n + 1 (n is odd)

Which starting number, under one million, produces the longest chain?

def advance heap, n, count

  if heap.has_key? n
    return heap[n] + count
  end

  if (n & 1) == 0
    return advance(heap, n / 2, count + 1)
  end

  advance(heap, 3 * n + 1, count + 1)

end

heap = Hash[0,0,1,1]
answer, max = 1, 1

1_000_000.times do |i|

  heap[i] = advance(heap, i, 1)

  if heap[i] > max
    max = heap[i]
    answer = i
  end
  
end

puts answer 

Project Euler: Problem 13 in Ruby

Just finished up Problem #13. Straight up brute force ran really well, but I figured I could save some cycles by only adding up the last 11 digits.

I ran this and #25 through ruby 1.8.6 and 1.9.1 and was suprised to see that it ran much slower in the newer version. Everything else I’ve tried has run much better.

Here are some numbers I found to be pretty indicative. Bummer.

$ time ruby 13.rb

real	0m0.009s
user	0m0.008s
sys	0m0.000s

$ time ruby1.9 13.rb

real	0m0.026s
user	0m0.020s
sys	0m0.004s

Problem 13

Work out the first ten digits of the sum of the following one-hundred 50-digit numbers.

input = File.new("files/13.txt", "r")
total = 0

input.each do |i|
  total += i.slice(0..10).to_i
end

puts total.to_s.slice(0,10)

Project Euler: Problem 25 in Ruby

Skipping around a bit, I saw that #25 looked pretty easy. It was. I saw in the forums that someone had used binary search and a calculator which I thought was pretty clever, but mine was just brute force.

Problem #25

What is the first term in the Fibonacci sequence to contain 1000 digits?

Solution

max  = 10 ** 999
a, b, i = 1, 1, 2

while b < max
  i += 1
  a, b = b, b + a
end

puts i