lunedì 21 aprile 2014

Python@Rice University

Così ho deciso il mese scorso di iscrivermi al corso Fundamentals of Computing il cui primo step è proprio un corso di introduzione (divertente a dire dei prof.) a Python.

Questo vorrebbe essere una specie di diario di viaggio, e considerato quanto mi stiano facendo studiare (sudare) non sarà molto ricco, cercherò almeno di pubblicare alcune note su pezzi di codice ed algoritmi che mi hanno particolarmente colpiti per l'eleganza, la linearità o semplicemente la bellezza ed efficienza.

Come spesso accade le ricerche più fruttuose nascono dalla soluzione di un problema: 

Durante la terza  settimana in uno dei quiz settimanali c'era questo problema al quale con mio sommo rammarico e fastidio sono riuscito a rispondere nell'immediato solo ed esclusivamente facendo il calcolo a manina (non ridete, sono proprio alle prime armi, ma migliorerò):
"
Given any initial natural number, consider the sequence of numbers generated by repeatedly following the rule:
  • divide by two if the number is even or
  • multiply by 3 and add 1 if the number is odd.
The Collatz conjecture states that this sequence always terminates at 1. For example, the sequence generated by 23 is:
23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1
Write a Python program that takes a global variable n and uses a timer callback to repeatedly apply the rule above to n. Use the code from the previous question as a template. I suggest that your code prints out the sequence of numbers generated by this rule. Run this program for n = 217. What is the largest number in the sequence generated by this starting value?
To test your code, starting at n = 23 generates a sequence with a maximum value of 160.       "   
Il codice a cui fa riferimento il testo non l'ho ancora capito  e si basava sull'utilizzo di un contatore e di un timer.
Sapendo che un ciclo while avrebbe potuto risolvere il problema ci ho provato e dopo qualche giorno sono riuscito a produrre questo pezzo di codice:

  
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
def collatz(n):
    
    print ""
           
    while n != 1:
                             
        if n % 2 == 0:
            
            n = n / 2
            
            print n
        
        elif n % 2 != 0: 
                           
            n = n * 3 + 1
            
            print n
                        
            if n == 1: break
                           
            if n != 1: continue
                


Naturalmente anche questo non è esente da difetti:
  • stampare i numeri in serie orizzontali
  • visualizzazione di alcune statistiche riguardante l'intervallo della successione
E perchè no giocare anche con altre successioni.

P.S. per chi fosse incuriosito sulla successione di Kollatz e le successioni in generale:


http://it.wikipedia.org/wiki/Congettura_di_Collatz


www.rudimathematici.com/blocknotes/pdf/RTC03.pdf‎


Good coding!

Rieccomi!
Quante righe di troppo!

Ecco qui una soluzione migliore:

1
2
3
4
5
6
7
8
9
def collatz(n):
    while n != 1:
        if n % 2 == 0:
            n = n / 2
            print n,
        elif n % 2 != 0:
            n = n * 3 + 1
            print n,
            
e questo è per esempio un risultato:
1
2
>>> collatz(180)
90 45 136 68 34 17 52 26 13 40 20 10 5 16 8 4 2 1






Nessun commento:

Posta un commento