• 9 Posts
  • 202 Comments
Joined 2 years ago
cake
Cake day: June 12th, 2023

help-circle


  • iPhone SE2:

    1. Use until it turns off due to empty battery
    2. Put on charger, wait for it to boot.
    3. Unlock at the earliest opportunity.

    Problem: after unlocking, the background disappears (goes black).

    Only the home screen though, the lock screen wallpaper works. ‘Fix’ is to change the wallpaper.





  • I did get the M30. It’s delightful but there’s one problem - it looks like The Lion King is one of the few games the Retro Receiver has a problem with. Any button presses while holding a direction on the D-pad interrupt the direction on the D-pad. So a roll becomes a crouch and a running jump becomes a standing jump. I’ve reached out to support, hopefully they can help, otherwise I’ll have to return it.










  • It was surreal to read about talk of extremism, social disruption and the calls for corporal punishment (by police), long jail sentences and more, all for a 5-10 minute delay caused by the A12 blockade, when the day after I was helping out at the Egmond Half Marathon there was real disruption, where people really couldn’t go places with their cars… not to mention events like the Dam tot Damloop or Amsterdam Marathon that effectively put parts of our capital city on lockdown. No calls for water cannons there.

    People might say “Those are not the same!” and that’s true - sport events are not a constitutional right.






  • C

    Merry Christmas everyone!

    Code
    #include "common.h"
    
    int
    main(int argc, char **argv)
    {
    	static char buf[7];
    	static short h[500][5];	/* heights */
    	static short iskey[500];
    	int p1=0, nh=0, i,j,k;
    
    	if (argc > 1)
    		DISCARD(freopen(argv[1], "r", stdin));
    	
    	for (nh=0; !feof(stdin) && !ferror(stdin); nh++) {
    		assert(nh < (int)LEN(h));
    
    		for (i=0; i<7; i++) {
    			fgets(buf, 7, stdin);
    			if (i==0)
    				iskey[nh] = buf[0] == '#';
    			for (j=0; j<5; j++)
    				h[nh][j] += buf[j] == '#';
    		}
    
    		/* skip empty line */
    		fgets(buf, 7, stdin);
    	}
    
    	for (i=0; i<nh; i++)
    	for (j=0; j<nh; j++)
    		if (iskey[i] && !iskey[j]) {
    			for (k=0; k<5 && h[i][k] + h[j][k] <= 7; k++) ;
    			p1 += k == 5;
    		}
    
    	printf("25: %d\n", p1);
    	return 0;
    }
    

    https://codeberg.org/sjmulder/aoc/src/branch/master/2024/c/day25.c

    Made the 1 second challenge with most of it to spare! 😎

    $ time bmake bench                                                                                                      
    day01  0:00.00  1912 Kb  0+88 faults                                                                                            
    day02  0:00.00  1992 Kb  0+91 faults 
    day03  0:00.00  1920 Kb  0+93 faults
    day04  0:00.00  1912 Kb  0+90 faults 
    day05  0:00.00  2156 Kb  0+91 faults
    day06  0:00.03  1972 Kb  0+100 faults
    day07  0:00.06  1892 Kb  0+89 faults
    day08  0:00.00  1772 Kb  0+87 faults 
    day09  0:00.02  2024 Kb  0+137 faults
    day10  0:00.00  1876 Kb  0+87 faults 
    day11  0:00.00  6924 Kb  0+3412 faults
    day12  0:00.00  1952 Kb  0+103 faults
    day13  0:00.00  1908 Kb  0+88 faults
    day14  0:00.05  1944 Kb  0+92 faults                                                                                            
    day15  0:00.00  2040 Kb  0+89 faults
    day16  0:00.03  2020 Kb  0+250 faults
    day17  0:00.00  1896 Kb  0+88 faults
    day18  0:00.00  1952 Kb  0+107 faults
    day19  0:00.01  1904 Kb  0+91 faults
    day20  0:00.01  2672 Kb  0+325 faults
    day21  0:00.00  1804 Kb  0+86 faults
    day22  0:00.03  2528 Kb  0+371 faults
    day23  0:00.02  2064 Kb  0+152 faults
    day24  0:00.00  1844 Kb  0+89 faults
    day25  0:00.00  1788 Kb  0+89 faults  
                                                                    
    real    0m0,359s
    

  • Oh my Kernigan, that was stressful. Really worried about not finishing there.

    Considered several approaches, the coolest of which would have been to test individual bits, propagate ‘suspicion’, etc, but it seemed too tricky.

    Eventually I needed to go do something other than worry about not finishing so I started writing a validator for the adder structure. Just a couple of rules later I had found 4 faults already and managed to write automated fixups for them!

    This means my solver is quite specific to my input but it can potentially be made more complete and I didn’t ‘cheat’ by hardcoding manual graph analysis.

    Code
    #include "common.h"
    
    /*
     * The approach behind part 2 was to essentially write a bunch of
     * validation rules for the structure of the adder, and then writing
     * fixups for problems it would find. That means it's likely quite
     * tailored to my input, but at least it's not hardcoding manual graph
     * analysis.
     */
    
    enum { W_NULL, W_OFF, W_ON };
    
    struct wire;
    
    struct wire {
    	struct wire *in[2];
    	char name[4];
    	char op; 		/* [A]ND, [O]R, [X]OR */
    	int8_t val;		/* W_NULL, W_OFF, W_ON */
    };
    
    static struct wire wires[320];
    static struct wire *zs[46], *swapped[8];
    static int nw, nsw;
    
    static struct wire *
    get_wire(const char *name)
    {
    	int i;
    
    	for (i=0; i<nw; i++)
    		if (!strcmp(name, wires[i].name))
    			return &wires[i];
    
    	assert(nw < (int)LEN(wires));
    	assert(strlen(name) < LEN(wires[i].name));
    
    	snprintf(wires[nw].name, sizeof(wires[nw].name), "%s", name);
    	return &wires[nw++];
    }
    
    
    static int
    cmp_wires(const void *a, const void *b)
    {
    	struct wire * const *wa = a;
    	struct wire * const *wb = b;
    
    	return strcmp((*wa)->name, (*wb)->name);
    }
    
    static int
    eval(struct wire *wire)
    {
    	int in1,in2;
    
    	if (wire->val)
    		return wire->val == W_ON;
    
    	assert(wire->in[0]);
    	assert(wire->in[1]);
    
    	in1 = eval(wire->in[0]);
    	in2 = eval(wire->in[1]);
    
    	wire->val = W_OFF + (
    	    wire->op=='A' ? in1 && in2 :
    	    wire->op=='O' ? in1 || in2 :
    	    wire->op=='X' ? in1 != in2 : (assert(!"bad op"), -1));
    
    	return wire->val == W_ON;
    }
    
    static void
    swap(struct wire *a, struct wire *b)
    {
    	struct wire tmp;
    
    	//printf("swapping %s and %s\n", a->name, b->name);
    
    	tmp = *a;
    
    	a->op = b->op;
    	a->in[0] = b->in[0];
    	a->in[1] = b->in[1];
    
    	b->op = tmp.op;
    	b->in[0] = tmp.in[0];
    	b->in[1] = tmp.in[1];
    
    	assert(nsw+2 <= (int)LEN(swapped));
    	swapped[nsw++] = a;
    	swapped[nsw++] = b;
    }
    
    static struct wire *
    find_z_xor(int bit)
    {
    	struct wire *xy_xor;
    	int i;
    
    	for (i=0; i<nw; i++) {
    		 /* must be a XOR */
    		if (wires[i].op != 'X')
    			continue;
    
    		 /* with an input XOR */
    		xy_xor = wires[i].in[0]->op == 'X' ? wires[i].in[0] :
    		         wires[i].in[1]->op == 'X' ? wires[i].in[1] :
    		         NULL;
    		if (!xy_xor)
    			continue;
    
    		 /* connected to the X and Y */
    		if (xy_xor->in[0]->name[0] != 'x' &&
    		    xy_xor->in[0]->name[0] != 'y')
    			continue;
    
    		 /* with the same bit number */
    		if (atoi(xy_xor->in[0]->name+1) != bit)
    			continue;
    
    		return &wires[i];
    	}
    
    	return NULL;
    }
    
    static struct wire *
    find_xy_and(int bit)
    {
    	int i;
    
    	for (i=0; i<nw; i++) {
    		 /* must be AND */
    		if (wires[i].op != 'A')
    			continue;
    
    		 /* must have XY inputs */
    		if ((wires[i].in[0]->name[0] != 'x'  ||
    		     wires[i].in[1]->name[0] != 'y') &&
    		    (wires[i].in[0]->name[0] != 'y'  ||
    		     wires[i].in[1]->name[0] != 'x'))
    			continue;
    		
    		 /* with the right bit number */
    		if (atoi(wires[i].in[0]->name+1) != bit ||
    		    atoi(wires[i].in[0]->name+1) != bit)
    			continue;
    		
    		return &wires[i];
    	}
    
    	return NULL;
    }
    
    static void
    fsck_carry_or(struct wire *or, int bit)
    {
    	struct wire *wire;
    	int i;
    
    	 /* both inputs must be AND; no fixup if neither */
    	assert(
    	    or->in[0]->op == 'A' ||
    	    or->in[1]->op == 'A');
    
    	for (i=0; i<2; i++) {
    		if (or->in[i]->op == 'A')
    			continue;
    
    		//printf("carry OR parent %s not AND\n", or->in[i]->name);
    
    		 /* only have fixup for the XY AND */
    		assert(
    		    or->in[!i]->in[0]->name[0] != 'x' &&
    		    or->in[!i]->in[0]->name[0] != 'y');
    
    		wire = find_xy_and(bit);
    		assert(wire);
    		swap(or->in[i], wire);
    	}
    }
    
    static void
    fsck_z(struct wire *z)
    {
    	struct wire *wire, *carry_or;
    	int bit;
    
    	assert(z->name[0] == 'z');
    
    	bit = atoi(z->name+1);
    
    	 /* first bit is very different */
    	if (!bit)
    		return;
    
    	 /* for the final bit, Z is the carry OR */
    	if (!zs[bit+1]) {
    		 /* no fixup if it isn't */
    		assert(z->op == 'O');
    
    		fsck_carry_or(z, bit-1);
    		return;
    	}
    
    	 /* must be a XOR */
    	if (z->op != 'X') {
    		//printf("Z %s isn't XOR\n", z->name);
    		wire = find_z_xor(bit);
    		assert(wire);
    		swap(z, wire);
    	}
    
    	 /* bit 2 and up must have a carry OR */
    	if (bit > 1) {
    		carry_or =
    		    z->in[0]->op == 'O' ? z->in[0] :
    		    z->in[1]->op == 'O' ? z->in[1] : NULL;
    		assert(carry_or);
    		fsck_carry_or(carry_or, bit-1);
    	}
    }
    
    int
    main(int argc, char **argv)
    {
    	struct wire *wire;
    	char buf[64], *rest, *lf, *name1,*name2, *opstr;
    	uint64_t p1=0;
    	int bit, i;
    
    	if (argc > 1)
    		DISCARD(freopen(argv[1], "r", stdin));
    
    	while ((rest = fgets(buf, sizeof(buf), stdin))) {
    		if (!strchr(buf, ':'))
    			break;
    
    		wire = get_wire(strsep(&rest, ":"));
    		wire->val = W_OFF + atoi(rest);
    
    	}
    
    	while ((rest = fgets(buf, sizeof(buf), stdin))) {
    		if ((lf = strchr(buf, '\n')))
    			*lf = '\0';
    
    		name1 = strsep(&rest, " ");
    		opstr = strsep(&rest, " ");
    		name2 = strsep(&rest, " ");
    		strsep(&rest, " ");
    
    		wire = get_wire(rest);
    		wire->in[0] = get_wire(name1);
    		wire->in[1] = get_wire(name2);
    		wire->op = opstr[0];
    	}
    
    	for (i=0; i<nw; i++)
    		if (wires[i].name[0] == 'z') {
    			bit = atoi(&wires[i].name[1]);
    			assert(bit >= 0);
    			assert(bit < (int)LEN(zs));
    			zs[bit] = &wires[i];
    		}
    
    	for (i=0; i < (int)LEN(zs); i++)
    		if (zs[i])
    			p1 |= (uint64_t)eval(zs[i]) << i;
    
    	for (i=0; i < (int)LEN(zs); i++)
    		if (zs[i])
    			fsck_z(zs[i]);
    
    	qsort(swapped, nsw, sizeof(*swapped), cmp_wires);
    
    	printf("24: %"PRIu64, p1);
    
    	for (i=0; i<nsw; i++)
    		printf(i ? ",%s" : " %s", swapped[i]->name);
    
    	putchar('\n');
    	return 0;
    }
    

    https://codeberg.org/sjmulder/aoc/src/branch/master/2024/c/day24.c

    Btw, spending some time on getting Graphviz output right did make studying the structure much easier!

    Graph snippet