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" | )get "input.ivy" | ||||||
| sample = 7 7 rho '....#..' '..###.#' '#...#.#' '.#...##' '#.###..' '##.#.##' '.#..#..' | sample = 7 7 rho '....#..' '..###.#' '#...#.#' '.#...##' '#.###..' '##.#.##' '.#..#..' | ||||||
| 
 | 
 | ||||||
| board = sample == '#' | #board = sample == '#' | ||||||
|  | board = input == '#' | ||||||
| #board | #board | ||||||
| 
 | 
 | ||||||
| op north a = 1 flip a | op north a = 1 flip a | ||||||
| @ -11,6 +12,9 @@ op east a = -1 rot a | |||||||
| 
 | 
 | ||||||
| #north 3 3 rho iota 9 | #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 = | op a coalesce b = | ||||||
|     a: a |     a: a | ||||||
|     b |     b | ||||||
| @ -22,43 +26,102 @@ op maybePad a = | |||||||
|     needsPad a: pad a |     needsPad a: pad a | ||||||
|     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 smearWE a = a or (west a) or (east a) | ||||||
| op smearNS a = a or (north a) or (south 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-" | op show a = (text ".#23456789"[1+a]),"\n-" | ||||||
| 
 | 
 | ||||||
| M = 0 | M = 0 | ||||||
| 
 | 
 | ||||||
| a = maybePad board | op axis1 a = 3 1 2 transp a | ||||||
| n = south smearWE a |  | ||||||
| s = north smearWE a |  | ||||||
| e = west smearNS a |  | ||||||
| w = east smearNS a |  | ||||||
| #n |  | ||||||
| 
 | 
 | ||||||
| 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) | op dup4 a = (4,rho a) rho a | ||||||
| rho C | 
 | ||||||
| canMove = a and or/ 3 1 2 transp C # can move if there is an elf nearby | # look in each direction | ||||||
| C2 = (not C) and (rho C) rho canMove # can move in a direction if not alone and there is no elf in that direction | # an elf can move in a direction if there is no elf in said direction and there is an elf somewhere nearby | ||||||
| show C2 | # returns a 4x(rho a) matrix | ||||||
| P1 = max/ p * 3 1 2 transp C2  # select direction | op canMove a = | ||||||
| P2 = p o.== P1   # decompose into 4x?x? matrix |     C = look a | ||||||
| P1; "\n-" |     (not C) and dup4 (a and or/axis1 C) | ||||||
| C3 = (north P2[1]) + (south P2[2]) + (west P2[3]) + (east P2[4]) | 
 | ||||||
| C3; "\n-" | 
 | ||||||
| notBlock = C3 == 1 | # prepare moves | ||||||
| C4 = (lift south notBlock), (lift north notBlock), (lift east notBlock), (lift west notBlock) | # assign each move a priority and take the max | ||||||
| rho C4 | # remove lower priority moves | ||||||
| P3 = P2 and C4 | op p prepare choices = | ||||||
| show P3 |     best = max/ p * axis1 choices  # select best direction | ||||||
| moved = or/ 3 1 2 transp P3 |     p o.== best                    # decompose into 4x?x? matrix | ||||||
| moved | 
 | ||||||
| #a and not moved | # count how many elves want to move to each square | ||||||
| #show P3 | # filter out moves which conflict | ||||||
| B = (a and not moved) + (north P3[1]) + (south P3[2]) + (west P3[3]) + (east P3[4]) | op unblocked moves = | ||||||
| show a |     open = 1 == +/axis1 1 moveNSWE moves | ||||||
| show B |     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