function Puzzle_v4_mzip % MATLAB zip file, a self-extracting MATLAB archive. % Usage: Run this file to recreate the original directory. fname = mfilename; fin = fopen([fname '.m'],'r'); dname = fname(1:find(fname=='_',1,'last')-1); mkdir(dname); mkdir([dname filesep 'lib']) addpath(dname) addpath([dname filesep 'lib']) L = fgetl(fin); while length(L) < 2 || ~isequal(L(1:2),'%%') L = fgetl(fin); end while ~isequal(L,'%% EOF') F = [dname filesep L(4:end)]; disp(F) fout = fopen(F,'w'); L = fgetl(fin); while length(L) < 2 || ~isequal(L(1:2),'%%') fprintf(fout,'%s\n',L); L = fgetl(fin); end fclose(fout); end fclose(fin); end %% polypuzzle.m function polypuzzle(arg1,arg2) % polypuzzle. Revolving Century puzzle. % polypuzzle, with no arguments, initiates the puzzle. % polypuzzle(A) initiates the puzzle with state matrix A. % polypuzzle(r,s), subsequent callbacks, r = row, s = direction. % https://blogs.mathworks.com/cleve/2025/05/11/ % CBM, '14-May-2025 15:07:34' % Copyright 2025 The MathWorks, Inc. if nargin < 2 if nargin == 0 A = original; else A = arg1; end rin = 0; sin = 0; D = puzzle_disc(7); for r = 1:6 D(:,:,r) = puzzle_disc(8-r); end fullscreen axis(8*[-1 1 -1 1]) axis square noticks box on shg tsteps = 1; else gcfud = get(gcf,'userdata'); [A,D] = deal(gcfud{:}); rin = arg1; sin = arg2; if rin < 1 polypuzzle(magic(6)) return end tsteps = 8; end d = dir; want_gif = any(contains(string({d(:).name}'),".gif")); colors = puzzle_colors; hold on for t = 1:tsteps plotdisc(disc(7.02,64),colors(1,:)) for r = 6:-1:1 P = D(:,:,7-r); rcolor = colors(mod(r,2)+1,:); delta = 0; if r == rin delta = sin*60/tsteps; P = rotate(P,delta,[0,0]); if t < tsteps rcolor = colors(mod(r,2)+3,:); end end D(:,:,7-r) = P; plotdisc(P,rcolor) labeldisc(r,A(r,:),t*delta,'') end plotdisc(disc(0.9),colors(1,:)) c = sum(sum(A))/6; text(0,0,int2str(c), ... 'fontsize',16, ... 'fontweight','bold', ... 'horiz','center') if want_gif gif_frame end drawnow end hold off shift = [2:6 1]; r = rin; if sin > 0 A(r,:) = A(r,shift); elseif sin < 0 A(r,shift) = A(r,:); end set(gcf,'userdata',{A,D}) delete(findobj('tag','sum')) labeldisc(7,sum(A),0,'sum') if sin == 0 uipush([0.15 0.53 0.075 0.05],'original',original) uipush([0.15 0.47 0.075 0.05],'solution',solution) set(gcf,'windowbuttondownfcn',@button_down, ... 'windowbuttonupfcn',[]) disableDefaultInteractivity(gca) end end %% lib\button_down.m function button_down(varargin) set(gcf,'windowbuttondownfcn',[]) set(gcf,'windowbuttonupfcn',@button_up) end %% lib\button_up.m function button_up(varargin) set(gcf,'windowbuttonupfcn',[]) point = get(gca,'currentpoint'); x = point(1,1); y = point(1,2); t = atan2d(y,x); r = floor(hypot(x,y)); s = sign(y)*(2*(rem(t,60)<30)-1); polypuzzle(r,s); set(gcf,'windowbuttondownfcn',@button_down) end %% lib\disc.m function D = disc(r,n) if nargin < 2 n = 32; end c = r*exp(pi*1i*(-n:1:n-1)/n); D = polyshape(real(c),imag(c)); end %% lib\labeldisc.m function labeldisc(r,Ar,tdelta,tag) fs = 14; for k = 1:6 theta = k*60 + tdelta; x = (r+0.5)*cosd(theta); y = (r+0.5)*sind(theta); text(x,y,num2str(Ar(k)), ... 'color','k', ... 'rotation',theta-90, ... 'fontsize',fs, ... 'fontweight','bold', ... 'tag',tag, ... 'horiz','center'); end end %% lib\original.m function A = original A = [ ... 1 4 25 29 6 35 18 5 34 33 0 10 19 24 2 26 8 21 28 13 32 0 11 16 12 14 23 7 27 17 15 20 22 31 3 9]; end %% lib\plotdisc.m function plotdisc(P,fc) lw = 1; plot(P,'facecolor',fc, ... 'edgecolor','k', ... 'facealpha',1, ... 'linewidth',lw) end %% lib\puzzle_colors.m function pc = puzzle_colors pc = [ 0.4444 0.2778 0.1111 1.0000 0.9675 0.8902 0.6667 0.4167 0.1667 1.0000 0.9892 0.9634]; end %% lib\puzzle_disc.m function D = puzzle_disc(r) c = r*exp(pi*2i*(-1:1/8:1)/12); c = [0.95*c(1) c(3:end-2) 0.95*c(end) 0]; c(end+1) = c(1); S = polyshape(real(c),imag(c)); D = []; for k = 1:6 D = [D, rotate(S,(k+1)*60,[0 0])]; end box on end %% lib\solution.m function A = solution(A,r) shift = @(v) v([2:6 1]); if nargin < 2 r = 1; A = original; end for k = 1:6 A(r,:) = shift(A(r,:)); if r < 6 A = solution(A,r+1); if all(sum(A)==100) return end end end end %% lib\uipush.m function uipush(position,string,state) fs = 14; uicontrol('style','pushbutton', ... 'units','normal', ... 'position',position, ... 'string',string, ... 'fontsize',fs, ... 'fontweight','bold', ... 'callback',@(~,~) polypuzzle(state)) end %% EOF