// El ciclo se escribe una vez. Lo que cambia entra como parámetro.
#include <stdio.h>

#define COUNT 4

typedef double (*PriceChange)(double);
typedef double (*PriceFold)(double, double);

double add_tax(double price) {
    return price * 1.18;
}

double half_price(double price) {
    return price / 2.0;
}

void change_all(double *prices, int n, PriceChange change) {
    for (int i = 0; i < n; i++) {
        prices[i] = change(prices[i]);
    }
}

double fold_prices(const double *prices, int n, PriceFold combine, double initial) {
    double result = initial;
    for (int i = 0; i < n; i++) {
        result = combine(result, prices[i]);
    }
    return result;
}

double add_prices(double total, double price) {
    return total + price;
}

double larger_price(double best, double price) {
    return price > best ? price : best;
}

void print_prices(const double *prices, int n) {
    for (int i = 0; i < n; i++) {
        printf("%.2f ", prices[i]);
    }
    printf("\n");
}

int main(void) {
    double prices[COUNT] = {10.0, 25.0, 4.5, 100.0};
    printf("total: %.2f\n", fold_prices(prices, COUNT, add_prices, 0.0));
    printf("mayor: %.2f\n", fold_prices(prices, COUNT, larger_price, prices[0]));
    change_all(prices, COUNT, add_tax);
    print_prices(prices, COUNT);
    change_all(prices, COUNT, half_price);
    print_prices(prices, COUNT);
    return 0;
}
