Inserción de aprendizaje Ordenar en Ruby

Acabo de comenzar el curso Introducción al algoritmo de MIT a través del material publicado en línea. Junto con el curso, también he decidido aprender / mejorar mis habilidades Ruby mediante la encoding de los algoritmos que contiene.

Estoy en el primer algoritmo dado, que es Insertion Sort, y tengo el siguiente código escrito, pero obtengo este error cuando lo ejecuto:

insertionsort.rb: 5: en `> ‘: comparación de Fixnum con nil failed (ArgumentError)

def insertionsort(num) for j in 2..num.length key = num[j] i = j - 1 while i > 0 and num[i] > key num[i+1] = num[i] i = i - 1 end num[i+1] = key end puts num end numbers = [23,34,46,87,12,1,66] insertionsort(numbers) 

Estoy seguro de que es un problema bastante básico, pero no puedo entender qué es en este momento. Cualquier ayuda o consejo sería muy apreciado.

Estás sobrepasando los límites de tu matriz. El ejemplo que se le dio fue asumiendo matrices de 1 indización, pero las matrices en ruby ​​están 0 indexadas. La primera línea debe ser

 for j in 1...num.length 

La otra respuesta es correcta que va más allá del final de los valores en la matriz porque está basada en 0 pero hay otros cambios que necesita hacer para que el algoritmo funcione:

 for j in 1..(num.length - 1) 

y

 while i >= 0 and num[i] > key 

Solo un complemento menor al otro, excelentes respuestas:

Creo que ahora se acepta generalmente que la indexación de origen 0 tiene una serie de ventajas prácticas y empíricas sobre la indexación de 1 origen. La experiencia sugiere que simplemente “funciona mejor” y es menos propenso a errores.

Es por eso que muchos progtwigdores enumeran las cosas desde cero y sorprenden a las personas “normales”.

Si bien este ejercicio es realmente genial, de acuerdo con esta excelente publicación de blog, probablemente debas evitar escribir tu propio estilo y confiar en el Array :: sort integrado

http://philcrissman.com/2010/07/18/how-not-to-write-sorting-algorithms-in-ruby/

La implementación más simple es algo como esto:

 def insertion_sort(arr) for i in (1...(arr.size)) if arr[i-1] > arr[i] i.downto(1) do |el| if arr[el] < arr[el-1] arr[el-1], arr[el] = arr[el], arr[el-1] end end end end arr end arr = [5, 2, 4, 6, 1, 3] p insertion(arr) 

Nota: para mejorar la eficiencia del algoritmo, puede usar la búsqueda binaria para comparar elementos.

¿Qué es Insertion Sort?