Lezione del 23/5/2014

Costruzione grafo/albero dei divisori di un numero intero

File divisori.rb

 1#!/usr/bin/env ruby
 2#-------------------------------------------------------------------------#
 3#  Esercitazioni in Laboratorio per il Corso di                           #
 4#  Fondamenti di Informatica e Calcolo Numerico, AA 2013/2014             #
 5#                                                                         #
 6#  Autori:   Enrico Bertolazzi e Carlos Maximiliano Giorgio Bort          #
 7#            Dipartimento di Ingeneria Industriale, Universita` di Trento #
 8#  Sito web: http://www.ing.unitn.it/~bertolaz/                           #
 9#                                                                         #
10#  Contatti: enrico.bertolazzi@unitn.it, cm.giorgiobort@unitn.it          #
11#                                                                         #
12#  Copyright (c) 2014 E.Bertolazzi e C.M. Giorgio Bort                    #
13#-------------------------------------------------------------------------#
14
15require 'pp'
16
17#
18# Programma che legge un numero da terminale e costruisce una struttura
19# ad albero dei divisori.
20# Una volta costruita la stuttura scrive l'albero risultante in un file .dot
21# per visualizzarlo graficamente.
22#
23
24#
25# La struttura data è una combinazione di Hash e Array fatta in questo modo
26#
27# Un modo dell'albero è una hash con 2 campi:
28#  :number    --> un intero
29#  :divisors  --> un Array di Hash con i divisori
30#
31# La funzione divisori costruisce ricorsivamente la struttura dati
32#
33def divisiori( n )
34  root = { :number => n, :divisors => [] }
35  #
36  # la ricorsione o meglio root è srruttura completa se `n` è un numero primo
37  # cioè non ha divisori. La prima cosa fare è calcolare i divisori
38  for i in 2..n/2
39    if n % i == 0 then
40      # se arrivo qui, i è un divisore del numero n
41      root[:divisors] << divisiori( i ) ; # divisori(i) restituisce la Hash del
42                                          # "sottoalbero" del divisore i
43    end
44  end
45  return root ;
46end
47
48#
49# to_dot e' una funzione che data la struttura dati dell' albero dei
50# divisori stampa una descrizione nel liguaggio "dot" di graphviz
51# dell'albero corrispondente
52#
53def to_dot( albero )
54  from = albero[:number] ; # numero di partenza del rampo dell'albero
55  albero[:divisors].each { |d|
56    to = d[:number] ;
57    # stanpo il ramo from --> to
58    puts "#{from} -> #{to};"
59    to_dot( d ) ;
60  }
61end
62
63#
64# input come linea di comando.
65# se il comando è 
66#   ruby divisori.rb 100
67# ARGV[1] contiene 100
68
69albero = divisiori( ARGV[0].to_i ) ;
70
71puts "digraph G {"
72to_dot(albero)
73puts "}"
74#pp albero