day 23 ivy solution
part 2 is very slow; takes about ~2min on my machine
This commit is contained in:
		
							parent
							
								
									540bbb9a9e
								
							
						
					
					
						commit
						98a4dffb3c
					
				
							
								
								
									
										125
									
								
								day23/sol.ivy
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								day23/sol.ivy
									
									
									
									
									
								
							| @ -1,7 +1,8 @@ | ||||
| )get "input.ivy" | ||||
| sample = 7 7 rho '....#..' '..###.#' '#...#.#' '.#...##' '#.###..' '##.#.##' '.#..#..' | ||||
| 
 | ||||
| board = sample == '#' | ||||
| #board = sample == '#' | ||||
| board = input == '#' | ||||
| #board | ||||
| 
 | ||||
| op north a = 1 flip a | ||||
| @ -11,6 +12,9 @@ op east a = -1 rot a | ||||
| 
 | ||||
| #north 3 3 rho iota 9 | ||||
| 
 | ||||
| op lift a = (1,rho a) rho a | ||||
| op n moveNSWE a = (lift n flip a[1]), (lift (-n) flip a[2]), (lift n rot a[3]), (lift (-n) rot a[4]) | ||||
| 
 | ||||
| op a coalesce b = | ||||
|     a: a | ||||
|     b | ||||
| @ -22,43 +26,102 @@ op maybePad a = | ||||
|     needsPad a: pad a | ||||
|     a | ||||
| 
 | ||||
| op maybePad1 a = | ||||
|     c1 = any a[1] | ||||
|     c2 = any a[(rho a)[1]] | ||||
|     c1 and c2: 0,a,0 | ||||
|     c1: 0,a | ||||
|     c2: a,0 | ||||
|     a | ||||
| 
 | ||||
| op maybePad a = | ||||
|     a = maybePad1 a | ||||
|     (any a[;1]) or (any a[;(rho a)[2]]): transp maybePad1 transp a | ||||
|     a | ||||
| 
 | ||||
| op smearWE a = a or (west a) or (east a) | ||||
| op smearNS a = a or (north a) or (south a) | ||||
| op lift a = (1,rho a) rho a | ||||
| 
 | ||||
| op show a = (text ".#23456789"[1+a]),"\n-" | ||||
| 
 | ||||
| M = 0 | ||||
| 
 | ||||
| a = maybePad board | ||||
| n = south smearWE a | ||||
| s = north smearWE a | ||||
| e = west smearNS a | ||||
| w = east smearNS a | ||||
| #n | ||||
| op axis1 a = 3 1 2 transp a | ||||
| 
 | ||||
| p = 4 3 2 1 | ||||
| op look a = | ||||
|     ns = lift smearNS a | ||||
|     we = lift smearWE a | ||||
|     -1 moveNSWE (we, we, ns, ns) | ||||
| 
 | ||||
| C = (lift n) , (lift s) , (lift w) , (lift e) | ||||
| rho C | ||||
| canMove = a and or/ 3 1 2 transp C # can move if there is an elf nearby | ||||
| C2 = (not C) and (rho C) rho canMove # can move in a direction if not alone and there is no elf in that direction | ||||
| show C2 | ||||
| P1 = max/ p * 3 1 2 transp C2  # select direction | ||||
| P2 = p o.== P1   # decompose into 4x?x? matrix | ||||
| P1; "\n-" | ||||
| C3 = (north P2[1]) + (south P2[2]) + (west P2[3]) + (east P2[4]) | ||||
| C3; "\n-" | ||||
| notBlock = C3 == 1 | ||||
| C4 = (lift south notBlock), (lift north notBlock), (lift east notBlock), (lift west notBlock) | ||||
| rho C4 | ||||
| P3 = P2 and C4 | ||||
| show P3 | ||||
| moved = or/ 3 1 2 transp P3 | ||||
| moved | ||||
| #a and not moved | ||||
| #show P3 | ||||
| B = (a and not moved) + (north P3[1]) + (south P3[2]) + (west P3[3]) + (east P3[4]) | ||||
| show a | ||||
| show B | ||||
| op dup4 a = (4,rho a) rho a | ||||
| 
 | ||||
| # look in each direction | ||||
| # an elf can move in a direction if there is no elf in said direction and there is an elf somewhere nearby | ||||
| # returns a 4x(rho a) matrix | ||||
| op canMove a = | ||||
|     C = look a | ||||
|     (not C) and dup4 (a and or/axis1 C) | ||||
| 
 | ||||
| 
 | ||||
| # prepare moves | ||||
| # assign each move a priority and take the max | ||||
| # remove lower priority moves | ||||
| op p prepare choices = | ||||
|     best = max/ p * axis1 choices  # select best direction | ||||
|     p o.== best                    # decompose into 4x?x? matrix | ||||
| 
 | ||||
| # count how many elves want to move to each square | ||||
| # filter out moves which conflict | ||||
| op unblocked moves = | ||||
|     open = 1 == +/axis1 1 moveNSWE moves | ||||
|     moves and -1 moveNSWE dup4 open | ||||
| 
 | ||||
| priority = 4 3 2 1 | ||||
| M = 0 | ||||
| changed = 0 | ||||
| 
 | ||||
| op M round a = | ||||
|     a = maybePad a | ||||
|     moves = unblocked (M flip priority) prepare canMove a | ||||
|     moved = or/axis1 moves | ||||
|     changed; changed = +/, moved | ||||
|     b = (a and not moved) + +/axis1 1 moveNSWE moves | ||||
|     b | ||||
| 
 | ||||
| op round a = M round a | ||||
| 
 | ||||
| # this is implemented using globals | ||||
| # to store the board instead of recursion | ||||
| # in order to avoid keeping a bunch of large | ||||
| # intermediate values alive on the stack | ||||
| B = 0 | ||||
| op i loop n = | ||||
|     i > n: i | ||||
|     changed; changed = 0 | ||||
|     B = M round B | ||||
|     M = M - 1 | ||||
|     changed == 0: i | ||||
|     (i+1) loop n | ||||
| 
 | ||||
| op n rounds a = | ||||
|     B; B = a | ||||
|     M; M = 0 | ||||
|     1 loop n | ||||
|     B | ||||
| 
 | ||||
| op n numrounds a = | ||||
|     B; B = a | ||||
|     M; M = 0 | ||||
|     1 loop n | ||||
| 
 | ||||
| op score a = | ||||
|     a = maybePad a | ||||
|     n = */ (rho a) - 2 | ||||
|     n - +/, a | ||||
| 
 | ||||
| show round board | ||||
| show 10 rounds board | ||||
| score 10 rounds board | ||||
| 
 | ||||
| 1000 numrounds board | ||||
| #numrounds board | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user