diff options
| author | Adam Spragg <adam@spra.gg> | 2022-12-20 19:02:04 +0000 | 
|---|---|---|
| committer | Adam Spragg <adam@spra.gg> | 2022-12-20 19:02:04 +0000 | 
| commit | e17a454221a6539640e3ea9b5f4cdfbd5471fa3a (patch) | |
| tree | 1fc5e3b1e070d0253e88f010d4a7dbcd3427fbd5 | |
| parent | e5829c438669e8b12236aaccd5b0c7c0c51e800d (diff) | |
Solve puzzle 20 part 2
Phew. Nice easy one for today! Caught up now.
| -rw-r--r-- | 20.c | 91 | 
1 files changed, 69 insertions, 22 deletions
| @@ -2,11 +2,12 @@  #include <stdio.h>  #include <stdlib.h>  #include <string.h> +#include <unistd.h>  struct num { -	int val; -	int ord; +	long val; +	long ord;  }; @@ -17,11 +18,54 @@ struct num {  int -main() +main(int argc, char ** argv)  { +	long key = 1, rounds = 1;  	char buf[BUFSIZ];  	struct num * nums = NULL; -	int nnums = 0, numsize = 0, i, pos; +	int nnums = 0, numsize = 0, r, i, pos; + +	// Parse options +	while ((i = getopt(argc, argv, "p:k:r:")) != -1) { +		switch (i) { +		case 'p': +			switch (atoi(optarg)) { +			case 1: +				key = 1; +				rounds = 1; +				break; + +			case 2: +				key = 811589153; +				rounds = 10; +				break; + +			default: +				fprintf(stderr, "Invalid part %s\n", optarg); +				return -1; +			} +			break; + +		case 'k': +			key = atoi(optarg); +			if (!key) { +				fprintf(stderr, "Invalid key %s\n", optarg); +				return -1; +			} +			break; + +		case 'r': +			rounds = atoi(optarg); +			if (rounds < 0) { +				fprintf(stderr, "Invalid rounds %s\n", optarg); +				return -1; +			} +			break; + +		default: +			return -1; +		} +	}  	// Read file.  	while (fgets(buf, sizeof(buf), stdin)) { @@ -46,33 +90,36 @@ main()  			free(nums);  			return -1;  		} +		nums[nnums].val *= key;  		nums[nnums].ord = nnums;  		++nnums;  	}  	// Mix file. -	for (i = 0, pos = 0; i < nnums; ++i) { -		int newpos; -		struct num tmp; +	for (r = 0; r < rounds; ++r) { +		for (i = 0, pos = 0; i < nnums; ++i) { +			int newpos; +			struct num tmp; -		// Look for the num whose ordinal is i, starting from the -		// position of the last num we looked at. -		while (nums[pos].ord != i) -			pos = modulo(pos + 1, nnums); +			// Look for the num whose ordinal is i, starting from the +			// position of the last num we looked at. +			while (nums[pos].ord != i) +				pos = modulo(pos + 1, nnums); -		if (nums[pos].val == 0) -			continue; +			if (nums[pos].val == 0) +				continue; -		// Move this. -		tmp = nums[pos]; +			// Move this. +			tmp = nums[pos]; -		newpos = modulo(pos + nums[pos].val, nnums - 1); // Buffer of nums does not include moving num -		if (newpos > pos) -			memmove(nums + pos, nums + pos + 1, (newpos - pos) * sizeof(struct num)); -		else -			memmove(nums + newpos + 1, nums + newpos, (pos - newpos) * sizeof(struct num)); +			newpos = modulo(pos + nums[pos].val, nnums - 1); // Buffer of nums does not include moving num +			if (newpos > pos) +				memmove(nums + pos, nums + pos + 1, (newpos - pos) * sizeof(struct num)); +			else +				memmove(nums + newpos + 1, nums + newpos, (pos - newpos) * sizeof(struct num)); -		nums[newpos] = tmp; +			nums[newpos] = tmp; +		}  	}  	// Find zero. @@ -85,7 +132,7 @@ main()  		return -1;  	} -	printf("Coords: %d,%d,%d; sum %d\n", +	printf("Coords: %ld,%ld,%ld; sum %ld\n",  			nums[modulo(i + 1000, nnums)].val,  			nums[modulo(i + 2000, nnums)].val,  			nums[modulo(i + 3000, nnums)].val, | 
