2010-01-10 15 views
6

tengo la siguiente función de Python para encontrar de forma recursiva todas las particiones de un conjunto:función Traducir para encontrar todas las particiones de un conjunto de Python Ruby

def partitions(set_): 
    if not set_: 
     yield [] 
     return 
    for i in xrange(2**len(set_)/2): 
     parts = [set(), set()] 
     for item in set_: 
      parts[i&1].add(item) 
      i >>= 1 
     for b in partitions(parts[1]): 
      yield [parts[0]]+b 

for p in partitions(["a", "b", "c", "d"]): 
print(p) 

Puede alguien ayudarme a traducir esto en Ruby? Esto es lo que tengo hasta ahora:

def partitions(set) 
    if not set 
    yield [] 
    return 
    end 
    (0...2**set.size/2).each { |i| 
    parts = [Set.new, Set.new] 
    set.each { |item| 
     parts[i&1] << item 
     i >>= 1 
    } 
    partitions(parts[1]).each { |b| 
     yield [parts[0]] << b 
    } 
    } 
end 

p partitions([1, 2, 3, 4].to_set) 

me sale el error "LocalJumpError: no determinado bloque". Supongo que esto se debe a que las funciones de rendimiento funcionan de manera diferente en Python y Ruby.

+0

¿Dónde encontraste las particiones función de Python? Para contextualizar y aprender, me gustaría leer la entrada del blog o el capítulo en el que la encontraste. Gracias. –

Respuesta

4
#!/usr/bin/ruby1.8 

def partitions(set) 
    yield [] if set.empty? 
    (0 ... 2 ** set.size/2).each do |i| 
    parts = [[], []] 
    set.each do |item| 
     parts[i & 1] << item 
     i >>= 1 
    end 
    partitions(parts[1]) do |b| 
     result = [parts[0]] + b 
     result = result.reject do |e| 
     e.empty? 
     end 
     yield result 
    end 
    end 
end 

partitions([1, 2, 3, 4]) do |e| 
    p e 
end 

# => [[1, 2, 3, 4]] 
# => [[2, 3, 4], [1]] 
# => [[1, 3, 4], [2]] 
# => [[3, 4], [1, 2]] 
# => [[3, 4], [2], [1]] 
# => [[1, 2, 4], [3]] 
# => [[2, 4], [1, 3]] 
# => [[2, 4], [3], [1]] 
# => [[1, 4], [2, 3]] 
# => [[1, 4], [3], [2]] 
# => [[4], [1, 2, 3]] 
# => [[4], [2, 3], [1]] 
# => [[4], [1, 3], [2]] 
# => [[4], [3], [1, 2]] 
# => [[4], [3], [2], [1]] 

Lo que es diferente:

  • El guardia llama set.empty? en lugar de (implícitamente) probando para set.nil?
  • dejar de lado el .Cada al llamar particiones
  • Uso matriz en lugar de Conjunto
  • Filtrar conjuntos vacíos fuera de la dado resultado
+0

¡Muchas gracias! – tom

0

Deberá pensar en Ruby's yield como una llamada a una operación definida por el usuario.

def twice 
    yield 
    yield 
end 

twice { puts "Hello" } 

De modo que cada vez que su código genere un valor, se llamará a una función de procesamiento para este elemento.

partitions([1, 2, 3, 4].to_set) { |result| 
    # process result 
} 

Este código no genera una lista en absoluto.

Cuestiones relacionadas