Guest User

Untitled

a guest
Dec 20th, 2020
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MatLab 6.29 KB | None | 0 0
  1. clc
  2. clear
  3. close all
  4.  
  5. tic
  6. disp('starting...')
  7.  
  8. x = importdata('input.txt');
  9. L = size(x,1);
  10. for i=1:L/11
  11.     z = x{(i-1)*11+1};
  12.     T(i,1).ID   =  str2double(z(6:9));
  13.     T(i,1).p    =  cell2mat(x((i-1)*11+2:(i-1)*11+11,:))=='#';
  14. end
  15.  
  16. for i=1:size(T,1)
  17.     x = T(i).p;
  18.     % find number of connecting pieces for x
  19.     connectedID = [];
  20.     for j=1:size(T,1)
  21.         if j==i
  22.             continue
  23.         end
  24.        
  25.         z=shareEdge(x,T(j).p);
  26.         if z
  27.             connectedID(end+1,1) = T(j).ID;
  28.         end
  29.     end
  30.     T(i).connectedID = connectedID;
  31. end
  32.  
  33. z=[];
  34. for i=1:size(T,1)
  35.     if size(T(i).connectedID,1)==2
  36.         z = [z,T(i).ID];
  37.     end
  38.     T(i).aligned = false;
  39. end
  40. format long
  41. disp(prod(z)) % Answer Part a
  42.  
  43. % align pieces
  44. allAligned = false;
  45. while ~allAligned
  46.    
  47.     T(1).aligned = true;
  48.     for i=1:size(T,1)
  49.         if T(i).aligned
  50.             for j=1:size(T(i).connectedID,1)
  51.                 idxK = ID2idx(T,T(i).connectedID(j));
  52.                 if ~T(idxK).aligned
  53.                     T(idxK).p       = alignPieces(T(i).p,T(idxK).p);
  54.                     T(idxK).aligned = true;
  55.                 end
  56.             end
  57.         end
  58.     end
  59.    
  60.     %Check if all aligned:
  61.     allAligned = true;
  62.     for i=1:size(T,1)
  63.         if ~T(i).aligned
  64.             allAligned = false;
  65.             break
  66.         end
  67.     end
  68. end
  69.  
  70. % Find direction of pieces relative to each other
  71. for i=1:size(T,1)
  72.     T(i).connectedIDpos = [];
  73.     for j=1:size(T(i).connectedID,1)
  74.         idxK = ID2idx(T,T(i).connectedID(j));
  75.         T(i).connectedIDpos(j,1) = getRelativePosition(T(i).p,T(idxK).p);
  76.     end
  77. end
  78.  
  79. % Fit pieces together:
  80. % Start with North-West corner, i.e. the piece that has only East and South
  81. % neighbour
  82. for i=1:size(T,1)
  83.     z = T(i).connectedIDpos;
  84.     if length(z)==2 && any(z==2) && any(z==3)
  85.         M(1,1) = T(i).ID;
  86.         break
  87.     end
  88. end
  89.  
  90. % Find pieces connecting to the east
  91. r = 1;
  92. c = 1;
  93. while 1
  94.     c = c + 1;
  95.     z = find(T(ID2idx(T,M(r,c-1))).connectedIDpos==2);
  96.     if isempty(z)
  97.         %reached end of the row
  98.         break
  99.     else
  100.         M(r,c) =  T(ID2idx(T,M(r,c-1))).connectedID(z);
  101.     end
  102. end
  103.  
  104. while 1
  105.     % Next row
  106.     z = find(T(ID2idx(T,M(r,1))).connectedIDpos==3);
  107.    
  108.     if isempty(z)
  109.         %reached end of the column
  110.         break
  111.     else
  112.         r = r+1;
  113.         M(r,1) = T(ID2idx(T,M(r-1,1))).connectedID(z);
  114.        
  115.         % Find pieces connecting to the east
  116.         c = 1;
  117.         while 1
  118.             c = c + 1;
  119.             z = find(T(ID2idx(T,M(r,c-1))).connectedIDpos==2);
  120.             if isempty(z)
  121.                 %reached end of the row
  122.                 break
  123.             else
  124.                 M(r,c) =  T(ID2idx(T,M(r,c-1))).connectedID(z);
  125.             end
  126.         end
  127.        
  128.     end
  129. end
  130.  
  131. % remove edges
  132. for i=1:size(T,1)
  133.     z       = T(i).p;
  134.     T(i).p  = z(2:end-1,2:end-1);
  135. end
  136.  
  137. % Build pixelmap
  138. P = false(size(M,1)*size(T(1).p,1),size(M,2)*size(T(1).p,2));
  139.  
  140. for r=1:size(M,1)
  141.     for c=1:size(M,1)
  142.         P((r-1)*8+1:r*8,(c-1)*8+1:c*8) = T(ID2idx(T,M(r,c))).p;
  143.     end
  144. end
  145.  
  146. % Monster
  147. M       = false(3,20);
  148. M(1,:)  = '                  # '=='#';
  149. M(2,:)  = '#    ##    ##    ###'=='#';
  150. M(3,:)  = ' #  #  #  #  #  #   '=='#';
  151.  
  152. N1 = findMonsters(P,M);
  153. N2 = findMonsters(rot90(P,1),M);
  154. N3 = findMonsters(rot90(P,2),M);
  155. N4 = findMonsters(rot90(P,3),M);
  156.  
  157. N5 = findMonsters(fliplr(P),M);
  158. N6 = findMonsters(rot90(fliplr(P),1),M);
  159. N7 = findMonsters(rot90(fliplr(P),2),M);
  160. N8 = findMonsters(rot90(fliplr(P),3),M);
  161.  
  162. N = max([N1,N2,N3,N4,N5,N6,N7,N8]);
  163. disp(sum(sum(P)) - N * sum(sum(M))) % Answer Part b
  164.  
  165. toc
  166. disp('Finished')
  167.  
  168. % functions:
  169. function z=shareEdge(x,y)
  170. z = false;
  171.  
  172. if all(x(1,:)==y(1,:)) || all(x(1,:)==y(end,:)) || all(x(1,:)==y(:,1)') || all(x(1,:)==y(:,end)') || ...
  173.         all(x(end,:)==y(1,:)) || all(x(end,:)==y(end,:)) || all(x(end,:)==y(:,1)') || all(x(end,:)==y(:,end)') || ...
  174.         all(x(:,1)==y(1,:)') || all(x(:,1)==y(end,:)') || all(x(:,1)==y(:,1)) || all(x(:,1)==y(:,end)) || ...
  175.         all(x(:,end)==y(1,:)') || all(x(:,end)==y(end,:)') || all(x(:,end)==y(:,1)) || all(x(:,end)==y(:,end))
  176.     z = true;
  177.     return
  178. end
  179.  
  180. y = fliplr(y);
  181.  
  182. if all(x(1,:)==y(1,:)) || all(x(1,:)==y(end,:)) || all(x(1,:)==y(:,1)') || all(x(1,:)==y(:,end)') || ...
  183.         all(x(end,:)==y(1,:)) || all(x(end,:)==y(end,:)) || all(x(end,:)==y(:,1)') || all(x(end,:)==y(:,end)') || ...
  184.         all(x(:,1)==y(1,:)') || all(x(:,1)==y(end,:)') || all(x(:,1)==y(:,1)) || all(x(:,1)==y(:,end)) || ...
  185.         all(x(:,end)==y(1,:)') || all(x(:,end)==y(end,:)') || all(x(:,end)==y(:,1)) || all(x(:,end)==y(:,end))
  186.     z = true;
  187.     return
  188. end
  189.  
  190. y = flipud(y);
  191.  
  192. if all(x(1,:)==y(1,:)) || all(x(1,:)==y(end,:)) || all(x(1,:)==y(:,1)') || all(x(1,:)==y(:,end)') || ...
  193.         all(x(end,:)==y(1,:)) || all(x(end,:)==y(end,:)) || all(x(end,:)==y(:,1)') || all(x(end,:)==y(:,end)') || ...
  194.         all(x(:,1)==y(1,:)') || all(x(:,1)==y(end,:)') || all(x(:,1)==y(:,1)) || all(x(:,1)==y(:,end)) || ...
  195.         all(x(:,end)==y(1,:)') || all(x(:,end)==y(end,:)') || all(x(:,end)==y(:,1)) || all(x(:,end)==y(:,end))
  196.     z = true;
  197.     return
  198. end
  199. end
  200.  
  201. function yNew = alignPieces(x,y)
  202. % aligns y to x
  203. yNew = y;
  204.  
  205. for k=0:3
  206.     y = rot90(yNew,k);
  207.     if all(y(end,:)==x(1,:)) || all(y(:,1)==x(:,end)) || all(y(1,:)==x(end,:)) || all(y(:,end)==x(:,1))
  208.         yNew = y;
  209.         return
  210.     end
  211. end
  212.  
  213. yNew = fliplr(yNew);
  214. for k=0:3
  215.     y = rot90(yNew,k);
  216.     if all(y(end,:)==x(1,:)) || all(y(:,1)==x(:,end)) || all(y(1,:)==x(end,:)) || all(y(:,end)==x(:,1))
  217.         yNew = y;
  218.         return
  219.     end
  220. end
  221. end
  222.  
  223. function z = getRelativePosition(x,y)
  224. z = 0;
  225. if all(y(end,:)==x(1,:))
  226.     z = 1;
  227.     return
  228. end
  229. if all(y(1,:)==x(end,:))
  230.     z = 3;
  231.     return
  232. end
  233. if all(y(:,end)==x(:,1))
  234.     z = 4;
  235.     return
  236. end
  237. if all(y(:,1)==x(:,end))
  238.     z = 2;
  239.     return
  240. end
  241. end
  242.  
  243. function idx = ID2idx(T,ID)
  244. idx=-1;
  245. for i=1:size(T,1)
  246.     if T(i).ID==ID
  247.         idx = i;
  248.         return
  249.     end
  250. end
  251. end
  252.  
  253. function N = findMonsters(P,M)
  254. % returns number of monster found
  255. N=0;
  256. for r=1:(size(P,1)-size(M,1)+1)
  257.     for c = 1:(size(P,2)-size(M,2)+1)
  258.         if all(all( (M & P(r:r+size(M,1)-1,c:c+size(M,2)-1)) == M))
  259.             N=N+1;
  260.         end
  261.     end
  262. end
  263. end
Advertisement
Add Comment
Please, Sign In to add comment