[–] 12 points 10 months ago (1 child)

What bothers me about this specific question, apart from it being dated, is that it breaks the rules of these kind of riddles. They're implied to be in a sort of frictionless sphere universe, the whole preposition is silly except as an abstract puzzle. To then rely on the physical properties of real lamps is cheating. You're supposed to ignore all the real-world aspects of the setting except that one.

  • source
  • [–] 1 point 11 months ago*

    Work: Windows + Rider/WebStorm/etc (I used the IdeaVim plugin before but found there were too many rough edges)

    Home: Debian or OpenBSD + vi or Pluma. I deliberately keep it simple. A terminal, an editor Ctrl+Z, make, fg, that kind of thing. I'm tired of fighting IDEs to get out of my way. Let me type!

  • source
  • [–] 3 points 11 months ago (1 child)

    the trap

    Re. what connections to process or not? That seems to be like one of those that's either completely obvious when you implement your solution one way, and a nasty pitfall when you do it another. In this case, pre-computing the list of pairs to process vs. finding the next one when you need it.

  • source
  • parent
  • context
  • [–] 3 points 11 months ago (1 child)

    C

    Got stuck for a bit on part 1 on a silly mistake in the group (circuit) merging code, where the nodes from one group are reassigned to the other:

    for (i=0; i < nnodes; i++)
            if (nodes[i].group == pair->b->group)
                    nodes[i].group = pair->a->group;
    

    At some point in the loop pair->b.group itself is updated, from then on the check is against the new group value. Oops.

    In the end, my solution's runtime on my (10 year old!) PC is about 160 ms for both parts, which is more than I would like, so maybe I'll look into better set representations.

    Code

    #include <stdio.h>
    #include <stdlib.h>
    #include <inttypes.h>
    #include <assert.h>
    
    #define LEN(a)		(sizeof(a)/sizeof(*(a)))
    #define NPAIRS(x)	((x)*((x)-1)/2)
    
    #define MAXN	1024
    
    struct node { int x,y,z, group; };
    struct pair { struct node *a, *b; int64_t dist_sq; };
    struct group { int count; };
    
    static struct node nodes[MAXN];
    static struct pair pairs[NPAIRS(MAXN)];
    static struct group groups[MAXN];
    
    static int nnodes;
    static int ngroups;
    
    static int64_t
    node_dist_sq(const struct node *a, const struct node *b)
    {
    	return
    	    (int64_t)(a->x - b->x) * (a->x - b->x) +
    	    (int64_t)(a->y - b->y) * (a->y - b->y) +
    	    (int64_t)(a->z - b->z) * (a->z - b->z);
    }
    
    static int
    cmp_pairs(const void *va, const void *vb)
    {
    	const struct pair *a = va;
    	const struct pair *b = vb;
    
    	return
    	    a->dist_sq < b->dist_sq ? -1 :
    	    a->dist_sq > b->dist_sq ?  1 : 0;
    }
    
    static int
    cmp_groups_asc(const void *va, const void *vb)
    {
    	const struct group *a = va;
    	const struct group *b = vb;
    
    	return b->count - a->count;
    }
    
    static void
    merge_groups(int group_a, int group_b)
    {
    	int i;
    
    	if (group_a == group_b)
    		return;
    
    	groups[group_a].count += groups[group_b].count;
    	groups[group_b].count = 0;
    
    	for (i=0; i<nnodes; i++)
    		if (nodes[i].group == group_b)
    			nodes[i].group = group_a;
    	
    	ngroups--;
    }
    
    int
    main()
    {
    	int p1=0,p2=0, p1_limit, i,j, n,p;
    
    	for (; ; nnodes++) {
    		assert(nnodes < MAXN);
    		n = scanf(" %d,%d,%d",
    		    &nodes[nnodes].x,
    		    &nodes[nnodes].y,
    		    &nodes[nnodes].z);
    		if (n < 3)
    			break;
    		nodes[nnodes].group = nnodes;
    		groups[nnodes].count = 1;
    	}
    
    	ngroups = nnodes;
    
    	for (p=0, i=0; i<nnodes-1; i++)
    	for (j=i+1; j<nnodes; j++, p++) {
    		pairs[p].a = &nodes[i];
    		pairs[p].b = &nodes[j];
    		pairs[p].dist_sq = node_dist_sq(&nodes[i], &nodes[j]);
    	}
    
    	qsort(pairs, NPAIRS(nnodes), sizeof(*pairs), cmp_pairs);
    
    	p1_limit = nnodes <= 100 ? 10 : 1000;
    
    	for (i=0; ngroups > 1; i++) {
    		merge_groups(pairs[i].a->group, pairs[i].b->group);
    
    		if (ngroups == 1)
    			p2 = pairs[i].a->x * pairs[i].b->x;
    
    		if (i == p1_limit) {
    			qsort(groups, LEN(groups), sizeof(*groups),
    			    cmp_groups_asc);
    
    			p1 = groups[0].count *
    			     groups[1].count *
    			     groups[2].count;
    		}
    	}
    
    	printf("08: %d %d\n", p1, p2);
    }
    

  • source
  • [–] 2 points 11 months ago* (last edited 11 months ago) (1 child)

    If I understand correctly, your visualization shows up to to 256 unique paths then?

    In this one, every time the beam passes a splitter, the other side is put on a queue, so eventually all possible paths are traced, breadth first. Initially I worked through the options recursively, but that depth-first filling out was boring to look at.

  • source
  • parent
  • context
  • [–] 3 points 11 months ago (3 children)

    Well it uses the input of course but I found that if you make it truly random, the lines mostly go down in a straight line, all bunching up in the middle, which isn't very pleasing. So now the beams have a "current direction" which has a 25% of flipping at every splitter

  • source
  • parent
  • context
  • [–] 8 points 11 months ago* (last edited 11 months ago) (5 children)

    In 16-bit real mode assembly, as a hybrid DOS .COM program and BIOS-bootable disk image. With bonus palette animations! I had the hybrid thing going on before (see the repo), but this is the first time getting something animated.

    Repo | day07.com (12 KB) | full video

    video

  • source
  • [–] 2 points 11 months ago

    C

    Accidentally solved part 2 first but had the foresight to save the code. Otherwise my solution looks similar to what other people are doing, just with more code 😅

    Code

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <inttypes.h>
    #include <assert.h>
    
    #define GW 148
    #define GH 74
    
    static char g[GH][GW];
    static uint64_t dp[2][GW];
    static int w,h;
    
    /* recursively traces beam for part 1, marking visited splitters with 'X' */
    static uint64_t
    solve_p1(int x, int y)
    {
    	if (x<0 || x>=w || y<0 || y>=h || g[y][x] == 'X')
    		return 0;
    	else if (g[y][x] != '^')
    		return solve_p1(x, y+1);
    	else {
    		g[y][x] = 'X';
    		return 1 + solve_p1(x-1, y) + solve_p1(x+1, y);
    	}
    }
    
    /* DP for part 2 */
    static uint64_t
    solve_p2(void)
    {
    	int x,y, odd;
    
    	for (y=h-1; y>=0; y--)
    	for (x=1; x<w-1; x++) {
    		/* only two rows relevant at a time, so don't store any more */
    		odd = y&1;
    
    		if (g[y][x] == 'S') {
    			printf("\n");
    			return dp[!odd][x] + 1;
    		}
    
    		dp[odd][x] = g[y][x] == '^' || g[y][x] == 'X'
    		    ? dp[!odd][x-1] + dp[!odd][x+1] + 1
    		    : dp[!odd][x];
    	}
    
    	return 0;
    }
    
    int
    main()
    {
    	int x,y, sx,sy;
    
    	for (h=0; ; ) {
    		/* one bottom row of padding */
    		assert(h < GH-1);
    		/* input already side padded, plus we have \n\0 */
    		if (!fgets(g[h], GW, stdin))
    			break;
    		/* skip empty rows */
    		for (x=0; g[h][x]; x++)
    			if (g[h][x] == 'S' || g[h][x] == '^')
    				{ h++; break; }
    	}
    
    	w = strlen(g[0])-1; /* strip \n */
    
    	for (y=0; y<h; y++)
    	for (x=0; x<w; x++)
    		if (g[y][x] == 'S')
    			{ sx=x; sy=y; break; }
    
    	printf("07: %"PRIu64" %"PRIu64"\n", solve_p1(sx,sy), solve_p2());
    }
    

  • source
  •  

    I have a retail Windows 7 Home Premium license, which allows for moving between machines. I upgraded it to Windows 8 and 10 through their respective programs and I could upgrade to 11 if it were to support my PC, but it doesn't.

    So I want to move the license to my newer laptop (13th gen Intel Framework 13). I could install Windows 10 with my Windows 7 key and then upgrade to Windows 11, but unfortunately the laptop doesn't support 10, not even enough to just install. And Windows 11 doesn't accept my Windows 7 key.

    Any ideas? One thing I considered is booting from USB, attach the system storage to a VM, install Windows 10 there, upgrade to 11 and then reboot into it natively, but maybe there's a better way.

    (I'm not intent on buying a new Windows 11 license, I own a license for 10 that can be moved and upgraded)

    Fixed!

    This is what I had to do, in the end, to transfer the retail license from my Windows 10 PC to a Windows 11 laptop:

    1. Link the Windows 10 license to my Microsoft account. First my Windows 10 activation status showed "activated with a digital license", switching to a Microsoft account associated the license with that account, making it show "activated with a digital license connected to your Microsoft account"

    2. Install Windows 11 on the laptop. Choose "I don't have a product key" during installation.

    3. In the Windows 11 activation settings, use the troubleshooter, select the "I changed my hardware" option. It should spin for a bit and then give an option to show devices to transfer the license from. (This first failed for me with a generic error message, fixed by reinstalling Windows 11)

    4. Choose the old system to transfer the license. (My Windows 10 system wasn't listed the first time, I had to convert its account to local and then back to an MS account for it to show up)

    The old Windows 7 key w/Windows 10 upgrade path was a massive red herring, that option was closed in 2023.

     

    My 1440p monitor died on me so I'm looking to upgrade to a 4K monitor, to be used with my home+work laptops, some older game consoles and an aging Linux PC.

    The aging PC is the problem: it's an i5-6600 on an Asus B150M-A. It lacks DP and its HDMI port can't do 4k60.

    I vaguely recall there being super cheap graphics cards meant for exactly this sort of thing, just a low end GPU with a bunch of ports, but I can't seem to find much, especially not AMD (Linux + Nvidia remains meh)

    Suggestions? Perhaps a minimally invasive upgrade to the PC? Or just stick it out at 1440p (non-integer scaling, ugh) until I can upgrade properly?

    view more: next ›