day 7 part 1 (C)

This commit is contained in:
2021-12-10 11:28:25 +01:00
parent 833732ae58
commit 6f6a6b286a
2 changed files with 173 additions and 0 deletions

View File

@@ -32,3 +32,29 @@ Each change of 1 step in horizontal position of a single crab costs 1 fuel. You
This costs a total of 37 fuel. This is the cheapest possible outcome; more expensive outcomes include aligning at position 1 (41 fuel), position 3 (39 fuel), or position 10 (71 fuel).
Determine the horizontal position that the crabs can align to using the least fuel possible. How much fuel must they spend to align to that position?
Your puzzle answer was 349769.
The first half of this puzzle is complete! It provides one gold star: *
--- Part Two ---
The crabs don't seem interested in your proposed solution. Perhaps you misunderstand crab engineering?
As it turns out, crab submarine engines don't burn fuel at a constant rate. Instead, each change of 1 step in horizontal position costs 1 more unit of fuel than the last: the first step costs 1, the second step costs 2, the third step costs 3, and so on.
As each crab moves, moving further becomes more expensive. This changes the best horizontal position to align them all on; in the example above, this becomes 5:
Move from 16 to 5: 66 fuel
Move from 1 to 5: 10 fuel
Move from 2 to 5: 6 fuel
Move from 0 to 5: 15 fuel
Move from 4 to 5: 1 fuel
Move from 2 to 5: 6 fuel
Move from 7 to 5: 3 fuel
Move from 1 to 5: 10 fuel
Move from 2 to 5: 6 fuel
Move from 14 to 5: 45 fuel
This costs a total of 168 fuel. This is the new cheapest possible outcome; the old alignment position (2) now costs 206 fuel instead.
Determine the horizontal position that the crabs can align to using the least fuel possible so they can make you an escape route! How much fuel must they spend to align to that position?

147
2021/day07/aoc-c.c Normal file
View File

@@ -0,0 +1,147 @@
/* aoc-c: Advent2021 game, day 6 parts 1 & 2
*
* Copyright (C) 2021 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <malloc.h>
#include "debug.h"
#include "bits.h"
static int ncrabs, crab_grow, crab_alloc, crab_max;
typedef struct crab {
int pos;
int ncrabs;
} crab_t;
crab_t *crabs = NULL;
//#ifdef DEBUG
static void print_crab()
{
int i = 0;
printf("crabs=%d max=%d\n", ncrabs, crab_max);
for (i = 0; i < ncrabs; ++i)
printf("%s%d/%d", i? ", ": "", crabs[i].pos, crabs[i].ncrabs);
printf("\n");
}
//#endif
static crab_t *grow_crabs()
{
//static int crab_max = 0;
int old = crab_alloc;
crab_alloc += crab_grow;
crabs = realloc(crabs, crab_alloc * sizeof (*crabs));
for (int i = old; i < crab_alloc; ++i) {
crabs[i].pos = -1;
crabs[i].ncrabs = 0;
}
return crabs;
}
static int add_crab(int crab)
{
int i;
if (crab > crab_max)
crab_max = crab;
if (ncrabs == crab_alloc) /* conservative grow */
grow_crabs();
for (i = 0; i < ncrabs; ++i) {
if (crabs[i].pos == crab) {
crabs[i].ncrabs++;
return i;
}
}
crabs[i].pos = crab;
crabs[i].ncrabs = 1;
ncrabs++;
return i;
}
static u64 read_crab()
{
char *buf, *token;
size_t alloc = 0;
ssize_t length;
if ((length = getline(&buf, &alloc, stdin)) < 0)
return -1;
crab_grow = length / 2;
token = strtok(buf, ",\n");
while (token) {
add_crab(atoi(token));
token = strtok(NULL, ",\n");
}
free(buf);
return ncrabs;
}
static int doit(int part)
{
int try, best_dist = 0, best_fuel = crab_max * crab_max;
if (part == 1) {
for (try = 0; try < crab_max; ++try) {
int fuel = 0;
for (int crab = 0; crab < ncrabs; ++crab)
fuel += abs(crabs[crab].pos - try) * crabs[crab].ncrabs;
if (fuel < best_fuel) {
best_dist = try;
best_fuel = fuel;
}
}
}
return best_fuel;
}
static int usage(char *prg)
{
fprintf(stderr, "Usage: %s [-d debug_level] [-p part]\n", prg);
return 1;
}
int main(int ac, char **av)
{
int opt;
u32 exercise = 1;
int res;
while ((opt = getopt(ac, av, "d:p:")) != -1) {
switch (opt) {
case 'd':
debug_level_set(atoi(optarg));
break;
case 'p': /* 1 or 2 */
exercise = atoi(optarg);
if (exercise < 1 || exercise > 2)
return usage(*av);
break;
default:
return usage(*av);
}
}
if (optind < ac)
return usage(*av);
read_crab();
res = doit(exercise);
printf ("%s : res=%d\n", *av, res);
exit (0);
}