Newsgroup: it.comp.programmare
Titolo: algoritmo

ciao raga mi servirebbe l'algoritmo di qsto problema:
un vettore contiene in nomi delle province del piemonte un secondo il numero
di abitanti per provincia un 3° l'estensione territtoriale in kmq
calcolare e memorizz in un altro vettla densita di pop densita=abit/km
calcola e visualiz la perc di abitanti per provinc sul numero di abitanti
della regione
visualizza la provinc con > e < densità
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 visualizza la provinc con > e < densità
Beh, non dici in che linguaggio, quindi ecco la soluzione + facile,
quella in Python (tanto chiedi solo l'algoritmo, no?-):
def compitoacasa(province, abitanti, kmq):
    assert len(province) == len(abitanti) == len(kmq)
    # primo requisito
    densita = [abit/float(km) for abit, km in zip(abitanti,kmq)]
    # secondo requisito
    abitreg100 = 100.0/sum(abitanti)
    print '%12s %5s" % ("Provincia", "%reg")
    for nome, abit in zip(province, abitanti):
        print '%12s %5.2f" % (nome, abitanti*abreg100)
    # terzo requisito
    zdp = zip(densita, province)
    print "Provincia con la maggiore densita`:", max(zdp)[-1]
    print "Provincia con la minore densita`:", min(zdp)[-1]
Alex

 ciao raga mi servirebbe l'algoritmo di qsto problema:
Questa non è la richiesta di "un algoritmo", questa è
la richiesta di un programmino bello e pronto.
Non ti preoccupare, come programmino è proprio facile...
sono sicuro che saprai scriverlo, una volta che avrai
preso il libro che adesso usi come fermaporte e te lo
sarai studiato un pò :->
Per il futuro:
1) se vuoi la pappa pronta vai su it.hobby.cucina;
2) qui nessuno lavora gratis. Alex non conta :-)



Nel caso in cui tu nonconosca il linguaggio Python ecco due altre
implementazioni dell'algoritmo:
In Smalltalk-80 (le frecce a sinistra in ASCII diventano caratteri
underscore):
| province abitanti kmq densita abitantiRegione
densMin densMax densMinIndex densMaxIndex |
province _ { 'Torino'. 'Novara'. 'Vercelli' }.
abitanti _ { 2860000. 540000. 560000 }.
kmq _ { 3200.0. 1254.0. 1427.0 }.
densita _ (1 to: province size) collect: [:i |
	(abitanti at: i) / (kmq at: i)].
Transcript nextPutAll: densita printString; cr.
abitantiRegione _ 0.
abitanti do: [:abit | abitantiRegione _ abitantiRegione + abit].
1 to: province size do: [:i |
	Transcript nextPutAll: (province at: i), ': ',
		((abitanti at: i) * 100.0 / abitantiRegione) printString,
		' %.'; cr].
densMin _ 1e9.
1 to: province size do: [:i |
	(densita at: i) < densMin ifTrue: [
		densMin _ densita at: i. densMinIndex _ i]].
Transcript nextPutAll: 'Provincia meno densamente popolata: ',
	(province at: densMinIndex), '.'; cr.
densMax _ -1.
1 to: province size do: [:i |
	(densita at: i) > densMax ifTrue: [
		densMax _ densita at: i. densMaxIndex _ i]].
Transcript nextPutAll: 'Provincia pi densamente popolata: ',
	(province at: densMaxIndex), '.'; cr; flush.
E in C++ con utilizzo della Standard Library:
#include <iostream>
#include <vector>
#include <deque>
#include <string>
#include <iterator>
#include <numeric>
#include <sstream>
using namespace std;
template <typename T1, typename T2>
class percentuale_abitanti {
	double tot_abitanti_;
public:
	percentuale_abitanti(double tot_abitanti):
		tot_abitanti_(tot_abitanti / 100) { }
	string operator()(const T1 &arg1, const T2 &arg2) {
		ostringstream ss;
		ss << arg1 << ": " << arg2 / tot_abitanti_ << " %.";
		return ss.str();
	}
};
template <typename C1, typename C2, typename C3, typename C4>
void compitino(const C1 &province, const C2 &abitanti,
	const C3 &kmq, C4 &densita) {
	transform(abitanti.begin(), abitanti.end(), kmq.begin(),
		back_inserter(densita), divides<double>());
	double tot_abitanti = accumulate(abitanti.begin(), abitanti.end(), 0.);
	transform(province.begin(), province.end(), abitanti.begin(),
		ostream_iterator<string>(cout, "\n"),
		percentuale_abitanti<typename C1::value_type,
		typename C2::value_type>(tot_abitanti));
	cout << "Provincia meno densamente popolata: "
		<< province[min_element(densita.begin(),
		densita.end()) - densita.begin()]
		<< ".\n";
	cout << "Provincia piu` densamente popolata: "
		<< province[max_element(densita.begin(),
		densita.end()) - densita.begin()]<< ".\n";
}
int main() {
	vector<string> province;
	province.push_back("Torino");
	province.push_back("Novara");
	province.push_back("Vercelli");
	deque<long> abitanti;
	abitanti.push_back(2860000);
	abitanti.push_back(540000);
	abitanti.push_back(560000);
	vector<double> kmq;
	kmq.push_back(3200.);
	kmq.push_back(1254.);
	kmq.push_back(1427.);
	deque<double> densita;
	compitino(province, abitanti, kmq, densita);
	cout << "Densita`: ";
	copy(densita.begin(), densita.end(),
		ostream_iterator<double>(cout, ""));
	cout << '\n';
	return 0;
}
Giusto per rendere il codice eseguibile, ho inserito qualche dato
fittizio.
Ovviamente un problema del genere ha senso solo come test delle
capacita` di programmazione.
Ho vinto qualcosa? :-)
P.S.: Non conoscendo io tutta la vasta libreria di Smalltalk, e'
possibile che si possa implementare lo stesso algoritmo con meno
istruzioni.
-- 
	Carlo Milanesi
 
http://digilander.libero.it/carlmila

il Sat, 15 Nov 2003 08:44:26 GMT, 
ste...@libero.it
 (ele) ha scritto::
la mia versione dei compiti.. se riesco a imparare smalltalk entro
domani posto anche quella :)
# in ruby:
Prov=[ 'Torino','Novara', 'Vercelli']
Abit=[2860000.0,540000.0,560000.0]
Area=[3200,1254,1427]
dens= Prov.zip(Abit,Area).map {|pr,ab,ar|
	[ab/ar,pr]
}
p dens.max,dens.min # gestiti dall'operatore Array <=> 
tot=Abit.inject {|x,y| x+y }
dens= Prov.zip(Abit,Area).map {|pr,ab,ar|
	[pr,ab*100/tot]
}
puts '',dens

 istruzioni.
In Smalltalk, è naturale lavorare ad oggetti - avere tre vettori 
distinti contenenti dati pertinenti ad una serie di oggetti logicamente 
congruenti è piuttosto scomodo.
Pertanto vale la pena definire una classe Provincia, con tre variabili 
d'istanza (nome, abitanti e kmq) e relativi metodi d'accesso (che ometto 
vista la loro semplicità ed il fatto che tutti gli ambienti smalltalk 
attuali sono in grado di generarli automaticamente con un click).
Object subclass: #Provincia
	instanceVariableNames: 'nome abitanti kmq'
	classVariableNames: ''
	poolDictionaries: ''
	classInstanceVariableNames: ''
La densita, inoltre, essendo un dato anch'esso pertinente alla provincia 
diverrebbe un metodo della classe stessa:
densita
	^abitanti / kmq
Fatto ciò il codice Smalltalk è molto più semplice.
"Userò i dati di prova presi dal tuo messaggio:"
province := OrderedCollection new.
province
	add: (Provincia nome: 'Torino' abitanti: 2860000 kmq: 3200.0);
	add: (Provincia nome: 'Novara' abitanti: 540000 kmq: 1254.0);
	add: (Provincia nome: 'Vercelli' abitanti: 560000 kmq: 1427.0).
"Il vettore contenente le densita si ottiene semplicemente chiedendo 
alle province la loro densita:"
densita := province collect: [ :prov | prov densita ].
"Gli abitanti della regione, facendo la somma degli abitanti delle 
singole province:"
abitantiRegione := province inject: 0 into: [ :cnt :prov | cnt + prov 
abitanti ].
"Con questo dato possiamo scrivere la percentuale di abitanti per 
provincia:"
province do: [ :prov |
	Transcript
		nextPutAll: prov nome;
		nextPutAll: ' ';
		display: (prov abitanti * 100.0 / abitantiRegione);
		nextPutAll: '%';
		cr.].
"Le province di massima e minima densita le ottengo scorrendo il vettore 
di province ed annotandomi quella migliore per il criterio scelto 
(densita min o max) man mano che vengono incontrate."
dmax := nil -> Float fmin.
	"Il messaggio (->) costruisce un'associazione con chiave
	il destinatario dell'oggeto e con valore il parametro
	del messaggio."
dmin := nil -> Float fmax.
province do: [ :prov |
	(dmax value < prov densita) ifTrue: [ dmax := prov -> prov densita 
].
	(dmin value > prov densita) ifTrue: [ dmin := prov -> prov densita 
].
].
Transcript nextPutAll: 'Provincia con densita max '; nextPutAll: dmax 
key nome; cr.
Transcript nextPutAll: 'Provincia con densita min '; nextPutAll: dmin 
key nome; cr.
-- 
Roberto Lupi

 ].
In alternativa, posso anche scrivere:
pdmax := province first.
pdmin := province first.
province do: [ :prov |
	(pdmax densita < prov densita) ifTrue: [ pdmax := prov ].
	(pdmin densita > prov densita) ifTrue: [ pdmin := prov ].
].
Transcript
	nextPutAll: 'Provincia con densita max';
	nextPutAll: pdmax nome;
	cr.
Transcript
	nextPutAll: 'Provincia con densita min';
	nextPutAll: pdmin nome;
	cr.
-- 
Roberto Lupi

il Sat, 15 Nov 2003 08:44:26 GMT, 
ste...@libero.it
 (ele) ha scritto::
e nello spirito del Sacro Ordine dei Perditempo, altra soluzione..
(il mio primo programma in SmallTalk :)
Provato con gnu smalltalk, sembrerebbe funzionare.. qualcuno sa come
effettuare un iterazione con più di due Collezioni per volta?
| province abitanti kmq 
  densita 
  tot |
province := { 'Torino'. 'Novara'. 'Vercelli' }.
abitanti := { 2860000. 540000. 560000. }.
kmq  := { 3200.0. 1254.0. 1427.0. }.
tot :=  abitanti  inject: 0 into: [:a :b| a+b ].
'percentuali :' printNl .
abitanti := abitanti with: province collect: [:ab :pr| 
    pr print .
    ( ab* 100.0 / tot) printNl .
    Array with: ab with: pr .
] .
densita := (abitanti with: kmq collect: [:ab :ar |
    Array with: (ab at: 1)/ar with: (ab at: 2) 
]) asSortedCollection: [:a :b|
    (a at: 1) <= (b at: 1) 
].
'la densita  min¨: ' print.
(densita at: 1 ) printNl .
'la densit  max : ' print .
(densita at: densita size ) printNl
!

 effettuare un iterazione con più di due Collezioni per volta?
anotherCollection keysAndValuesDo: [ :idx :itemOfB |
	| itemOfA |
	itemOfA := aCollection at: idx.
	"Codice che usa itemOfA e itemOfB"
].
" oppure "
aReadStream := aCollection readStream.
anotherCollection do: [ :itemOfB |
	| itemOfA |
	itemOfA := aReadStream next.
	"Codice che usa itemOfA e itemOfB"
].
-- 
Roberto Lupi


grazie per la risposta.
Perň stavo pensando piů a qualcosa sul modello di 
aCollection with: otherCollection do:
..
il punto č che per quel che ho visto (with: collect:) nn č possibile
usare piů di una collezione come parametro.. 
C'č un metodo per unire n collezioni in una (stile zip() in python o
Enumerable.zip() in ruby) ?

 Pertanto vale la pena definire una classe Provincia, ...
So bene che in qualunque linguaggio e' sempre meglio avere un array di
strutture piuttosto che piu' array della stessa lunghezza, ma ho cercato
di attenermi al testo del problema.


 di attenermi al testo del problema.
Non era una critica al tuo codice.
Volevo sottolineare come Smalltalk pur essendo un 
linguaggio di programmazione imperativo, NON è un 
linguaggio adatto alla programmazione strutturata.
Al contrario, è fatto in modo tale da scoraggiarla 
spingendo invece verso l'uso degli oggetti.
Python, C++, Ruby - proposti dagli altri partecipanti al 
thread - supportano in certa misura il paradigma della 
progammazione strutturata. Smalltalk no, non è nato per 
questo e non è adatto a questo scopo.
-- 
Roberto Lupi

 Enumerable.zip() in ruby) ?
Non c'è nulla nella libreria standard, né in Dolphin 
Smalltalk che ho sottomano.
Ma visto che in Smalltalk si possono definire nuovi metodi 
in classi già esistenti, non è affatto difficile 
aggiungere tali metodi a SequenceableCollection:
with: anotherCollection do: aBlock 
	| rs |
	rs := anotherCollection readStream.
	self do: [:item | aBlock value: item value: rs next]
zipWith: anotherCollection 
	| result |
	result := self copyEmpty.
	self with: anotherCollection do: [:a :b |
		result add: (Array with: a with: b)].
	^result
-- 
Roberto Lupi

 > Enumerable.zip() in ruby) ?
Non avevo notato la parte relativa alle n collezioni.
zipWithAll: aCollectionOfCollections 
  | streams result |
  streams := 
    ((Array with: self) , 
    aCollectionOfCollections) collect:
      [:coll | coll readStream].
  result := OrderedCollection new.
  [streams first atEnd]
    whileFalse:
    [result add: (streams collect: [:s | s next])].
  ^result
 
-- 
Roberto Lupi

Non avevo notato la parte relativa alle n collezioni.
grazie tante per il codice.
Ho scaricato un po' di roba su smalltalk da mezza settimana 
perdonatemi se sono un po naive :)
Deve esserci qualcosa di strano nell'aria.. a me è venuta la curiosità
di imparare smalltalk, un mio amico si è presentato con un CD con
CincomSmalltalk, trovo altre due persone che inviano snippet su usenet
al riguardo...
Tra l'altro qualche giorno fa su 
artima.com
 mi pare di aver notato un
messaggio relativo a una mailing list italiana su questo linguaggio..
qualcuno ne sa qualcosa?

 qualcuno ne sa qualcosa?
http://lists.unica.it/mailman/listinfo/smalltalkit
 
-- 
Roberto Lupi

, 

oh, grazie :)