Day 16/part 2: C version.
This commit is contained in:
@@ -15,13 +15,13 @@ output:
|
|||||||
|
|
||||||
compile: ex1-c ex2-c
|
compile: ex1-c ex2-c
|
||||||
|
|
||||||
ex1:
|
ex1: ex1-c
|
||||||
@$(TIME) ex1.bash < $(INPUT) 2>&1
|
@$(TIME) ex1.bash < $(INPUT) 2>&1
|
||||||
@$(TIME) ex1-c 2020 < $(INPUT) 2>&1
|
@$(TIME) ex1-c < $(INPUT) 2>&1
|
||||||
|
|
||||||
ex2:
|
ex2: ex2-c
|
||||||
@$(TIME) ex2.bash < $(INPUT) 2>&1
|
@$(TIME) ex2.bash < $(INPUT) 2>&1
|
||||||
@#$(TIME) ex1-c 30000000 < $(INPUT) 2>&1
|
@$(TIME) ex2-c < $(INPUT) 2>&1
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -f ex1-c ex2-c core
|
@rm -f ex1-c ex2-c core
|
||||||
|
@@ -5,9 +5,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define AA "ABCD"
|
|
||||||
#define LAA sizeof(AA)
|
|
||||||
|
|
||||||
/* tickets ranges */
|
/* tickets ranges */
|
||||||
struct srange {
|
struct srange {
|
||||||
char *name;
|
char *name;
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
CMD=${0##*/}
|
CMD=${0##*/}
|
||||||
#shopt -s extglob
|
#shopt -s extglob
|
||||||
|
|
||||||
declare -A valid=()
|
declare -A VALID=()
|
||||||
declare -i state=0 res=0
|
declare -i state=0 res=0
|
||||||
|
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
@@ -13,7 +13,7 @@ while read -r line; do
|
|||||||
n1=$(seq "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}")
|
n1=$(seq "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}")
|
||||||
n2=$(seq "${BASH_REMATCH[5]}" "${BASH_REMATCH[6]}")
|
n2=$(seq "${BASH_REMATCH[5]}" "${BASH_REMATCH[6]}")
|
||||||
for i in $n1 $n2; do
|
for i in $n1 $n2; do
|
||||||
valid[$i]=1
|
VALID[$i]=1
|
||||||
done
|
done
|
||||||
elif [[ $line =~ (your ticket:|nearby tickets) ]]; then
|
elif [[ $line =~ (your ticket:|nearby tickets) ]]; then
|
||||||
((state++))
|
((state++))
|
||||||
@@ -21,7 +21,7 @@ while read -r line; do
|
|||||||
if ((state == 2)); then
|
if ((state == 2)); then
|
||||||
for i in ${line//,/ }; do
|
for i in ${line//,/ }; do
|
||||||
# shellcheck disable=SC2100
|
# shellcheck disable=SC2100
|
||||||
[[ ! -v valid[$i] ]] && res=res+i
|
[[ ! -v VALID[$i] ]] && res=res+i
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
243
day16/ex2-c.c
Normal file
243
day16/ex2-c.c
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
/* ex1-c: Advent2020 game, day 16/game 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* tickets ranges */
|
||||||
|
struct srange {
|
||||||
|
char *name;
|
||||||
|
int s1, e1;
|
||||||
|
int s2, e2;
|
||||||
|
int col;
|
||||||
|
int possiblecount;
|
||||||
|
int *possible; /* possible[i]=-1 => column i cannot be */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct list {
|
||||||
|
int size;
|
||||||
|
int last;
|
||||||
|
struct srange *ranges;
|
||||||
|
} list = {
|
||||||
|
0, 0, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BLOCKSIZE 1024 /* number of elements for realloc() */
|
||||||
|
|
||||||
|
int *myticket=NULL;
|
||||||
|
int *curticket=NULL; /* current ticket */
|
||||||
|
int ticketsize=0;
|
||||||
|
|
||||||
|
void print_ranges()
|
||||||
|
{
|
||||||
|
unsigned i, n=list.last;
|
||||||
|
int j;
|
||||||
|
struct srange *p=list.ranges;
|
||||||
|
|
||||||
|
printf("RANGES: address=%p last=%u size=%u\n", list.ranges, n, list.size);
|
||||||
|
for (i=0; i<n; ++i, ++p) {
|
||||||
|
printf(" [%03u] %u-%u %u-%u [%s]\n", i, p->s1, p->e1, p->s2, p->e2, p->name);
|
||||||
|
printf(" Possible cols (%d remaining) : ", p->possiblecount);
|
||||||
|
for (j=0; j<ticketsize; ++j)
|
||||||
|
if (p->possible[j] >= 0)
|
||||||
|
printf(" %d", p->possible[j]);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct srange *add_range(name, s1, e1, s2, e2)
|
||||||
|
char *name;
|
||||||
|
int s1, e1, s2, e2;
|
||||||
|
{
|
||||||
|
struct srange *p;
|
||||||
|
|
||||||
|
if (list.last == list.size) {
|
||||||
|
list.ranges=realloc(list.ranges, sizeof(struct srange)*BLOCKSIZE);
|
||||||
|
list.size+=BLOCKSIZE;
|
||||||
|
}
|
||||||
|
p=list.ranges+list.last;
|
||||||
|
p->name=strdup(name);
|
||||||
|
p->s1=s1;
|
||||||
|
p->e1=e1;
|
||||||
|
p->s2=s2;
|
||||||
|
p->e2=e2;
|
||||||
|
p->col=-1;
|
||||||
|
list.last++;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_ticket(ticket)
|
||||||
|
int *ticket;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
printf("Ticket: ");
|
||||||
|
for (i=0; i<ticketsize; ++i)
|
||||||
|
printf("%d ", *(ticket+i));
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
int *parse_ticket(str)
|
||||||
|
char *str;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (!curticket)
|
||||||
|
curticket=malloc(ticketsize * sizeof *myticket);
|
||||||
|
for (i=0, p=str; i<ticketsize; ++i, ++p)
|
||||||
|
curticket[i]=(int)strtol(p, &p, 10);
|
||||||
|
return curticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
int *parse_myticket(str)
|
||||||
|
char *str;
|
||||||
|
{
|
||||||
|
int i, j, *possible;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
ticketsize=1;
|
||||||
|
for (p=str; *p; p++)
|
||||||
|
if (*p==',')
|
||||||
|
ticketsize++;
|
||||||
|
|
||||||
|
myticket=malloc(ticketsize * sizeof *myticket);
|
||||||
|
for (p=str, i=0; i<ticketsize; ++i, ++p)
|
||||||
|
myticket[i]=(int)strtol(p, &p, 10);
|
||||||
|
// set possible columns for all ranges
|
||||||
|
for (i=0; i<list.last; ++i) {
|
||||||
|
possible=malloc(sizeof (int) * ticketsize);
|
||||||
|
list.ranges[i].possible=possible;
|
||||||
|
list.ranges[i].possiblecount=ticketsize;
|
||||||
|
for (j=0; j<ticketsize; ++j)
|
||||||
|
possible[j]=j;
|
||||||
|
}
|
||||||
|
return myticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_in_range(i, range)
|
||||||
|
int i;
|
||||||
|
struct srange *range;
|
||||||
|
{
|
||||||
|
if ((i>=range->s1 && i<=range->e1) || (i>=range->s2 && i<=range->e2))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_valid(ticket)
|
||||||
|
int *ticket;
|
||||||
|
{
|
||||||
|
int i, r, found;
|
||||||
|
|
||||||
|
for (i=0; i<ticketsize; ++i) {
|
||||||
|
found=0;
|
||||||
|
for (r=0; r<list.last; ++r) {
|
||||||
|
if (is_in_range(*(ticket+i), list.ranges+r)) {
|
||||||
|
found=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ex2_add(ticket)
|
||||||
|
int *ticket;
|
||||||
|
{
|
||||||
|
int i, r;
|
||||||
|
|
||||||
|
if (check_valid(ticket)) {
|
||||||
|
for (i=0; i<ticketsize; ++i) {
|
||||||
|
for (r=0; r<list.last; ++r) {
|
||||||
|
if (!is_in_range(*(ticket+i), list.ranges+r)) {
|
||||||
|
// this value cannot be in this range, we unset this column
|
||||||
|
list.ranges[r].possible[i]=-1;
|
||||||
|
list.ranges[r].possiblecount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long ex2()
|
||||||
|
{
|
||||||
|
int i, r, r1, unique=0;
|
||||||
|
unsigned long res=1;
|
||||||
|
struct srange *range, *range1;
|
||||||
|
|
||||||
|
while (!unique) {
|
||||||
|
unique=1;
|
||||||
|
for (r=0; r<list.last; ++r) {
|
||||||
|
range=list.ranges+r;
|
||||||
|
if (range->col >= 0)
|
||||||
|
continue;
|
||||||
|
if (range->possiblecount == 1) {
|
||||||
|
for (i=0; range->possible[i]==-1 && i<ticketsize; ++i)
|
||||||
|
;
|
||||||
|
range->col=i;
|
||||||
|
for (r1=0; r1<list.last; ++r1) {
|
||||||
|
range1=list.ranges+r1;
|
||||||
|
if (range1 != range && range1->possible[i] != -1) {
|
||||||
|
range1->possible[i]=-1;
|
||||||
|
range1->possiblecount--;
|
||||||
|
unique=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (r=0; r<list.last; ++r) {
|
||||||
|
range=list.ranges+r;
|
||||||
|
if (!strncmp(range->name, "departure", 9)) {
|
||||||
|
res*=myticket[range->col];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(ac, av)
|
||||||
|
int ac;
|
||||||
|
char **av;
|
||||||
|
{
|
||||||
|
char line[1024], pname[80], *elabel;
|
||||||
|
int s1, e1, s2, e2, end=0, status=0;
|
||||||
|
unsigned long res=0;
|
||||||
|
int *ticket;
|
||||||
|
|
||||||
|
while (fgets(line, sizeof line, stdin)) {
|
||||||
|
if (*line=='\n')
|
||||||
|
continue;
|
||||||
|
if (*line >= '0' && *line <= '9') {
|
||||||
|
switch (status) {
|
||||||
|
case 1:
|
||||||
|
ticket=parse_myticket(line);
|
||||||
|
// print_ranges();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ticket=parse_ticket(line);
|
||||||
|
// valid ticket
|
||||||
|
// print_ticket(ticket);
|
||||||
|
ex2_add(ticket);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (elabel=strchr(line, ':')) {
|
||||||
|
if (*(elabel+1)=='\n') {
|
||||||
|
status++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sscanf(line, "%[^:]: %d-%d or %d-%d %n",
|
||||||
|
pname, &s1, &e1, &s2, &e2, &end);
|
||||||
|
add_range(pname, s1, e1, s2, e2);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res=ex2();
|
||||||
|
printf("%s : res=%lu\n", *av, res);
|
||||||
|
exit (0);
|
||||||
|
}
|
Reference in New Issue
Block a user