1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
#include "message.h"
#include "maklib.h"
#include <iostream>

int * group_array();
int group_new_array(int * nowa_tablica);
int size_of_new_grouped_array;

int find_biggest_from_index(int);

// Okresl rozmiar tablicy, na ktorej dzialasz
int n = Size();
int * new_array = new int [n];
int size;

const int defaultPC = 0;

int main() {
    // Na poczatek przydziel komputerowi wykonanie funkcji o jego identyfikatorze ...
    int result, result_of_0;

    // Grupuj tablice, by latwiej sie na niej pracowalo
    if(MyNodeId() == defaultPC) {
        // nowy rozmiar tablicy, na ktorej bede pracowac
        size = group_new_array(group_array());

        // Wyślij rozmiar do wszystkich innych
        for(int i = 1; i<NumberOfNodes(); i++) {
            PutInt(i, size);
            Send(i);
        }
    }
    // Odczytaj zawarty w wiadomosci rozmiar nowej tablicy
    else {
        Receive(defaultPC);
        size = GetInt(defaultPC);
    }

    if(size <= NumberOfNodes()) {
        // Funkcje wykonaja tylko te komputery, krore maja mniejszy lub rowny Id w stosunku do size
        if(MyNodeId() < size) {
            if(MyNodeId() != defaultPC) {
                // To kazdy komputer niech uruchomi swoja funkcje
                result = find_biggest_from_index(MyNodeId());

                // Umiesc wynik w kolejce ...
                PutInt(defaultPC, result);
                // Wyslij wynik do instancji 0 - pierwszego komputera
                // Moge wyslac, bo zaden komputer nie bedzie robil funkcji dwa razy
                Send(defaultPC);
            }
            else {
                // Przypisz wynik do zmiennej
                result_of_0 = find_biggest_from_index(MyNodeId());

                // + nie musze do siebie wysylac wyniku
            }
        }
    }
    else {
        // Niech komputery porownuja same swoje wyniki ...

        // Jako ze bedzie wiecej niz Size() funkcji do zrobienia ...
        int currResult = 0;
        // Bo rozpoczynajac funkcje, funkcja zwieksza curr_element_to_work_on o jeden
        int curr_index_to_work_on = NumberOfNodes();

         // Zacznij prace dla funkcji z parametrem jako nr Twojego Id
         result = find_biggest_from_index(MyNodeId());
         // Porownaj - tak dla scislosci ... z zerem -.-
         currResult = result > currResult ? result : currResult;

         // Dopuki masz na czym pracowac ...
         while(curr_index_to_work_on < size) {

            // Zwieksz curr_element_to_work_on, zeby inny komp Ci nie zabral tego parametru .. :)
            curr_index_to_work_on++;
            // Wyslij do kazdego kompa oprocz ciebie wiadomosc, ze zmienilo sie curr_element_to_work_on

            // Najpierw wszystko skolejkuj
            for(int i=0; i<NumberOfNodes(); i++) {
                if(i != MyNodeId()) {
                    PutInt(i, curr_index_to_work_on);
                    Send(i);
                }
            }
            // Nie moge odwracac kolejnosci, bo odczytuje pierwsze skolejkowane
            for(int i=0; i<NumberOfNodes(); i++) {
                if(i != MyNodeId()) {
                    Receive(i);
                    curr_index_to_work_on = GetInt(i);
                }
            }

            if(MyNodeId() != defaultPC) {
                // To kazdy komputer niech uruchomi swoja funkcje
                result = find_biggest_from_index(curr_index_to_work_on);
                // Od razu zapamietaj tylko wiekszy wynik :)
                currResult = result > currResult ? result : currResult;
            }
            else {
                result_of_0 = find_biggest_from_index(curr_index_to_work_on);
                currResult = result_of_0 > currResult ? result_of_0 : currResult;
            }
         }

         //Jezeli juz nie ma na czym pracowac ...

        // Umiesc wynik w kolejce ...
        // Wyslij wynik do instancji 0 - pierwszego komputera
        PutInt(defaultPC, currResult);
        Send(defaultPC);

    }

    // Zbierz wszystkie wyniki w komputerze nr 0
    if(MyNodeId() == defaultPC) {
        int final_result = result_of_0;
        for(int i=1; i<NumberOfNodes(); i++) {
            Receive(i);
            int recived = GetInt(i);
            final_result = final_result < recived ? recived : final_result;
        }
        std::cout << final_result;
    }

    return 0;
}

