Advertisement
Guest User

Untitled

a guest
Dec 21st, 2021
1,386
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.29 KB | None | 0 0
  1. import numpy as np
  2.  
  3. def part_1():
  4.   #part 1 is pretty easy, we just make an array of the size we need, and do the operations
  5.   #Note that I just manually deleted the items outside the valid range from the
  6.   #input file (they all come before the invalid ones)
  7.   #that was faster than writing code to filter them
  8.   handle = open('22a.txt','r')
  9.   data = np.zeros((101,101,101))
  10.   for line in handle:
  11.     #kinda gross line splitting
  12.     items = line.split(' ')
  13.     if items[0] == 'on':
  14.       value = 1
  15.     else:
  16.       value = 0
  17.     #rather than parse x,y,z, just use the fact that they appear in order
  18.     ranges = [x[2:] for x in items[1].split(',')]
  19.     #get the start and end values, shift up by 50 so we're all non-negative
  20.     x_start,x_end = [int(x)+50 for x in ranges[0].split("..")]
  21.     y_start,y_end = [int(x)+50 for x in ranges[1].split("..")]
  22.     z_start,z_end = [int(x)+50 for x in ranges[2].split("..")]
  23.     #do the assignment
  24.     data[x_start:x_end+1,y_start:y_end+1,z_start:z_end+1] = value
  25.  
  26.   print(np.sum(data))
  27.  
  28. def part_2():
  29.  
  30.   #part 2 is trickier.  The plan is to keep a list of cubes and their values
  31.   #and then when an existing cube is intersected by a new cube, carve what remains
  32.   #up into several smaller cubes, and carry on
  33.   #(note that 'cubes' are actually 'rectangular prisms')
  34.  
  35.   #the basic idea behind carving up remainders is to first take all the stuff
  36.   #to the left of the intersection and make that a cube, then do the same for the right
  37.   #then above and below, then in front and behind.  Each time we carve off a slice,
  38.   #we remove it from the original cube so that we don't double-cover it in the next
  39.   #slice, and so on.
  40.  
  41.   handle = open('22a.txt','r')
  42.   data = [] #this will be our list of cubes
  43.   for line in handle:
  44.     items = line.split(' ')
  45.     if items[0] == 'on':
  46.       value = 1
  47.     else:
  48.       value = 0
  49.     ranges = [x[2:] for x in items[1].split(',')]
  50.     x_start,x_end = [int(x) for x in ranges[0].split("..")]
  51.     y_start,y_end = [int(x) for x in ranges[1].split("..")]
  52.     z_start,z_end = [int(x) for x in ranges[2].split("..")]
  53.     #it's easier to do inclusive start indices and exclusive end indices,
  54.     #at least for me.  You could do it either way.
  55.     x_end+=1
  56.     y_end+=1
  57.     z_end+=1
  58.     #a cube is a 7-tuple (actually a list so we can modify it), as follows:
  59.     cube = [x_start,x_end,y_start,y_end,z_start,z_end,value]
  60.     #we'll put all the new cubes into this list
  61.     new_items = []
  62.     for i in range(len(data)):
  63.       #loop through all the existing cubes and check whether they intersect.
  64.       #I originally made this an index-loop because i was going to `del`
  65.       #the indices from the list, but then I decided it was simpler to just make
  66.       #a new one each loop
  67.       item = data[i]
  68.      
  69.       #in order to intersect, we must overlap in x, y and z
  70.       x_overlap = x_end > item[0] and x_start < item[1]
  71.       y_overlap = y_end > item[2] and y_start < item[3]
  72.       z_overlap = z_end > item[4] and z_start < item[5]
  73.       if x_overlap and y_overlap and z_overlap:
  74.        
  75.         #now we check for each of the possible 'left-over' slices,
  76.         #left, right, up, down, front back
  77.         if item[0] < x_start:
  78.           #if the left edge of this cube is to the left of the new one,
  79.           #then it's going to have a left-over slice on the left side.
  80.           #this left-over slice is everything to the left of the new cube
  81.           #so its x_end value will be the *x_start* of the new cube
  82.           new_item = [item[0],x_start,item[2],item[3],item[4],item[5],item[6]]
  83.           #we've already accounted for everything to the left of here, so remove it
  84.           #from the cube to avoid double counting
  85.           item[0] = x_start
  86.           #add the slice to our new list
  87.           new_items.append(new_item)
  88.         #repeat for the five other directions, all the exact same idea
  89.         if item[1] > x_end:
  90.           new_item = [x_end,item[1],item[2],item[3],item[4],item[5],item[6]]
  91.           item[1] = x_end
  92.           new_items.append(new_item)
  93.         if item[2] < y_start:
  94.           new_item = [item[0],item[1],item[2],y_start,item[4],item[5],item[6]]
  95.           item[2] = y_start
  96.           new_items.append(new_item)        
  97.         if item[3] > y_end:
  98.           new_item = [item[0],item[1],y_end,item[3],item[4],item[5],item[6]]
  99.           item[3] = y_end
  100.           new_items.append(new_item)
  101.         if item[4] < z_start:
  102.           new_item = [item[0],item[1],item[2],item[3],item[4],z_start,item[6]]
  103.           item[4] = z_start
  104.           new_items.append(new_item)        
  105.         if item[5] > z_end:
  106.           new_item = [item[0],item[1],item[2],item[3],z_end,item[5],item[6]]
  107.           item[5] = z_end
  108.           new_items.append(new_item)
  109.       else:
  110.         #if we didn't intersect at all, just keep the cube
  111.         new_items.append(item)
  112.    
  113.     #add our new one
  114.     new_items.append(cube)
  115.     #update the list for the next pass
  116.     data = new_items
  117.  
  118.   #sum up the total number of cells that are on
  119.   total = 0
  120.   for i in range(len(data)): #I don't know why this is index-based
  121.     item = data[i]
  122.     if item[6]==1: #only count cells that are on!
  123.       #add the total area of the cube
  124.       total+=(item[1]-item[0])*(item[3]-item[2])*(item[5]-item[4])
  125.  
  126.   print(total)
  127.  
  128.  
  129.  
  130. part_2()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement