Lawful Evil #6 – zadanie na rozgrzewke help

Widząc tytuł “Zadanie” byłem przekonany, że za chwilę wkleję delikwentowi linki do tego lub tego wpisu. Jednak okazało się, że ów delikwent prosi o coś zupełnie innego, i nie mam tutaj na myśli lekcji poprawnego użycia liczb mnogiej i pojedynczej:

ZadanieZadanie

Zadanie 5

W tablicy jednowymiarowej A[50]: wyzeruj elementy większe od średniej z wszystkich elementów.

W odpowiedzi zastosowałem trochę C++17, żeby wykładowca nie musiał kłopotać się z przestarzałym kodem:

template<size_t N, typename T>
void zero_elems(T* arr, double avg) {
    if constexpr(N > 0) {
        *arr = *arr > avg ? 0 : *arr;
        zero_elems<N-1>(arr+1, avg);
    }
}
 
template<typename T, size_t N>
void zero_elems(T (&arr)[N]) {
    auto avg = std::accumulate(std::begin(arr), std::end(arr), 0.0, std::plus<>{});
    avg /= N;
    zero_elems<N>(arr, avg);
}

Zadanie 9

W tablicy jednowymiarowej A[50]: zamień parzyste elementy na dwójki a nieparzyste na jedynki pod warunkiem, że ich indeksy są odpowiednio parzyste i nieparzyste.

Tutaj sprawa jest oczywiście mniej skomplikowana – nie ma potrzeby osobnego obliczania średniej, więc można po prostu sprawdzić wartości wszystkich elementów:

auto& elem_0 = A[0];
if(0 == (elem_0 & 1)) elem_0 = (2 >> 0);
 
auto& elem_1 = A[1];
if(1 == (elem_1 & 1)) elem_1 = (2 >> 1);
 
auto& elem_2 = A[2];
if(0 == (elem_2 & 1)) elem_2 = (2 >> 0);
 
auto& elem_3 = A[3];
if(1 == (elem_3 & 1)) elem_3 = (2 >> 1);
 
auto& elem_4 = A[4];
if(0 == (elem_4 & 1)) elem_4 = (2 >> 0);
 
auto& elem_5 = A[5];
if(1 == (elem_5 & 1)) elem_5 = (2 >> 1);
 
auto& elem_6 = A[6];
if(0 == (elem_6 & 1)) elem_6 = (2 >> 0);
 
auto& elem_7 = A[7];
if(1 == (elem_7 & 1)) elem_7 = (2 >> 1);
 
auto& elem_8 = A[8];
if(0 == (elem_8 & 1)) elem_8 = (2 >> 0);
 
auto& elem_9 = A[9];
if(1 == (elem_9 & 1)) elem_9 = (2 >> 1);
 
auto& elem_10 = A[10];
if(0 == (elem_10 & 1)) elem_10 = (2 >> 0);
 
auto& elem_11 = A[11];
if(1 == (elem_11 & 1)) elem_11 = (2 >> 1);
 
auto& elem_12 = A[12];
if(0 == (elem_12 & 1)) elem_12 = (2 >> 0);
 
auto& elem_13 = A[13];
if(1 == (elem_13 & 1)) elem_13 = (2 >> 1);
 
auto& elem_14 = A[14];
if(0 == (elem_14 & 1)) elem_14 = (2 >> 0);
 
auto& elem_15 = A[15];
if(1 == (elem_15 & 1)) elem_15 = (2 >> 1);
 
auto& elem_16 = A[16];
if(0 == (elem_16 & 1)) elem_16 = (2 >> 0);
 
auto& elem_17 = A[17];
if(1 == (elem_17 & 1)) elem_17 = (2 >> 1);
 
auto& elem_18 = A[18];
if(0 == (elem_18 & 1)) elem_18 = (2 >> 0);
 
auto& elem_19 = A[19];
if(1 == (elem_19 & 1)) elem_19 = (2 >> 1);
 
auto& elem_20 = A[20];
if(0 == (elem_20 & 1)) elem_20 = (2 >> 0);
 
auto& elem_21 = A[21];
if(1 == (elem_21 & 1)) elem_21 = (2 >> 1);
 
auto& elem_22 = A[22];
if(0 == (elem_22 & 1)) elem_22 = (2 >> 0);
 
