Newsgroup: it.comp.lang.perl
Titolo: giochino terno

Su it.comp.os.linux.iniziare era in corso una "sfida" (in effetti
abbastanza OT, ma tralasciamo) su come creare il piu' piccolo programma
che mi simulasse l' estrazione di un terno da una ruota (e dunque la
stampa di 3 numeri random diversi tra loro).
Ci sono programmi in C, in python e io, nel mio piccolo, avevo scritto una
cosa del genere:
#!/usr/bin/perl
while (keys %n < 3) { $n{int(rand(90))+1}=0 }
print join (' ', keys %n), "\n"
ora, oltre a mostrare quanto io NON sappia il perl (piu' che altro ho dato
un' occhiata alla documentazione presente su 
perl.it
) volevo sapere se c'
era ancora modo di comprimere il tutto!
-- 
25/1/2005 | -2 all' alba!

 era ancora modo di comprimere il tutto!
Beh, se golf [1] dev'essere, usiamo almeno le regole del golf! :)
Elimino quindi la she-bang, e con altre modifiche piu` o meno
cosmetiche la tua versione diventa questa:
  {$n{int(rand(90))+1}++;keys%n<3&&redo}@v=keys%n;print"@v\n"
60 caratteri, ma ho idea che si possa fare di meglio.
ciao,
S.
[1] 
http://perlgolf.sourceforge.net/
 
-- 
Stefano Rodighiero      |  
http://larsen.perlmonk.org
mailto:
lar...@perl.it
   |  
http://www.perl.it

 60 caratteri, ma ho idea che si possa fare di meglio.
  {$n{int(rand(90))+1}++;@v=keys%n;@v<3&&redo}print"@v\n"
56 caratteri
S.


 56 caratteri
wow O_o
solo un paio di cose... che significa fare "++" dopo $n{...}?
(cioe', so che vuol dire, non ne capisco l' utilita')
ah, non avevo mai visto manco la funzione redo, carina!


 
Da buon parassita, mi limito a limare qualche carattere dalla tua 
brillante soluzione ;-)
	{\$n{1+int rand 90};@v=keys%n;@v<3&&redo}print"@v\n"
	# 53 caratteri
Se poi togliamo anche il newline finale (era richiesto?) scendiamo a 51 
caratteri:
	{\$n{1+int rand 90};@v=keys%n;@v<3&&redo}print"@v"
Ciao,
Emanuele.

print join (' ', keys %n), "\n"
E dov'è che ti assicuri che i tre numeri siano diversi?
Ciao.

Emanuele Zeppieri wrote:

47 caratteri, con qualche (sporco) trucco:
	{$n{1+int rand 90}=' ';keys%n<3&&redo}print(%n)
oppure:
	{\$n{1+int rand 90};(@v=(%n))<6&&redo}print"@v"
Ciao,
Emanuele.

 E dov'è che ti assicuri che i tre numeri siano diversi?
Contando il numero di chiavi nella hash, considerando come
vengono gestite i conflitti (lo stesso numero estratto due
volte non da` luogo ad un'incremento del numero di chiavi).
Il problema, piuttosto, e` che non e` un algoritmo, poiche`
potrebbe anche non terminare mai (continuando ad estrarre
lo stesso numero).
ciao,


Giovanni Zezza wrote:

Perché un hash non può avere chiavi duplicate (direi che ZeD il Perl lo 
conosce bene, contrariamente a quanto dice ;-)
Ciao,
Emanuele.

   {\$n{1+int rand 90};(@v=(%n))<6&&redo}print"@v"
Mi piace in particolare la seconda versione. Quanto agli sporchi
trucchi, sono il bello del golf :)
ciao,


 omettere.
Un motivo forse l'ho trovato, rispondendo in un altro punto
del thread. Continuando a impostare a 0 il valore della chiave
il programma potrebbe anche non terminare; nel mio caso invece
termina per overflow (uhm, in effetti *credo* che termini per
overflow: non ho controllato se invece avvengono meccanismi di 
wrap-around).
ciao,


lo stesso numero).
Questo termina, ma è un po' più lungo:
@r=(1..90);for$i(0..2){$n=int(rand(90-$i));push@e,(splice@r,$n,1)}print"@e"
Ciao.

 	{\$n{1+int rand 90};(@v=(%n))<6&&redo}print"@v"
ora pero' me la spieghi!!!


 conosce bene, contrariamente a quanto dice ;-)
mi spiace deluderti ma DAVVERO non conosco il perl... semplicemente
conosco i dizionari realizzati con hash (ho dato algoritmi e strutture
dati circa un paio di mesi fa) e "speravo" che quello che avevo studiato
fosse valido anche nel perl ^^;;;
un paio di prove mi hanno confermato che, almeno in casi "non al limite"
il sistema funzianava, dunque l' ho pubblicato (sia qui che su icoli).


 ora pero' me la spieghi!!!
Come sempre, il tentativo di spiegare le cose a qualcun altro richiede 
un'analisi piu` accurata di quello che avevi enucleato 
autoreferenzialmente (nun so' che vor di', ma me sona bene,) che, in 
questo caso, fa emergere in tutta la loro chiarezza una coppia di 
parentesi ridondanti nella mia precedente soluzione, eliminate le quali 
scendiamo a *45* caratteri:
	{\$n{1+int rand 90};(@v=%n)<6&&redo}print"@v"
Per quanto attiene alla chiarificazione, si tratta solo di qualche 
trucco aggiunto alla soluzione di Stefano.
La cosa più rilevante è probabilmente il frammento:
	(@v=%n)<6
Qui c'è prima l'assegnazione di un hash ad un array, e poi una 
maggiorazione (che viene eseguita (in contesto scalare) sull'array, dopo 
che e` stato valorizzato.)
Una volta eseguita l'assegnazione, l'array @v conterra` sia le chiavi 
che i valori dell'hash %n, disposti in questo modo:
	(key_1, val_1, key_2, val_2, key_3, val_3)
(Per inciso, gli indici stanno soltanto ad indicare la corrispondenza 
tra chiavi e valori, e *non* l'ordine nel quale le chiavi dell'hash sono 
state generate.)
Nel nostro caso pertanto, essendo il numero delle chiavi richieste pari 
a 3, gli elementi dell'array dovranno essere 6 (3 chiavi + 3 valori,) da 
cui dovrebbe risultare ovvia anche la maggiorazione.
Quando alla fine si stampa l'array @v, in realtà si stanno stampando 6 
elementi, solo che gli elementi dell'array corrispondenti ai valori 
dell'hash non appaiono, perche` non sono stati definiti (ma sono stati 
allocati, grazie all'operatore "\".)
Una curisosità: come è andata a finire la competizione su icoli?
Ciao,
Emanuele.

 allocati, grazie all'operatore "\".)
E questa e` la cosa che mi e` piaciuta di piu` della tua soluzione.
E` questo secondo me il bello del golf: e` squisitamente inutile, 
si finisce per scrivere codice illeggibile e orribile, che nessuno
sano di mente ficcherebbe in un prodotto reale, ma come effetto 
collaterale si imparano un sacco di cose sul funzionamento del
linguaggio. Che non e` cosa da poco.
ciao,


 (ma sono stati allocati, grazie all'operatore "\".)
ecco, non conoscevo (neanche) questo operatore!
ti ringrazio per la lezioncina!