int * group_array() {
    // stworz tablice na elementy
    int * tablica = new int [n];
    int sum = 0;

    int last_number = 0;
    int k = 0;

    // Okresl liczbe PC
    int ile_liczb_zrobic = (n / NumberOfNodes()) + 1;

    // Index to start from
    int start = MyNodeId() * ile_liczb_zrobic;
    int end = start + ile_liczb_zrobic;

     // Zainicjuj tablice wartosciami pobranymi przez [  int ElementAt(int i);  ]
    for(int i=start; i<end; i++) {
        tablica[i] = ElementAt(i+1);

        // Pozbijaj dodatnie i ujemne elementy w grupe
         if(last_number >= 0) {      // if POSITIVE
            if(tablica[i] >= 0) {
                sum += tablica[i];
            }
            else {
                // przypisz elementow tablicy positive wartosc sum
                new_array[k] = sum;
                k++;
                sum = 0;
                sum += tablica[i];
            }
        }
        else {                      // if NEGATIVE
            if(tablica[i] < 0) {
                sum += tablica[i];
            }
            else {
                new_array[k] = sum;
                k++;
                sum = 0;
                sum += tablica[i];
            }
        }
        last_number = tablica[i];
    }
    k++;
    new_array[k-1] = sum;
    delete [] tablica;

    // NOWA TABLICA //

    // Okresl rozmiar nowej tablicy
    int new_size = k;
    for(int i=1; i<NumberOfNodes(); i++) {
        PutInt(defaultPC, k);
        Send(defaultPC);

        if(MyNodeId == defaultPC) {
            Receive(i);
            new_size += GetInt(i);
        }
    }

    int * final_array = new int [new_size];

    size_of_new_grouped_array = new_size;

    for(int i=0; i<NumberOfNodes(); i++) {
        for(int j=0; j<k; j++) {
            PutInt(defaultPC, final_array[i]);
            Send(defaultPC);

            Receive(i);
            final_array[MyNodeId() * ile_liczb_zrobic + j] = GetInt(i);
        }
    }

    return final_array;
}

int group_new_array(int * tablica) {
    // stworz tablice na elementy
    int sum = 0;

    int last_number = 0;
    int k = 0;

     // Zainicjuj tablice wartosciami pobranymi przez [  int ElementAt(int i);  ]
    for(int i=0; i<size_of_new_grouped_array; i++) {
        tablica[i] = ElementAt(i+1);

        // Pozbijaj dodatnie i ujemne elementy w grupe
         if(last_number >= 0) {      // if POSITIVE
            if(tablica[i] >= 0) {
                sum += tablica[i];
            }
            else {
                // przypisz elementow tablicy positive wartosc sum
                new_array[k] = sum;
                k++;
                sum = 0;
                sum += tablica[i];
            }
        }
        else {                      // if NEGATIVE
            if(tablica[i] < 0) {
                sum += tablica[i];
            }
            else {
                new_array[k] = sum;
                k++;
                sum = 0;
                sum += tablica[i];
            }
        }
        last_number = tablica[i];
    }
    k++;
    new_array[k-1] = sum;

    return k;
}

int find_biggest_from_index(int index) {
    int curr_sum = 0, sum = 0;

    for (int i=index; i<size; i++) {
        if(curr_sum > 0) {
            curr_sum += new_array[i];
        }
        else {
            curr_sum = new_array[i];
        }

        if(curr_sum > sum) {
            sum = curr_sum;
        }
    }

    return sum;
}