mirror of
https://github.com/peter-tanner/advent-of-code-2021.git
synced 2024-11-30 11:10:20 +08:00
Day 7 solutions
This commit is contained in:
parent
1f3169bc83
commit
d0a016cc3a
84
7/7-1.c
Normal file
84
7/7-1.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
// SOLUTION USING GRADIENT DESCENT
|
||||
|
||||
#define PART_2
|
||||
|
||||
#ifdef PART_2
|
||||
#define STEP 0.0001F
|
||||
#else
|
||||
#define STEP 0.2F
|
||||
#endif
|
||||
|
||||
#define INITIAL_CONDITION \
|
||||
{ \
|
||||
16, 1, 2, 0, 4, 2, 7, 1, 2, 14 \
|
||||
}
|
||||
#define INITIAL_GUESS 10000.0F
|
||||
|
||||
// THIS IS NEEDED FOR PART 2 BECAUSE OF FLOATS. QUICK AND DIRTY COPYPASTE.
|
||||
int fuel_total_int(int *state, size_t state_len, int point)
|
||||
{
|
||||
int total = 0;
|
||||
for (size_t i = 0; i < state_len; i++)
|
||||
{
|
||||
int fuel = abs(state[i] - point);
|
||||
#ifdef PART_2
|
||||
fuel *= (fuel + 1) / 2.0F; // TRIANGLE NUMBER T_n = n/2*(n+1)
|
||||
#endif
|
||||
total += fuel;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
// MUST BE FLOAT FOR GRADIENT DESCENT TO WORK.
|
||||
float fuel_total(int *state, size_t state_len, float point)
|
||||
{
|
||||
float total = 0;
|
||||
for (size_t i = 0; i < state_len; i++)
|
||||
{
|
||||
float fuel = fabs(state[i] - point);
|
||||
#ifdef PART_2
|
||||
fuel *= (fuel + 1) / 2.0F; // TRIANGLE NUMBER T_n = n/2*(n+1)
|
||||
#endif
|
||||
total += fuel;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void gradient_descent(int *state, size_t state_len, float *guess, float *gradient)
|
||||
{
|
||||
float y = fuel_total(state, state_len, *guess);
|
||||
float dy_dx = fuel_total(state, state_len, *guess + 1) - y;
|
||||
printf("%.5f, y=%.5f, dy=%.5f\n", *guess, y, dy_dx);
|
||||
*guess -= STEP * dy_dx;
|
||||
*gradient = dy_dx;
|
||||
}
|
||||
|
||||
float main(float argc, char const *argv[])
|
||||
{
|
||||
int state[] = INITIAL_CONDITION;
|
||||
size_t state_len = sizeof(state) / sizeof(state[0]);
|
||||
float guess = INITIAL_GUESS;
|
||||
float gradient = 1.0F; // START WITH NON-ZERO VALUE
|
||||
while (fabs(gradient) > 0.01)
|
||||
{
|
||||
gradient_descent(state, state_len, &guess, &gradient);
|
||||
}
|
||||
|
||||
// CHECK "AREA" SURROUNDING FINAL GUESS
|
||||
int min_fuel = __INT_MAX__;
|
||||
for (int t = guess - 1; t < guess + 1; t++)
|
||||
{
|
||||
int fuel = fuel_total_int(state, state_len, t);
|
||||
if (fuel < min_fuel)
|
||||
min_fuel = fuel;
|
||||
}
|
||||
|
||||
printf("FUEL %d\n", (int)min_fuel);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user