The true spirit of delight, the exaltation, the sense of being more than Man, which is the touchstone of the highest excellence, is to be found in mathematics as surely as in poetry.
These are my own solutions to the Advent of Code problems. So far, they’ve all been in C, but I want to write a few in Common Lisp in the next new days.
archivist/day01-1.carchivist/day01-1.c
\#include "../array.h" \#include "../fileload.h" int main (int argc, char\*\*argv){ if(argc < 2){ printf("not enough inputs\n"); return -1; } char \* input = file\_contents(argv[1]); char\*dispos = input; array data = arr\_init(0, sizeof(int)); char \* line = 0; while((line = strsep(&dispos, "\n")) != NULL){ if(strlen(line) == 0) break; char \* val = strsep(&line, " "); int temp = atoi(val); arr\_add(&data, &temp); }; for (int j = 0;j<data.size;j++){ printf("val: %d\n", arr\_get(int, data, j)); } for (size\_t i = 0;i<data.size;i++){ for (size\_t j = 0;j<data.size;j++){ if (arr\_get(int,data,i) + arr\_get(int,data,j)== 2020){ printf("Found! The multiple is: %d\n", arr\_get(int,data,i) \* arr\_get(int,data,j) ); } } } return 0; }
archivist/day01-2.carchivist/day01-2.c
\#include "../array.h" \#include "../fileload.h" int main (int argc, char\*\*argv){ if(argc < 2){ printf("not enough inputs\n"); return -1; } char \* input = file\_contents(argv[1]); char\*dispos = input; array data = arr\_init(0, sizeof(int)); char \* line = 0; while((line = strsep(&dispos, "\n")) != NULL){ if(strlen(line) == 0) break; char \* val = strsep(&line, " "); int temp = atoi(val); arr\_add(&data, &temp); }; for (int j = 0;j<data.size;j++){ //printf("val: %d\n", arr\_get(int, data, j)); } for (size\_t i = 0;i<data.size;i++){ for (size\_t j = 0;j<data.size;j++){ for (size\_t k = 0;k<data.size;k++){ if (arr\_get(int,data,i) + arr\_get(int,data,j) + arr\_get(int,data,k)== 2020){ printf("Found! The multiple is: %d\n", arr\_get(int,data,i) \*arr\_get(int,data,j) \*arr\_get(int,data,k)); } } } } return 0; }
archivist/day01-3.carchivist/day01-3.c
\#include "../array.h" \#include "../fileload.h" \#include <stdlib.h> //For /g/&\#39;s bigboy dataset. Target sum is 99920044 int MAX\_SIZE = 100000; int compare(const void\* a, const void\* b){ return (\*(int \*)a < \*(int \*)b) ? -1 : 1; return 0; } int search\_up(int\*vals, int left, int right, int max){ int here; while (right-left > 1){ here = (left+right)/2; if(vals[here] == max) return here; if(vals[here] > max) right = here; if(vals[here] < max) left = here; } if(vals[right] > max){ return left; } return right; } int search\_down(int\*vals, int left, int right, int min){ int here; while (right-left > 1){ here = (left+right)/2; if(vals[here] == min) return here; if(vals[here] > min) right = here; if(vals[here] < min) left = here; } if(vals[left] < min){ return right; } return left; } int main (int argc, char\*\*argv){ if(argc < 2){ printf("not enough inputs\n"); return -1; } char \* input = file\_contents(argv[1]); int size = 0; const int target = 99920044; int\*arr = malloc(sizeof(int)\*MAX\_SIZE); char \* line = 0; while((line = strsep(&input, "\n")) != NULL){ if(strlen(line) == 0) break; char \* val = strsep(&line, " "); arr[size++] = atoi(val); if (size > MAX\_SIZE) { printf("Too many inputs\n"); exit(-1);} }; //int (\*func)(const void \*, const void \*, void \*) = &compare; qsort(&arr[0], size, sizeof(int), compare); for(int i = 0; i < size; i++){ //printf("%d\n", arr[i]); } //a<b<c int true\_left = 0; int true\_right= size-1; //first pass while(true\_right>true\_left+2){ int any=1; while(any){ any = 0; int new\_true\_right = search\_up(arr,true\_left+2,true\_right,target-arr[true\_left]-arr[true\_left+1]); if(new\_true\_right<true\_right){ true\_right = new\_true\_right; any++; } int new\_true\_left = search\_down(arr,true\_left,true\_right-2,target-arr[true\_right]-arr[true\_right-1]); if(new\_true\_left>true\_left){ true\_left=new\_true\_left; any++; } //if(any)printf("true left, true right %d, %d\n", true\_left, true\_right); } int left=true\_left; int right = true\_right-1; int starget = target - arr[true\_right]; any = 1; while(any){ any = 0; int new\_right = search\_up(arr,left+1,right,starget-arr[left]); if(new\_right<right){ right = new\_right; any++; } int new\_left = search\_down(arr,left,right-1,starget-arr[right]); if(new\_left>left){ left=new\_left; any++; } //printf("%d, %d\n", left, right); } //printf("starting iteration\n"); while(left != right ){ int tempright = search\_up(arr, left+1, right,starget-arr[left]); if(arr[left]+arr[tempright] == starget){ printf("FOUND IT! the nums are %d, %d, %d\n", arr[left], arr[right], arr[true\_right]); printf("Sum is: %d, compared with %d\n", arr[left]+ arr[right]+ arr[true\_right], target); return 0; } left++; } true\_right--; } return 0; }
archivist/day02-1.carchivist/day02-1.c
\#include "../array.h" \#include "../fileload.h" int main (int argc, char\*\*argv){ if(argc < 2){ printf("not enough inputs\n"); return -1; } char \* input = file\_contents(argv[1]); char\*dispos = strdup(input); array data = arr\_init(0, sizeof(int)); int n\_valid\_passwords = 0; char \* line = 0; while((line = strsep(&dispos, "\n")) != NULL){ if(strlen(line) == 0) break; int polchar\_occurences = 0; char \* val = line; printf("string: %s\n", val); int min = atoi(val); strsep(&val, "-"); int max = atoi(val); strsep(&val, " "); char polchar = val[0]; strsep(&val, " "); printf("%d, %d, %c\n", min, max, polchar); while(val[0] != &\#39;\0&\#39;){ printf("%c", val[0]); if (val[0] == polchar) polchar\_occurences++; val++; } printf("\nnumber of times %c occured: %d\n", polchar, polchar\_occurences); if(min <= polchar\_occurences && polchar\_occurences <= max) n\_valid\_passwords++; }; printf("Number of valid passwords:%d\n", n\_valid\_passwords); for (size\_t j = 0;j<data.size;j++){ printf("val: %d\n", arr\_get(int, data, j)); } return 0; }
archivist/day02-2.carchivist/day02-2.c
\#include "../array.h" \#include "../fileload.h" int main (int argc, char\*\*argv){ char\* input = file\_contents(argv[1]); int n\_valid\_passwords = 0; char\* line = NULL; int ind[2]; while((line = strsep(&input, "\n")) != NULL){ if(strlen(line) == 0) break; char\* val = line; ind[0] = atoi(val)-1; strsep(&val, "-"); ind[1] = atoi(val)-1; strsep(&val, " "); char polchar = val[0]; strsep(&val, " "); n\_valid\_passwords += ((val[ind[0]]==polchar) != (val[ind[1]]==polchar)); }; printf("Number of valid passwords:%d\n", n\_valid\_passwords); return 0; }
archivist/day03-1.carchivist/day03-1.c
\#include "../array.h" \#include "../fileload.h" \#include <stdlib.h> int main (int argc, char\*\*argv){ if(argc < 2){ printf("not enough inputs\n"); return -1; } int width = 0; int height = 0; char \* input = file\_contents(argv[1]); char\*dispos = malloc(strlen(input)\*sizeof(char)); strcpy(dispos, input); array data = arr\_init(0, sizeof(int)); char \* line = 0; while((line = strsep(&dispos, "\n")) != NULL){ if(strlen(line) == 0) break; width=strlen(line); height++; }; int xpos = 0; int ypos = 0; int n\_trees = 0; printf("W: %d, H: %d\n", width,height); while(ypos < height){ xpos = (xpos+3)%width; ypos = ypos+1; printf("%d, %d\n", xpos,ypos); //We have to use width+1 to account for newline characters if(input[xpos+ypos\*(width+1)] == &\#39;\#&\#39;) { n\_trees++; printf("you hit a tree\n"); } } printf("You hit %d trees\n", n\_trees); return 0; }
archivist/day03-2.carchivist/day03-2.c
\#include <stdio.h> /\*TO THE\*/ \#include <stdlib.h> /\*OCEAN!\*/ \#include <string.h> \#define R 5 // // int main( int argc, char \*\*argv){ int w=0;int h=0; int l=0;FILE\*f=fopen( argv[1],"r");char\*I;if (!f) return-1;fseek(f,0,SEEK\_END); l=ftell (f);printf("l is %d\n",l); rewind(f) ;I=(char\*)malloc(sizeof(char)\* (l+1)) ;fread(I,sizeof(char),l,f); fclose (f);((char\*)I)[l]=&\#39;\0&\#39;;for(int i=0; i<l;i++){if(I[i]==&\#39;\n&\#39;){w=i;break ;}}h=l /(w+1);printf("W: %d,H: %d\n" ,w,h) ;int s[R] [2]={{1,1},{3,1},{5,1}, {7,1}, {1,2} };long int tot=1;for(int run=0;run<R; run++){int x=0; int y=0;int n=0;while(y<h){x=( x+s [run] [0] )%w;y=y+s[run][1];if(I[x+y\*(w+1) ]==&\#39;\#&\#39;)n++ ; }printf("You hit %d trees on run %d\n",n,run) ; tot \*=n;}printf("Total multiple: %ld\n",tot); ; int i=0;i++;i++;i++;i++;i++;i++;i++; i++;i++;i++; i++; i++;i++;i++;i++;i++;i++;i++ ;i++;i++; i++;i++;i++ ;i++; i++;i++;i++;i++;i++;i++;i++; i++;i++; i++;i++; i++; i++; i++;i++; i++; i++;i++;i++;i++;i++; i++; i++; i++;i++;i++;i++;i++;i++;i++; i++;i++; i++; i++; i++;i++;i++;i++;i++;i++;i++;i++;i++;i++; i++; i++; i++;i++;i++; i++;i++;i++; i++;i++;i++;i++; i++;;}
archivist/day03-3.carchivist/day03-3.c
\#include <stdio.h> \#include <stdlib.h> \#include <string.h> \#include "../bn.h" int main (int argc, char\*\*argv){ int width = 0; int height = 0; long int length = 0; FILE \*f = fopen(argv[1], "r"); char output[8192]; output[0] = &\#39;a&\#39;; output[1024] = &\#39;\0&\#39;; char \*input; if (!f) return -1; fseek(f, 0, SEEK\_END); length = ftell(f); printf("length is %ld\n", length); rewind(f); input = (char\*)malloc(sizeof(char) \* (length+1)); fread(input, sizeof(char), length, f); printf("length is %ld\n", length); fclose(f); ((char\*)input)[length] = &\#39;\0&\#39;; for(int i = 0; i < length; i++){ if(input[i] == &\#39;\n&\#39;){ width = i; break; } } height = length/(width+1); printf("W: %d, H: %d\n", width,height); int run\_list\_size = 15; int slopevals[2][15] = {{ 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 32, 36, 48, 54, 64 }, { 1, 5, 7, 11, 13, 17, 19, 23, 25, 29, 31, 35, 37, 41, 47 }}; unsigned long long int running\_mult\_total = 1; struct bn total; struct bn tmp; struct bn tmp2; bignum\_from\_int(&total, 1); for(int i = 0;i<run\_list\_size;i++){ for(int j = 0;j<run\_list\_size;j++){ //printf("Slope %d, %d\n", slopevals[0][i], slopevals[1][j]); int xpos = 0; int ypos = 0; int n\_trees = 0; while(ypos < height){ xpos = (xpos+slopevals[0][i])%width; ypos = ypos+slopevals[1][j]; //We have to use width+1 to account for newline characters if(input[xpos+ypos\*(width+1)] == &\#39;\#&\#39;) n\_trees++; } printf("You hit %d trees on run %d\n", n\_trees, i\*15+j); if(n\_trees == 0) n\_trees++; //bignum\_from\_int(&total, 111231); bignum\_assign(&tmp2, &total); bignum\_from\_int(&tmp,n\_trees); bignum\_mul(&tmp,&tmp2,&total); bignum\_to\_string(&total, output, sizeof(output)); printf("running multiple: %s\n", output); } } bignum\_to\_string(&total, output, 1024); printf("Total multiple: %s\n", output); return 0; }
archivist/day04-1.carchivist/day04-1.c
\#include "../array.h" \#include "../fileload.h" \#include <stdlib.h> /\* \* byr (Birth Year) \* iyr (Issue Year) \* eyr (Expiration Year) \* hgt (Height) \* hcl (Hair Color) \* ecl (Eye Color) \* pid (Passport ID) \* cid (Country ID) \*/ \#define BYR 1<<0 \#define IYR 1<<1 \#define EYR 1<<2 \#define HGT 1<<3 \#define HCL 1<<4 \#define ECL 1<<5 \#define PID 1<<6 \#define CID 1<<7 typedef struct field{ int bitcode; char label[4]; }field; int main (int argc, char\*\*argv){ field fields[8]; strcpy(fields[0].label, "BYR"); strcpy(fields[1].label, "IYR"); strcpy(fields[2].label, "EYR"); strcpy(fields[3].label, "HGT"); strcpy(fields[4].label, "HCL"); strcpy(fields[5].label, "ECL"); strcpy(fields[6].label, "PID"); strcpy(fields[7].label, "CID"); int all\_on = 0; for(int i = 0; i<8; i++){ fields[i].bitcode = 1<<i; all\_on = all\_on | fields[i].bitcode; fields[i].label[3] = &\#39;\0&\#39;; } if(argc < 2){ printf("not enough inputs\n"); return -1; } char \* input = file\_contents(argv[1]); char\*dispos = input; int n\_valids = 0; int bitmap\_default = 0 | CID; int bitmap = 0 | CID; char \* line= 0; char \* val = 0; char \* fieldname = 0; while((line = strsep(&dispos, "\n")) != NULL){ if(strlen(line) == 0) { //printf("Passport done\n"); if (bitmap == all\_on) { //printf("Valid passport\n"); n\_valids++; }else{ //printf("Invalid passport\n"); } bitmap = bitmap\_default | CID; continue; } while(val =strsep(&line, " ")){ fieldname = strsep(&val, ":"); for(int i = 0; i<8; i++){ if(strcasecmp(fieldname, fields[i].label) == 0){ bitmap = bitmap | fields[i].bitcode; break; } } } }; printf("There are %d valid passports among the bunch.\n", n\_valids); return 0; }
archivist/day04-2.carchivist/day04-2.c
\#include "../fileload.h" \#include <stdlib.h> /\* \* byr (Birth Year) \* iyr (Issue Year) \* eyr (Expiration Year) \* hgt (Height) \* hcl (Hair Color) \* ecl (Eye Color) \* pid (Passport ID) \* cid (Country ID) \*/ typedef struct field{ int bitcode; char label[4]; int (\*validate)(const void \*); }field; int valBYR(const void\*value){ char \* str = (char\*)value; int yr = atoi(str); if(strlen(str) == 4 && 1920<=yr && yr <= 2002) return 1; return 0; } int valIYR(const void\*value){ char \* str = (char\*)value; int yr = atoi(str); if( strlen(str) == 4 && 2010<=yr && yr<=2020) return 1; return 0; } int valEYR(const void\*value){ char \* str = (char\*)value; int yr = atoi(str); if( strlen(str) == 4 && 2020<=yr && yr<=2030) return 1; return 0; } int valHGT(const void\*value){ char \* str = (char\*)value; int len = strlen(str); if(strcmp(str+len-2, "cm") == 0){ int h = atoi(str); if( 150 <= h && h <= 193) return 1; }else if(strcmp(str+len-2, "in") == 0){ int h = atoi(str); if( 59 <= h && h <= 76) return 1; } return 0; } int valHCL(const void\*value){ char \* str = (char\*)value; if(strlen(str) != 7) return 0; if(str[0] != &\#39;\#&\#39;) return 0; for(int i = 1; i < 7; i++){ if ( !(str[i]>=48&&str[i]<=57) &&!(str[i]>=97&&str[i]<=102)) return 0; } return 1; } int valECL(const void\*value){ char \* str = (char\*)value; if(strcmp(str,"amb")==0)return 1; if(strcmp(str,"blu")==0)return 1; if(strcmp(str,"brn")==0)return 1; if(strcmp(str,"gry")==0)return 1; if(strcmp(str,"grn")==0)return 1; if(strcmp(str,"hzl")==0)return 1; if(strcmp(str,"oth")==0)return 1; return 0; } int valPID(const void\*value){ char \* str = (char\*)value; if(strlen(str) != 9) return 0; for(int i = 0; i < 9; i++){ if (str[i]<48||str[i]>57) return 0; } return 1; } int valCID(const void\*value){ //lol no return 1; } int main (int argc, char\*\*argv){ field fields[8]; strcpy(fields[0].label, "BYR"); fields[0].validate = valBYR; strcpy(fields[1].label, "IYR"); fields[1].validate = valIYR; strcpy(fields[2].label, "EYR"); fields[2].validate = valEYR; strcpy(fields[3].label, "HGT"); fields[3].validate = valHGT; strcpy(fields[4].label, "HCL"); fields[4].validate = valHCL; strcpy(fields[5].label, "ECL"); fields[5].validate = valECL; strcpy(fields[6].label, "PID"); fields[6].validate = valPID; strcpy(fields[7].label, "CID"); fields[7].validate = valCID; int all\_on = 0; for(int i = 0; i<8; i++){ fields[i].bitcode = 1<<i; all\_on = all\_on | fields[i].bitcode; fields[i].label[3] = &\#39;\0&\#39;; } if(argc < 2){ printf("not enough inputs\n"); return -1; } char \* input = file\_contents(argv[1]); char\*dispos = input; int n\_valids = 0; int bitmap\_default = 0 | CID; int bitmap = 0 | CID; char \* line= 0; char \* val = 0; char \* fieldname = 0; while((line = strsep(&dispos, "\n")) != NULL){ if(strlen(line) == 0) { //printf("Passport done\n"); if (bitmap == all\_on) { //printf("Valid passport\n"); n\_valids++; }else{ //printf("Invalid passport\n"); } bitmap = bitmap\_default | CID; continue; } while(val =strsep(&line, " ")){ fieldname = strsep(&val, ":"); for(int i = 0; i<8; i++){ if(strcasecmp(fieldname, fields[i].label) == 0){ bitmap = bitmap | (fields[i].bitcode \*fields[i].validate(val)); break; } } } }; printf("There are %d valid passports among the bunch.\n", n\_valids); return 0; }
archivist/day05-1.carchivist/day05-1.c
\#include <stdio.h> \#include <stdlib.h> \#include <string.h> \#define PLANE\_LENGTH 128 \#define PLANE\_WIDTH 8 int blookup(int min,int max, char \* code, int n\_splits){ for(int i = 0; i < n\_splits; i++){ if(code[i]==&\#39;B&\#39; || code[i]==&\#39;R&\#39;) min = (min+max)/2+1; if(code[i]==&\#39;F&\#39; || code[i]==&\#39;L&\#39;) max = (min+max)/2; } //printf("min %d, max %d\n", min, max); return min; }; int main (int argc, char\*\*argv){ int length = 0; FILE \*f = fopen(argv[1], "r"); char \*input; if (!f) return -1; fseek(f, 0, SEEK\_END); length = ftell(f); rewind(f); input = (char\*)malloc(sizeof(char) \* (length+1)); fread(input, sizeof(char), length, f); //printf("length is %d\n", length); fclose(f); ((char\*)input)[length] = &\#39;\0&\#39;; int biggest\_possible\_id = (0 + 8\*127+7); printf("Biggest possible ID: %d\n", biggest\_possible\_id); int biggest\_id = 0; char \* line = 0; while((line = strsep(&input, "\n"))!= NULL){ if(strlen(line) == 0) break; int row = 0; int column = 0; int id = 0; //printf("%s\n", line); //boarding seat code is 10 chars long row = blookup(0, PLANE\_LENGTH-1, line,7); column = blookup(0, PLANE\_WIDTH-1, line+7,3); id=row\*8+column; //printf("Row %d, Column %d, ID %d\n", row, column, id); if(id>biggest\_id) biggest\_id=id; } printf("Biggest ID so far: %d\n", biggest\_id); return 0; }
archivist/day05-2.carchivist/day05-2.c
\#include <stdio.h> \#include <stdlib.h> \#include <string.h> \#define PLANE\_LENGTH 128 \#define PLANE\_WIDTH 8 int compare(const void\* a, const void\* b){ return (\*(int \*)a < \*(int \*)b) ? -1 : 1; return 0; } int blookup(int min,int max, char \* code, int n\_splits){ for(int i = 0; i < n\_splits; i++){ if(code[i]==&\#39;B&\#39; || code[i]==&\#39;R&\#39;) min = (min+max)/2+1; if(code[i]==&\#39;F&\#39; || code[i]==&\#39;L&\#39;) max = (min+max)/2; } //printf("min %d, max %d\n", min, max); return min; }; int main (int argc, char\*\*argv){ int length = 0; FILE \*f = fopen(argv[1], "r"); char \*input; if (!f) return -1; fseek(f, 0, SEEK\_END); length = ftell(f); rewind(f); input = (char\*)malloc(sizeof(char) \* (length+1)); fread(input, sizeof(char), length, f); fclose(f); ((char\*)input)[length] = &\#39;\0&\#39;; int n\_lines = 0; for(int i = 0; i < length; i++){ if(input[i] == &\#39;\n&\#39;) n\_lines++; } printf("no. of lines: %d\n", n\_lines); int \* idlist = malloc(sizeof(int)\*n\_lines); int list\_index = 0; char \* line = 0; while((line = strsep(&input, "\n"))!= NULL){ if(strlen(line) == 0) break; int row = 0; int column = 0; int id = 0; row = blookup(0, PLANE\_LENGTH-1, line,7); column = blookup(0, PLANE\_WIDTH-1, line+7,3); id=row\*8+column; idlist[list\_index++] = id; } qsort(idlist, n\_lines, sizeof(int), &compare); for(int i = 0; i < n\_lines-1; i++){ if ((idlist[i+1]-idlist[i]) > 1){ printf("ID between %d and %d\n", idlist[i], idlist[i+1]); printf("My ID is %d\n", idlist[i]+1); } } return 0; }
archivist/day06.carchivist/day06.c
\#include <stdio.h> \#include <stdlib.h> \#include <string.h> const int coffset = 97; int countbits(int N){ int count = 0; while(N > 0){ count += N & 1; N >>= 1; } return count; } int part1(char\* in); int part2(char\* in); int main (int argc, char\*\*argv){ int length = 0; FILE \*f = fopen(argv[1], "r"); char \*input; if (!f) return -1; fseek(f, 0, SEEK\_END); length = ftell(f); rewind(f); input = (char\*)malloc(sizeof(char) \* (length+1)); fread(input, sizeof(char), length, f); fclose(f); ((char\*)input)[length] = &\#39;\0&\#39;; //part1(input); part2(input); return 0; } int part1(char\* in){ char \* line = 0; int sum = 0; int groupbits = 0; while((line = strsep(&in, "\n"))!= NULL){ if(strlen(line) == 0){ sum += countbits(groupbits); groupbits = 0; continue; } for(int i=0;i<strlen(line);i++){ groupbits |= (1 << ((int)line[i] - coffset)); } } printf("Sum of sums: %d\n", sum); } int part2(char\* in){ char \* line = 0; int sum = 0; int groupbits = ~0; int passengerbits = 0; while((line = strsep(&in, "\n"))!= NULL){ if(strlen(line) == 0){ sum += countbits(groupbits); groupbits = ~0; continue; } for(int i=0;i<strlen(line);i++){ passengerbits |= (1 << ((int)line[i] - coffset)); } groupbits &= passengerbits; passengerbits = 0; } printf("Sum of sums: %d\n", sum); }
archivist/day07.lisparchivist/day07.lisp
(asdf:load-system :split-sequence) (asdf:load-system :iterate) (defpackage \#:aoc-7 (:use \#:cl \#:split-sequence \#:iterate)) (in-package \#:aoc-7) (defun cat (&rest strs) (concatenate &\#39;string strs)) (defun replace-all (string part replacement &key (test \#&\#39;char=)) "Returns a new string in which all the occurences of the part is replaced with replacement." (with-output-to-string (out) (loop with part-length = (length part) for old-pos = 0 then (+ pos part-length) for pos = (search part string :start2 old-pos :test test) do (write-string string out :start old-pos :end (or pos (length string))) when pos do (write-string replacement out) while pos))) (defun getinput () (let\* ((fname "testinput") (lines (uiop:read-file-lines fname))) lines )) (defun replac (lines) (mapcar (lambda (x) (last (mapcar (lambda (s r) (setf x (replace-all x s r))) &\#39;("," "." " bags " " bag " "contain " "no other" " bags" " bag") `("" "" ,(string \#\newline) ,(string \#\newline) "" "" "" ""))) ) lines) ) (defun split (lines) (remove-if (lambda (x) (eq (length x) 1)) (mapcar (lambda (x) (split-sequence \#\newline (car x) :remove-empty-subseqs t)) lines))) (defun split-num (str) (list (parse-integer (car (split-sequence \#\space str :count 1))) (apply (lambda (x y) (concatenate &\#39;string x y)) (split-sequence \#\space str :from-end t :count 2)))) (defun line-num (line) (cons (replace-all (car line) " " "") (mapcar \#&\#39;split-num (cdr line)))) (defun split-nums (lines) (mapcar (lambda (x) (line-num x)) lines)) (defun get-data () (split-nums (split (replac (getinput))))) (defun searchline (str line) (reduce (lambda (&optional x y) (or x y)) (mapcar (lambda (sub) (equal (cadr sub) str)) line))) (defun getline (str data) (car (remove-if-not (lambda (x) (equal str (car x))) data))) (defun remline (str data) (remove-if (lambda (x) (equal str (car x))) data)) (defun rep-element (el data &optional (keepln t)) (if (getline (second el) data) (list (first el) (rep-line (cdr (getline (second el) data)) data keepln)) (if keepln el (list (first el)))) ) (defun rep-line (line data &optional (keepln t)) (mapcar (lambda (x) (rep-element x data keepln)) line)) (defun rep (col1 lines data &optional (keepln t)) (mapcar (lambda (x l) (cons x (rep-line l data keepln))) col1 lines)) (defun find-recur (el l) (cond ((null l) nil) ((atom l) (equal el l)) (t (if (equal el (car l)) t (or (find-recur el (car l)) (find-recur el (cdr l))))))) (defun nostring (l) (let ((nl (if (not (or (atom l) (null l))) (remove-if (lambda (x) (typep x &\#39;string )) l) l))) (cond ((atom nl) nl) ((null (cdr nl)) (list (nostring (car nl)))) (t (list (nostring (car nl)) (nostring (cdr nl))) )))) (defun count-recur (l) (cond ((null l) 0) ((atom l) l) ((and (> (length l) 1) (atom (car l)) (not (atom (cadr l)))) (+ (car l) (\* (car l) (count-recur (cdr l))))) (t (+ (count-recur (car l)) (count-recur (cadr l)))))) (defun part1 () (let\* ((data (remline "shinygold" (get-data))) (fdata (mapcar \#&\#39;car data)) (bdata (mapcar \#&\#39;cdr data))) (count &\#39;t (mapcar (lambda (x) (find-recur "shinygold" x)) (rep fdata bdata data))) )) (defun part2 () (let\* ((data (get-data)) (fdata (mapcar \#&\#39;car data)) (bdata (mapcar \#&\#39;cdr data)) (pdata (rep fdata bdata data nil)) (gold (getline "shinygold" pdata))) (print pdata) (print gold) (print (nostring gold)) (cdr gold) (count-recur (cdr gold))))
archivist/day08.lisparchivist/day08.lisp
(asdf:load-system :split-sequence) (asdf:load-system :iterate) (defpackage \#:aoc-8 (:use \#:cl \#:split-sequence \#:iterate)) (in-package \#:aoc-8) (defun cat (&rest strs) (concatenate &\#39;string strs)) (defun replace-all (string part replacement &key (test \#&\#39;char=)) "Returns a new string in which all the occurences of the part is replaced with replacement." (with-output-to-string (out) (loop with part-length = (length part) for old-pos = 0 then (+ pos part-length) for pos = (search part string :start2 old-pos :test test) do (write-string string out :start old-pos :end (or pos (length string))) when pos do (write-string replacement out) while pos))) (defstruct machine (pointer 0) (accum 0)) (defparameter \*vm\* (make-machine)) (defun copy-array (array) (let ((new (make-array (array-dimensions array) :displaced-to array))) (adjust-array new (array-dimensions array) :displaced-to nil))) (defun getinput () (let\* ((fname "bigboylarge") (lines (uiop:read-file-lines fname))) lines )) (defun process (input) (make-array (length input) :initial-contents (mapcar (lambda (x) (list (str-to-op x) nil)) input))) (defun str-to-op (str) (let ((substr (subseq str 0 3))) (list (cond ((equal substr "nop") \#&\#39;nop) ((equal substr "acc") \#&\#39;acc) ((equal substr "jmp") \#&\#39;jmp)) (parse-integer (subseq str 4))))) (defun nop (vm val) (incf (machine-pointer vm))) (defun acc (vm val) (setf (machine-accum vm) (+ (machine-accum vm) val)) (incf (machine-pointer vm))) (defun jmp (vm val) (setf (machine-pointer vm) (+ (machine-pointer vm) val))) (defun part1 () (let ((vm (make-machine)) (code (process (getinput)))) (iterate (while (and (not (cadr (aref code (machine-pointer vm)))) (<= (machine-pointer vm) (length code)))) (let ((op (aref code (machine-pointer vm)))) (setf (cadr op) t) (funcall (caar op) vm (cadar op))) ) (print code) (machine-accum vm))) (defun part2-run (code) (let ((vm (make-machine))) (iterate (while (and (< (machine-pointer vm) (length code)) (>= (machine-pointer vm) 0) (not (cadr (aref code (machine-pointer vm)))) )) (let ((op (aref code (machine-pointer vm)))) (setf (cadr op) t) (funcall (caar op) vm (cadar op)) ) (finally (return (if (>= (machine-pointer vm) (length code)) (machine-accum vm) nil)))))) (defun swap (fun) (cond ((eq fun \#&\#39;jmp) \#&\#39;nop) ((eq fun \#&\#39;nop) \#&\#39;jmp) (t fun))) (defun part2 () (let\* ((code (process (getinput)))) ;(part2-run vcode) ;reset (print (1- (length code))) (iterate (for i from 0 to (1- (length code))) (if (eq (mod i 10000) 0) (print i)) (let ((op (aref code i))) (if (not (eq (caar op) \#&\#39;acc)) (progn (setf (caar op) (swap (caar op))) (let ((res (part2-run code))) (if res (return res))) (iterate (for i from 0 to (1- (length code))) (setf (cadr (aref code i)) nil)) (setf (caar op) (swap (caar op)))))))))
archivist/day09.lisparchivist/day09.lisp
(asdf:load-system :split-sequence) (asdf:load-system :iterate) (defpackage \#:aoc-9 (:use \#:cl \#:split-sequence \#:iterate)) (in-package \#:aoc-9) (defun getinput () (mapcar \#&\#39;parse-integer (uiop:read-file-lines "input"))) (defun split (vlist index) (values (subseq vlist 0 index) (nthcdr index vlist))) (defun seek (l val) (iterate (while l) (let ((a (pop l))) (if (iterate (for b in l) (if (eq val (+ a b)) (return t))) (return t))))) (defun part1 () (let\* ((all (getinput))) (multiple-value-bind (preamble remain) (split all 25) (iterate (while remain) (let\* ((val (pop remain)) (s (remove-if (lambda (x) (> x val)) (sort (copy-seq preamble) \#&\#39;<)))) (if (not (seek s val)) (return val)) (pop preamble) (nconc preamble (list val))))))) (defun part2 () (let\* ((all-in (getinput)) (all (make-array (length all-in) :initial-contents all-in)) (val (part1))) (iterate (for i from 0 to (1- (length all))) (let ((ret (iterate (for j from (1+ i) to (1- (length all))) (let ((s (subseq all i (1+ j)))) (if (eq val (reduce \#&\#39;+ s)) (progn (return (+ (reduce \#&\#39;min s) (reduce \#&\#39;max s))))))))) (if ret (return ret))))))
archivist/day10.lisparchivist/day10.lisp
(asdf:load-system :split-sequence) (asdf:load-system :iterate) (defpackage \#:aoc-10 (:use \#:cl \#:split-sequence \#:iterate)) (in-package \#:aoc-10) (defun getinput () (mapcar (lambda (x) (parse-integer x)) (uiop:read-file-lines "bigboy.txt"))) (defun part1 () (let\* ((input (sort (getinput) \#&\#39;<)) (proc (mapcar (lambda (x y) (- y x)) (cons 0 (subseq input 0 (length input) )) (nreverse (cons (+ (car (last input)) 3) (nreverse input) ))))) (\* (count 1 proc) (count 3 proc)))) (defun part2-walk (l cache) (if (not (cadr l)) 1 (reduce \#&\#39;+ (mapcar (lambda (remain) (if (and (car remain) (<= (- (car remain) (car l)) 3)) (multiple-value-bind (result exists) (gethash (car remain) cache) (if exists result (setf (gethash (car remain) cache) (part2-walk remain cache)))) 0)) `(,(cdr l) ,(cddr l) ,(cdddr l)))))) (defun part2-slow () (let\* ((input (cons 0 (append (sort (getinput) \#&\#39;<) (list (+ 3 (apply \#&\#39;max (getinput))))))) (mycache (make-hash-table :test \#&\#39;equal))) (part2-walk input mycache))) (defun validp (a b) (<= (- b a) 3)) (defun getif (val later) (if (validp val (car later)) (cadr later) 0)) (defun part2 () (let\* ((input (nreverse (cons 0 (sort (getinput) \#&\#39;<)))) (tri (list (pop input) 1)) (two (list (pop input) 1)) (one-f (pop input)) (one (list one-f (+ (getif one-f two) (getif one-f tri))))) (iterate (while input) (let\* ((newval (pop input)) (new (list newval (reduce \#&\#39;+ (mapcar (lambda (x) (getif newval x)) (list tri two one)))))) (setf tri (copy-list two)) (setf two (copy-list one)) (setf one (copy-list new)))) (log (cadr one) 10)))
archivist/day11.lisparchivist/day11.lisp
(asdf:load-system :split-sequence) (asdf:load-system :iterate) (asdf:load-system :alexandria) (defpackage \#:aoc-11 (:use \#:cl \#:split-sequence \#:iterate \#:alexandria)) (in-package \#:aoc-11) (defun getinput () (let ((in (uiop:read-file-lines "input"))) (make-array (list (length in) (length (car in))) :initial-contents in))) (defun cval (c) (cond ((eq c \#\\#) 1) ((eq c \#\L) 0) ((eq c \#\.) 0))) (defun getval (x y arr dims) (if (or (> x (1- (car dims))) (< x 0) (> y (1- (cadr dims))) (< y 0) ) 0 (cval (aref arr x y)))) (defun next (x y arr dims) (let ((sum (+ (getval (1+ x) y arr dims) (getval (1+ x) (1+ y) arr dims) (getval x (1+ y) arr dims) (getval (1- x) (1+ y) arr dims) (getval (1- x) y arr dims) (getval (1- x) (1- y) arr dims) (getval x (1- y) arr dims) (getval (1+ x) (1- y) arr dims) )) (state (aref arr x y))) (cond ((and (eq state \#\L) (eq sum 0)) \#\\#) ((and (eq state \#\\#) (>= sum 4)) \#\L) (t state)))) (defun part1 () (let\* ((grid (getinput)) (grid-2 (copy-array grid)) (dims (array-dimensions grid))) (do ((stable nil) (filled 0 )) ((eq stable t) filled) (setf stable t) (setf filled 0) (do ((i 0 (1+ i))) ((> i (1- (car dims)))) (do ((j 0 (1+ j))) ((> j (1- (cadr dims)))) (let ((new (next i j grid dims))) (if (not (eq new (aref grid i j))) (setf stable nil)) (setf (aref grid-2 i j) new) (if (equal \#\\# new) (incf filled))))) (setf grid (copy-array grid-2))))) (defun look (x y dirx diry arr dims) (if (or (> x (1- (car dims))) (< x 0) (> y (1- (cadr dims))) (< y 0)) 0 (if (or (eq (aref arr x y) \#\\#) (eq (aref arr x y) \#\L)) (cval (aref arr x y)) (look (+ x dirx) (+ y diry) dirx diry arr dims)))) (defun next-2 (x y arr dims) (let ((sum (+ (look (1+ x) y 1 0 arr dims) (look (1+ x) (1+ y) 1 1 arr dims) (look x (1+ y) 0 1 arr dims) (look (1- x) (1+ y) -1 1 arr dims) (look (1- x) y -1 0 arr dims) (look (1- x) (1- y) -1 -1 arr dims) (look x (1- y) 0 -1 arr dims) (look (1+ x) (1- y) 1 -1 arr dims))) (state (aref arr x y))) ;(format t "~a,~a: ~a~%" x y sum) (cond ((and (eq state \#\L) (eq sum 0)) \#\\#) ((and (eq state \#\\#) (>= sum 5)) \#\L) (t state)))) (defun part2 () (let\* ((grid (getinput)) (grid-2 (copy-array grid)) (dims (array-dimensions grid))) (do ((stable nil) (filled 0 )) ((eq stable t) filled) (setf stable t) (setf filled 0) (do ((i 0 (1+ i))) ((> i (1- (car dims)))) (do ((j 0 (1+ j))) ((> j (1- (cadr dims)))) (let ((new (next-2 i j grid dims))) (if (not (eq new (aref grid i j))) (setf stable nil)) (setf (aref grid-2 i j) new) (if (equal \#\\# new) (incf filled))))) (setf grid (copy-array grid-2)) )))
archivist/day12.lisparchivist/day12.lisp
(asdf:load-system :split-sequence) (asdf:load-system :iterate) (asdf:load-system :alexandria) (defpackage \#:aoc-12 (:use \#:cl \#:split-sequence \#:iterate \#:alexandria)) (in-package \#:aoc-12) (defun getinput () (let ((in (uiop:read-file-lines "input"))) (mapcar (lambda (x) (list (coerce (subseq x 0 1) &\#39;character) (parse-integer (subseq x 1)))) in))) (defstruct ship (x 0) (y 0) (heading 0)) (defun rot (ship d) (setf (ship-heading ship) (mod (+ d (ship-heading ship)) 360))) (defun f (ship val) (let ((px (round (\* val (cos (\* pi (/ (ship-heading ship) 180)))))) (py (round (\* val (sin (\* -1 pi (/ (ship-heading ship) 180))))))) (move ship px py))) (defun move (ship x y) (setf (ship-x ship) (+ (ship-x ship) x)) (setf (ship-y ship) (+ (ship-y ship) y))) (defun intcmd (ship cmd) (cond ((eq (car cmd) \#\N) (move ship 0 (cadr cmd))) ((eq (car cmd) \#\S) (move ship 0 (\* -1 (cadr cmd)))) ((eq (car cmd) \#\E) (move ship (cadr cmd) 0)) ((eq (car cmd) \#\W) (move ship (\* -1 (cadr cmd)) 0)) ((eq (car cmd) \#\R) (rot ship (cadr cmd))) ((eq (car cmd) \#\L) (rot ship (\* -1 (cadr cmd)))) ((eq (car cmd) \#\F) (f ship (cadr cmd))) )) (defun part1 () (let\* ((in (getinput)) (s (make-ship))) (iter (while in) (let ((c (pop in))) (intcmd s c)) (print s)) (+ (abs (ship-x s)) (abs (ship-y s))))) (defstruct wpt (x 10) (y 1)) (defun wrot (pt val) (let\* ((ang (\* pi (/ val 180))) (oldx (wpt-x pt))) (setf (wpt-x pt) (+ (\* (round (cos ang)) (wpt-x pt)) (\* (round (sin ang)) (wpt-y pt)))) (setf (wpt-y pt) (+ (\* (round (sin (\* -1 ang))) oldx) (\* (round (cos ang)) (wpt-y pt)))))) (defun wmove (pt x y) (setf (wpt-x pt) (+ (wpt-x pt) x)) (setf (wpt-y pt) (+ (wpt-y pt) y))) (defun goto (ship pt val) (iter (repeat val) (setf (ship-x ship) (+ (ship-x ship) (wpt-x pt))) (setf (ship-y ship) (+ (ship-y ship) (wpt-y pt))))) (defun wintcmd (ship pt cmd) (cond ((eq (car cmd) \#\N) (wmove pt 0 (cadr cmd))) ((eq (car cmd) \#\S) (wmove pt 0 (\* -1 (cadr cmd)))) ((eq (car cmd) \#\E) (wmove pt (cadr cmd) 0)) ((eq (car cmd) \#\W) (wmove pt (\* -1 (cadr cmd)) 0)) ((eq (car cmd) \#\R) (wrot pt (cadr cmd))) ((eq (car cmd) \#\L) (wrot pt (\* -1 (cadr cmd)))) ((eq (car cmd) \#\F) (goto ship pt (cadr cmd))))) (defun part2 () (let\* ((in (getinput)) (s (make-ship)) (p (make-wpt))) (iter (while in) (let ((c (pop in))) (wintcmd s p c)) (print s) (print p) ) (+ (abs (ship-x s)) (abs (ship-y s)))))