I’ve asked my wife to select a certain date in a format MM/DD and she replied: 04/17 adding an unsolicited remark: …”and, mind you, it is my birthday and it is just around the corner…!
I tried the digits 0,1,4,7 as a candidate generator of all the dates in April i.e. 1 to 30 (in my head, of course) : 1, 1+0!, 4-1, 4, 4+1, 7-1, …7*4+1, 7*4+1+0! and (check whether I err) found out that her date allows to create all the dates of April.
Now - solve the following puzzle:
a. How many dates in a leap year can be considered “a perfect generator” for the month they represent, provided each of the four digits of MM/DD can be used once and any of the operators “+ - * / ^ and ! “ twice at most. Concatenation: only numbers.
b. What dates are the worst generators i.e. create the lowest quantity of dates?
c. What perfect generator has the lowest sum of digits in its MMDD?
d. What would be the answer to a. if a sqrt operator were allowed as well?
Brackets, of course, are allowed.
(In reply to
checking Ady and a - c by Charlie)
Program to produce main list:
clc,clearvars
global phi availOps stack availDigs forms form vrange had
phi=(1+sqrt(5))/2;
digSet=1:9;
availOps='+-*/!'; % note no v in version w/o sq root
stack=[];
% availDigs=digSet;
% availDigs=[0 1 4 7];
form='';
moLen=[31 29 31 30 31 30 31 31 30 31 30 31];
for mo= 1:12
extraDig=['0' char(string(mo))];
extraDig=extraDig(end-1:end);
for day=1:moLen(mo)
tic
dayDig=['0' char(string(day))];
dayDig=dayDig(end-1:end);
availDigs=[extraDig dayDig]-48;
% disp(availDigs);
vrange=1:moLen(mo); had=zeros(1,31);
form=''; forms={};
findIt()
ct=0;
for i=1:length(forms)
if length(forms{i})>0
ct=ct+1;
end
end
fprintf('%4s %3d %3d\n',strcat(availDigs+48),moLen(mo),ct)
toc
end
end
function findIt()
global phi availOps stack availDigs forms form vrange had
% form
% stack
% disp(' ')
for whDig=1:length(availDigs)
dig=availDigs(whDig);
availDigs(whDig)=[];
stack=[stack dig];
saveform=form;
form=[form char(string(dig)) ','];
if length(stack)==1
if stack(end)>=vrange(1) && stack(end)<=vrange(end) && stack(end)==floor(stack(end))
if ~ismember(stack(end),had)
had(stack(end))=stack(end);
forms{stack(end)}=form;
else
if length(form)<length(forms{stack(end)})
had(stack(end))=stack(end);
forms{stack(end)}=form;
end
end
end
end
if length(form)<22
findIt();
end
stack(length(stack))=[];
form=saveform;
availDigs=[availDigs(1:whDig-1) dig availDigs(whDig:end)];
idxcom=find(form==',');
if length(idxcom)==1
idxcom=[0 idxcom];
end
if length(idxcom)>=2
saveform=form;
stacksave=stack;
if ~isnan(str2double(form(idxcom(end-1)+1:idxcom(end)-1)))
stack(end)=10*stack(end)+dig;
availDigs(whDig)=[];
form=[form(1:idxcom(end)-1) char(string(dig)) ','];
if length(stack)==1
if stack(end)>=vrange(1) && stack(end)<=vrange(end) && stack(end)==floor(stack(end))
if ~ismember(stack(end),had)
had(stack(end))=stack(end);
forms{stack(end)}=form;
else
if length(form)<length(forms{stack(end)})
had(stack(end))=stack(end);
forms{stack(end)}=form;
end
end
end
end
findIt();
availDigs=[availDigs(1:whDig-1) dig availDigs(whDig:end)];
end
stack=stacksave;
form=saveform;
end
end
if length(stack)>0
for whOp=1:length(availOps)
Op=availOps(whOp);
if length(strfind(form,Op))>=2 || Op~='!' && Op~="v" && length(stack)<2
continue
end
saveform=form;
stacksave=stack;
form=[form Op ','];
if Op=='!'
if stack(end)>=0 && stack(end)<=17 && stack(end)==floor(stack(end))
stack(end)=factorial(stack(end));
if stack(end)>=vrange(1) && stack(end)<=vrange(end) && stack(end)==floor(stack(end))
if ~ismember(stack(end),had)
had(stack(end))=stack(end);
forms{stack(end)}=form;
else
if length(form)<length(forms{stack(end)})
had(stack(end))=stack(end);
forms{stack(end)}=form;
end
end
end
if length(form)<22
findIt();
end
end
elseif Op=='v'
if stack(end)>=0
stack(end)=sqrt(stack(end));
if length(stack)==1 && length(char(string(stack(end))))<8
if stack(end)>=vrange(1) && stack(end)<=vrange(end) && stack(end)==floor(stack(end))
if ~ismember(stack(end),had)
had(stack(end))=stack(end);
forms{stack(end)}=form;
else
if length(form)<length(forms{stack(end)})
had(stack(end))=stack(end);
forms{stack(end)}=form;
end
end
end
end
if length(form)<22
findIt();
end
end
else
if (Op~='/' || stack(end)~=0) && length(stack)>=2
v=eval([num2str(stack(end-1),16) Op num2str(stack(end),16)]);
stack=[stack(1:end-2) v];
if length(stack)==1
if stack(end)>=vrange(1) && stack(end)<=vrange(end) && stack(end)==floor(stack(end))
if ~ismember(stack(end),had)
had(stack(end))=stack(end);
forms{stack(end)}=form;
else
if length(form)<length(forms{stack(end)})
had(stack(end))=stack(end);
forms{stack(end)}=form;
end
end
end
end
if length(form)<22
findIt();
end
end
end
stack=stacksave;
form=saveform;
end
end
end
Note the 'v' Op code was excluded, though the code for calculating square root was included. However when it was activated by placing v in the list of available operations, execution time exploded, and it was not worthwhile to try portion d of the puzzle.
Program to produce and analyze statistics:
fid=fopen('c:\VB5 Projects\flooble\carpe diem new.txt','r');
mo=0;
totct=0;moCt=0;
worst=99; worstday={}; lowsod=9999; lowestsodday={};
while ~feof(fid)
l=fgetl(fid);
prevmo=mo;
mo=str2double(l(1:2));
if mo>prevmo
daysInMo=str2double(l(7:8));
fprintf('%2d %2d\n',prevmo, moCt)
moCt=0;
end
day=str2double(l(3:4));
dayct=str2double(l(11:12));
if dayct==daysInMo
disp(l)
totct=totct+1; moCt=moCt+1;
sumdig=sum(l(1:4)-48);
if sumdig <=lowsod
if sumdig<lowsod
lowestsodday={};
end
lowsod=sumdig;
lowestsodday{end+1}=l(1:4);
end
else
if dayct<=worst
if dayct<worst
worstday={};
end
worst=dayct;
worstday{end+1}=l(1:4);
end
end
end
fclose('all');
fprintf('%2d %2d\n',prevmo, moCt)
disp (totct)
fprintf('worst dates(%2d):\n',worst);
for i=1:length(worstday)
disp(worstday{i})
end
disp('low sod:')
for i=1:length(lowestsodday)
disp(lowestsodday{i})
end
Program for an individual date (the first written, for verifying 0417:
clc,clear
global phi availOps stack availDigs forms form vrange had
phi=(1+sqrt(5))/2;
digSet=1:9;
availOps='+-*/!';
stack=[];
availDigs=digSet;
availDigs=[0 4 1 7];
form='';
forms={};
vrange=1:30; had=zeros(1,31);
findIt()
for i=1:length(forms)
% disp(forms{i})
fprintf('%3d %s\n',i,forms{i})
end
function findIt()
global phi availOps stack availDigs forms form vrange had
% form
% stack
% disp(' ')
for whDig=1:length(availDigs)
dig=availDigs(whDig);
if dig==3
xx=99;
end
availDigs(whDig)=[];
stack=[stack dig];
saveform=form;
form=[form char(string(dig)) ','];
if length(stack)==1
if stack(end)>=vrange(1) && stack(end)<=vrange(end) && stack(end)==floor(stack(end))
if ~ismember(stack(end),had)
had(stack(end))=stack(end);
forms{stack(end)}=form;
else
if length(form)<length(forms{stack(end)})
had(stack(end))=stack(end);
forms{stack(end)}=form;
end
end
end
end
findIt();
stack(length(stack))=[];
form=saveform;
availDigs=[availDigs(1:whDig-1) dig availDigs(whDig:end)];
idxcom=find(form==',');
if length(idxcom)==1
idxcom=[0 idxcom];
end
if length(idxcom)>=2
saveform=form;
stacksave=stack;
if ~isnan(str2double(form(idxcom(end-1)+1:idxcom(end)-1)))
stack(end)=10*stack(end)+dig;
availDigs(whDig)=[];
form=[form(1:idxcom(end)-1) char(string(dig)) ','];
if length(stack)==1
if stack(end)>=vrange(1) && stack(end)<=vrange(end) && stack(end)==floor(stack(end))
if ~ismember(stack(end),had)
had(stack(end))=stack(end);
forms{stack(end)}=form;
else
if length(form)<length(forms{stack(end)})
had(stack(end))=stack(end);
forms{stack(end)}=form;
end
end
end
end
findIt();
availDigs=[availDigs(1:whDig-1) dig availDigs(whDig:end)];
end
stack=stacksave;
form=saveform;
end
end
if length(stack)>0
for whOp=1:length(availOps)
Op=availOps(whOp);
if length(strfind(form,Op))>=2 || Op~='!'&& length(stack)<2
continue
end
saveform=form;
stacksave=stack;
form=[form Op ','];
if Op=='!'
if stack(end)>=0 && stack(end)<=17 && stack(end)==floor(stack(end))
stack(end)=factorial(stack(end));
% if length(stack)==1
if stack(end)>=vrange(1) && stack(end)<=vrange(end) && stack(end)==floor(stack(end))
if ~ismember(stack(end),had)
had(stack(end))=stack(end);
forms{stack(end)}=form;
else
if length(form)<length(forms{stack(end)})
had(stack(end))=stack(end);
forms{stack(end)}=form;
end
end
end
% end
if length(form)<22
findIt();
end
end
else
if Op~='/' || stack(end)~=0
v=eval([num2str(stack(end-1),16) Op num2str(stack(end),16)]);
stack=[stack(1:end-2) v];
if length(stack)==1
if stack(end)>=vrange(1) && stack(end)<=vrange(end) && stack(end)==floor(stack(end))
if ~ismember(stack(end),had)
had(stack(end))=stack(end);
forms{stack(end)}=form;
else
if length(form)<length(forms{stack(end)})
had(stack(end))=stack(end);
forms{stack(end)}=form;
end
end
end
end
if length(form)<22
findIt();
end
end
end
stack=stacksave;
form=saveform;
end
end
end
|
Posted by Charlie
on 2023-04-07 17:28:29 |