auto& elem_23 = A[23];
if(1 == (elem_23 & 1)) elem_23 = (2 >> 1);
 
auto& elem_24 = A[24];
if(0 == (elem_24 & 1)) elem_24 = (2 >> 0);
 
auto& elem_25 = A[25];
if(1 == (elem_25 & 1)) elem_25 = (2 >> 1);
 
auto& elem_26 = A[26];
if(0 == (elem_26 & 1)) elem_26 = (2 >> 0);
 
auto& elem_27 = A[27];
if(1 == (elem_27 & 1)) elem_27 = (2 >> 1);
 
auto& elem_28 = A[28];
if(0 == (elem_28 & 1)) elem_28 = (2 >> 0);
 
auto& elem_29 = A[29];
if(1 == (elem_29 & 1)) elem_29 = (2 >> 1);
 
auto& elem_30 = A[30];
if(0 == (elem_30 & 1)) elem_30 = (2 >> 0);
 
auto& elem_31 = A[31];
if(1 == (elem_31 & 1)) elem_31 = (2 >> 1);
 
auto& elem_32 = A[32];
if(0 == (elem_32 & 1)) elem_32 = (2 >> 0);
 
auto& elem_33 = A[33];
if(1 == (elem_33 & 1)) elem_33 = (2 >> 1);
 
auto& elem_34 = A[34];
if(0 == (elem_34 & 1)) elem_34 = (2 >> 0);
 
auto& elem_35 = A[35];
if(1 == (elem_35 & 1)) elem_35 = (2 >> 1);
 
auto& elem_36 = A[36];
if(0 == (elem_36 & 1)) elem_36 = (2 >> 0);
 
auto& elem_37 = A[37];
if(1 == (elem_37 & 1)) elem_37 = (2 >> 1);
 
auto& elem_38 = A[38];
if(0 == (elem_38 & 1)) elem_38 = (2 >> 0);
 
auto& elem_39 = A[39];
if(1 == (elem_39 & 1)) elem_39 = (2 >> 1);
 
auto& elem_40 = A[40];
if(0 == (elem_40 & 1)) elem_40 = (2 >> 0);
 
auto& elem_41 = A[41];
if(1 == (elem_41 & 1)) elem_41 = (2 >> 1);
 
auto& elem_42 = A[42];
if(0 == (elem_42 & 1)) elem_42 = (2 >> 0);
 
auto& elem_43 = A[43];
if(1 == (elem_43 & 1)) elem_43 = (2 >> 1);
 
auto& elem_44 = A[44];
if(0 == (elem_44 & 1)) elem_44 = (2 >> 0);
 
auto& elem_45 = A[45];
if(1 == (elem_45 & 1)) elem_45 = (2 >> 1);
 
auto& elem_46 = A[46];
if(0 == (elem_46 & 1)) elem_46 = (2 >> 0);
 
auto& elem_47 = A[47];
if(1 == (elem_47 & 1)) elem_47 = (2 >> 1);
 
auto& elem_48 = A[48];
if(0 == (elem_48 & 1)) elem_48 = (2 >> 0);
 
auto& elem_49 = A[49];
if(1 == (elem_49 & 1)) elem_49 = (2 >> 1);

Wersja @hauleth

Wyżej wymieniony pan zasugerował, że powyższe zadanie można wykonać w następujący sposób:

void clamp(int *arr, size_t size) {
  int *i = arr;
  do { *i = (*i & 1) ^ ((i - arr) & 1) ? *i : ((~(i - arr) & 1) + 1); } while (++i - arr < (ptrdiff_t)size);
}

2 thoughts on “Lawful Evil #6 – zadanie na rozgrzewke help

  1. Nie znam tych nowych standardów C++’a, ale czy w zadaniu 5 w wierszu 13 nie powinno być & przed arr?

    zero_elems(&arr, avg);

    W tej dolnej funkcji arr jest referencją, a w górnej masz wskaźnik.

    1. Nie, jest dobrze. Tablice w C (a zatem i w C++) automatycznie decayują (brak mi polskiego słowa) do wskaźnika na pierwszy element. Niemniej jednak, w pierwszej funkcji zero_elems parametrem jest wskaźnik, i wywołujemy też wersję ze wskaźnikiem, więc nie ma potrzeby pobierania jego adresu.

Leave a Reply

Your email address will not be published.