tags:

views:

115

answers:

2

Given a string of characters as input, without using regular expression or pattern matching, how to get the output, if the characters matches aaa should output 1 and if the characters matches aBa should output 2. (Note: Should not re-process characters so as to output both “1” and “2” when processing the same input)

So for example:

given 'aaBaBaaaBaaa' it should output 211

given 'aaaBaBaaaaBBaBaBa' it should output 1212

Thanks in advance.

+4  A: 

without using regular expression or pattern matching

#input = 'aaBaBaaaBaaa'
input = 'aaaBaBaaaaBBaBaBa'
codes = {'aaa' => 1, 'aBa' => 2}
patterns = codes.keys
output = []

current = 0
length = input.length

while current <= length - 1
    is_find = false
    patterns.each do|pattern|
        len = pattern.length
        if input[current, len] == pattern
            output << codes[pattern]
            current += len
            is_find = true
            break
        end
    end

    current += 1 if !is_find
end

p output
aaz
p output.join - he wanted a string ;) Nicely done though, solved the problem and then added the flexibility of adding new "codes" of any length.
Beanish
Excellent. How about the same in JAVA?
satynos
The algorithm is pretty solid, so the solution in Java is pretty much the same. Biggest changes are you lose access to Ruby's each iterator, and hashes aren't part of the default types. There are many ways around that. For starters, you could import java.util.HashMap, or you could redefine the codes hash as an array of code objects.
EmFi
After reviewing the code again, and the given conditions of not using regular expression or pattern matching, I believe although the solution is good it doesn't satisfy all the conditions. Isn't (if input[current, len] == pattern) considered as pattern matching?
satynos
@satynos It is only pattern matching only if you also consider, if "Hello" == "Hello" to also be pattern matching. And if you do, then your requirements can't be satisfied.
he_the_great
`pattern` is just a variable name. Substitute `code` or `str` if it makes you feel better.
glenn jackman
thanks for all the excellent feedback guys.
satynos
+6  A: 

Sounds like you want a state machine:

require 'statemachine'

state_machine = Statemachine.build do
  trans :_, :a, :a
  trans :_, :B, :_
  trans :a, :a, :aa
  trans :a, :B, :aB
  trans :aa, :a, :_, 'print 1'
  trans :aa, :B, :aB
  trans :aB, :a, :_, 'print 2'
  trans :aB, :B, :_
end

"aaBaBaaaBaaa".each_char do |i|
  state_machine.process_event(i)
end

state_machine.reset
puts

"aaaBaBaaaaBBaBaBa".each_char do |i|
  state_machine.process_event(i)
end
kejadlen
Awesome solution, you should have deserved the accept!
Adrian
+1 Nicely done!
z5h