Skip to content

Instantly share code, notes, and snippets.

@jcboyd
Created January 30, 2024 08:22
Show Gist options
  • Save jcboyd/7f4a2a2a6414c645ebe50fb132e1c81f to your computer and use it in GitHub Desktop.
Save jcboyd/7f4a2a2a6414c645ebe50fb132e1c81f to your computer and use it in GitHub Desktop.
Sieve of Eratosthenes with tikz
\documentclass[tikz]{standalone}
\usepackage{tikz}
\begin{document}
\def\primes{2,3,5,7,11,13,17,19,23}
\def\revprimes{23,19,17,13,11,7,5,3,2}
\def\palette{{
"0.00 0.00 1.00",
"0.00 0.00 1.00",
"0.00 0.00 1.00",
"0.00 0.00 1.00",
"0.00 0.00 1.00",
"0.00 0.00 1.00",
"0.00 0.00 1.00",
"0.73 0.00 0.00",
"1.00 0.98 0.00",
"0.00 0.77 1.00"}}
\def\width{5}
\def\height{5}
\newcommand{\drawboundingbox}[3]{% anchor, fill
\draw [thick, #3, fill=#2, fill opacity=0.2] (#1.north west) -- (#1.south west) -| (#1.north east) -- (#1.north west);
}
% for the ifnodedefined macro, full credit to: https://tex.stackexchange.com/questions/85528/checking-whether-or-not-a-node-has-been-previously-defined
\makeatletter
\long\def\ifnodedefined#1#2#3{%
\@ifundefined{pgf@sh@ns@#1}{#3}{#2}%
}
\makeatother
\foreach \prime [count=\pp] in \primes{
\pgfmathtruncatemacro{\firststep}{\prime}
\pgfmathtruncatemacro{\secondstep}{\prime*\prime}
\pgfmathtruncatemacro{\thirdstep}{\secondstep+\prime}
\pgfmathtruncatemacro{\numgrid}{\width*\height}
\foreach \step in {1, \firststep, \secondstep, \thirdstep, ..., \numgrid}{
\begin{tikzpicture}
% set canvas size
\useasboundingbox (0pt,0pt) rectangle (230pt,230pt);
% draw grid
\pgfmathtruncatemacro{\gridwidth}{\width}
\foreach \x [count=\xx] in {1, ..., \gridwidth} {
\pgfmathtruncatemacro{\gridheight}{\height-1}
\foreach \y [count=\yy] in {\gridheight, ..., 0} {
\pgfmathtruncatemacro{\cell}{\width*\y+\x} % draw location
\ifnum\cell>1
\foreach \iterprime [count=\x] in \revprimes {
% define colour
\pgfmathparse{\palette[\x]}
\definecolor{fillcolour}{rgb}{\pgfmathresult};
\ifnum\prime<\iterprime
\else % i.e. iterprime <= prime
\pgfmathparse{Mod(\cell,\iterprime)==0?1:0}
\ifnum\pgfmathresult>0
\ifnum\iterprime=\prime % current prime--wait for grid
\ifnum\cell>\step
\else % label <= step
\ifnum\cell<\secondstep % skip over multiples between prime and prime**2
\ifnum\cell>\firststep
\else
\ifnum\cell=\firststep
\node[inner sep=8pt, text=black, font=\bfseries, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell};
\drawboundingbox{n\xx\yy}{fillcolour}{very thick}%{0.4}
\breakforeach
\else
% draw
\node[inner sep=8pt, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell};
\drawboundingbox{n\xx\yy}{fillcolour}{semithick}%{0.2}
\breakforeach
\fi
\fi
\else
\node[inner sep=8pt, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell};
\drawboundingbox{n\xx\yy}{fillcolour}{semithick}%{0.2}
\breakforeach
\fi
\fi
\else
\pgfmathtruncatemacro{\iterfirststep}{\iterprime}
\pgfmathtruncatemacro{\itersecondstep}{\iterprime*\iterprime}
\ifnum\cell<\itersecondstep % skip over multiples between prime and prime**2
\ifnum\cell>\iterfirststep
\else
\ifnum\cell=\iterfirststep
\node[inner sep=8pt, text=black, font=\bfseries, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell};
\drawboundingbox{n\xx\yy}{fillcolour}{very thick}%{0.4}
\breakforeach
\else
% draw
\node[inner sep=8pt, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell};
\drawboundingbox{n\xx\yy}{fillcolour}{semithick}%{0.2}
\breakforeach
\fi
\fi
\else
\node[inner sep=8pt, minimum size=1.2cm] (n\xx\yy) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell};
\drawboundingbox{n\xx\yy}{fillcolour}{semithick}%{0.2}
\breakforeach
% draw
\fi
\fi
\fi
\fi
}
\ifnodedefined{n\xx\yy}{} {% if node not drawn by a prime
\node[inner sep=8pt, minimum size=1.2cm] (char) at (\xx*1.5-0.5, \yy*1.5-0.5) {\cell};
\drawboundingbox{char}{gray}{semithick}{0.2}
}
\fi
}
}
% \xdef\primelist{Primes:}
% \foreach \x in \primes{
% \ifnum\x>\prime
% \else
% \ifnum\x=\prime
% \ifnum\step>1
% \xdef\primelist{\primelist \ \ \x}
% \fi
% \else
% \xdef\primelist{\primelist \ \ \x}
% \fi
% \fi
% }
% \node[inner sep=8pt, anchor=west] (list) at (0.3, 9) {\Large\primelist};
\end{tikzpicture}
\ifnum\step=\firststep
\ifnum\secondstep>\numgrid % break if overstep grid size (larger primes)
\breakforeach
\fi
\fi
\ifnum\step=\secondstep
\ifnum\thirdstep>\numgrid % break if overstep grid size (larger primes)
\breakforeach
\fi
\fi
}
}
\end{document}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment