Práctica: Ordenar por Calificaciones

Se tiene un fichero de entrada con calificaciones de alumnos como el que sigue:
Ferrer Pérez, Eduardo & 9'6\\
García  García, Laura & 7'5 \\
García Medina, Anai & 6'5\\
García Rodríguez, Pedro & 7'2\\
González del Castillo, Jorge & 5'0\\
Hernández Pérez, Daniel & 5'0\\
Marrero Díaz, Jose Antonio & 8'0\\
Marrero Piñero, Sergio & 7'2\\
Padrón Padrón, Adolfo & 5'0\\
Pedrín Ruiz, Ana & 9'6\\
Pedrínez Pérez, Ignacio & 7'5\\
Piñero Piñero, Antonio & 5'3\\
Pérez García, Adolfo & 9'5\\
Pérez González, Germán & 5'0\\
Pérez Pedrínez, Maria & 5'0\\
Ramos Ramos, Ignacio & 5'0\\
Rodríguez González, Andrés & 10'0\\
Rodríguez Rodríguez, Jorge & 9'2\\
Se pide escribir un programa que muestre el listado de alumnos ordenados en orden decreciente de calificaciones.

Sugerencias:

  1. Puede leer el fichero completo en un array usando readlines:
    >> f = File.open('notas')
    => #<File:notas>
    >> x = f.readlines
    => ["Ferrer P\303\251rez, Eduardo & 9'6\\\\\n", ... , "Rodr\303\255guez Rodr\303\255guez, Jorge & 9'2\\\\\n"]
    >> puts x[-1]
    Rodríguez Rodríguez, Jorge & 9'2\\
    => nil
    
  2. Ahora deberá construir un hash indexado en los nombres de los alumnos y cuyos valores sean las calificaciones:
    >> y = x.map { |alu| alu =~ /(.*)\s+\&\s+(\d+'\d*)/;  [$1, $2] }
    => [["Ferrer P\303\251rez, Eduardo", "9'6"], ... , ["Rodr\303\255guez Rodr\303\255guez, Jorge", "9'2"]]
    >> puts y[-1]
    Rodríguez Rodríguez, Jorge
    9'2
    >> h =  Hash[*y.flatten]
    => {"Pedr\303\255nez P\303\251rez, Ignacio"=>"7'5", ... , "Marrero Pi\303\261ero, Sergio"=>"7'2"}
    >> h.keys
    => ["Pedr\303\255nez P\303\251rez, Ignacio", ... , "Marrero Pi\303\261ero, Sergio"]
    >> h["Pedr\303\255nez P\303\251rez, Ignacio"]
    => "7'5"
    
  3. Ordene el hash en orden decreciente de calificaciones. Observe que las números se han escrito según la convención española de usar apóstrofes en vez del punto decimal. Una posibilidad es que utilices gsub para hacer sustituciones y convertir los apóstrofes en puntos:
    >> "7'5".gsub(/(\d+)'(\d*)/, '\1.\2')
    => "7.5"
    >> "7".gsub(/(\d+)'(\d*)/, '\1.\2')
    => "7"
    
  4. Es posible ordenar los elementos de un hash según sus claves:
    irb(main):005:0> h = {'a' => 3, 'b' =>2, 'c' => 1}
    => {"a"=>3, "b"=>2, "c"=>1}
    irb(main):008:0> h.sort
    => [["a", 3], ["b", 2], ["c", 1]]
    
    Se puede pasar un bloque a sort. El bloque recibe los dos elementos a comparar. Los elementos son parejas clave-valor:
    irb(main):006:0> h.sort { |a,b| a[0] <=> b[0] }
    => [["a", 3], ["b", 2], ["c", 1]]
    irb(main):007:0> h.sort { |a,b| a[1] <=> b[1] }
    => [["c", 1], ["b", 2], ["a", 3]]
    

Casiano Rodriguez León 2015-01-07