Day 7: Bridge Repair

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • sjmulder@lemmy.sdf.org
    link
    fedilink
    arrow-up
    3
    ·
    17 days ago

    C

    Big integers and overflow checking, what else is there to say 😅​

    Code
    #include "common.h"
    
    /* returns 1 on sucess, 0 on overflow */
    static int
    concat(uint64_t a, uint64_t b, uint64_t *out)
    {
    	uint64_t mul;
    
    	for (mul=1; mul<=b; mul*=10) ;
    
    	return 
    	    !__builtin_mul_overflow( mul, a, out) &&
    	    !__builtin_add_overflow(*out, b, out);
    }
    
    static int
    recur(uint64_t expect, uint64_t acc, uint64_t arr[], int n, int p2)
    {
    	uint64_t imm;
    
    	return
    	    n < 1 ? acc == expect :
    	    acc >= expect ? 0 :
    	    recur(expect, acc + arr[0], arr+1, n-1, p2) ||
    	    recur(expect, acc * arr[0], arr+1, n-1, p2) ||
    	    (p2 && concat(acc, arr[0], &imm)
    	        && recur(expect, imm, arr+1, n-1, p2));
    }
    
    int
    main(int argc, char **argv)
    {
    	char buf[128], *tok, *rest;
    	uint64_t p1=0, p2=0, arr[32], expect;
    	int n;
    
    	if (argc > 1)
    		DISCARD(freopen(argv[1], "r", stdin));
    	
    	while ((rest = fgets(buf, sizeof(buf), stdin))) {
    		assert(strchr(buf, '\n'));
    		expect = atoll(strsep(&rest, ":"));
    
    		for (n=0; (tok = strsep(&rest, " ")); n++) {
    			assert(n < (int)LEN(arr));
    			arr[n] = atoll(tok);
    		}
    
    		p1 += recur(expect, 0, arr, n, 0) * expect;
    		p2 += recur(expect, 0, arr, n, 1) * expect;
    	}
    
    	printf("07: %"PRIu64" %"PRIu64"\n", p1, p2);
    	return 0;
    }
    

    https://github.com/sjmulder/aoc/blob/master/2024/c/day07.c