¿Cómo lograría lo siguiente? Tome una matriz de rangos y reste otra matriz de rangos de ella.

Por ejemplo:

arr0 = [[0,50],[60,80],[100,150]] # 0-50, 60-80, etc.

arr1 = [[4,8],[15,20]] # 4-8, 15-20, etc.

# arr0 - arr1 magic

result = [[0,3],[9,14],[21,50],[60,80],[100,150]] # 0-3, 9-14, etc.

¿Cuál es la forma más limpia y eficiente de hacer esto en Ruby?

2
Artem Kalinchuk 13 dic. 2016 a las 19:54
1
No creo que haya una sola línea impulsada por stdlib aquí
 – 
Sergio Tulentsev
13 dic. 2016 a las 19:55
Esto necesita MUCHAS pruebas / ejemplos. Especialmente para casos de esquina extraños. Pero parece interesante. Si fuera un ejercicio sobre ejercicio, lo resolvería :)
 – 
Sergio Tulentsev
13 dic. 2016 a las 19:57
Tengo curiosidad por saber cómo sería una solución simple sin todos los casos extremos.
 – 
Artem Kalinchuk
13 dic. 2016 a las 19:58
1
Bueno, pruébalo y tal vez lo averigües. :)
 – 
Sergio Tulentsev
13 dic. 2016 a las 19:59
1
Necesitaba lo mismo, solo en golang. (también los rangos pueden tener "valor" en mi caso, pero básicamente no es más que el mismo rango repetido varias veces) Vea el código en esta esencia: gist.github.com/petrkotek/317dbcf6a73387682bc8d899b09c36df --- básicamente la idea es encontrar todos los puntos de ruptura (desde y hasta valores) y diferenciarlos; luego, itera sobre los puntos de ruptura ordenados y genera la salida :) ¡Espero que ayude!
 – 
petrkotek
30 dic. 2016 a las 18:15

1 respuesta

La mejor respuesta

Esta es una solución deliberadamente ingenua. No es eficiente, pero fácil de comprender y bastante breve.

Deconstruye arr0 en una lista de números:

n1 = arr0.flat_map { |a, b| (a..b).to_a }
#=> [0, 1, ..., 49, 50, 60, 61, ..., 79, 80, 100, 101, ..., 149, 150]

Lo mismo para arr1:

n2 = arr1.flat_map { |a, b| (a..b).to_a }
#=> [4, 5, 6, 7, 8, 15, 16, 17, 18, 19, 20]

Luego, reste n2 de n1 y vuelva a combinar números consecutivos:

(n1 - n2).chunk_while { |a, b| a.succ == b }.map(&:minmax)
#=> [[0, 3], [9, 14], [21, 50], [60, 80], [100, 150]]
3
Stefan 13 dic. 2016 a las 20:33