# Evenly distributed random non-stops

I am trying again to recreate some strange images. I am trying to generate hexagons of nonstop with three colors. The distribution of these three should be

Color 1 = (N-1)^2
Color 2 = (N-1)*N
Color 3 = N^2


where N is the side length of the non stops. The result should look something like this.

NOTE: Here 4 colors is used, I only need 3! Secondly the distribution itself is wrong in the image above.

The idea is then to "sort" the nonstop to make the figure below

I am able to create the hexagonal non stop pattern (after a lot of work!), see below.

What I want to improve is this

• How can I control exactly how many of each color type that is present in the hexagon. I still want them to appear randomly in the hexagon.
• Any improvements in apperance to look a bit more like actual candy would be much appreciated.
• Is there an easier approach to generating the hexagon? I had to do a lot of mathematics, and trial and error to get the result right. (Also why is there a small space between my rows?).

Any other approach to obtain the result is much appreciated.

# Code

\documentclass[12pt]{article}
\usepackage{ifthen, tikz}
\pgfmathsetseed{\number\pdfrandomseed}

\usetikzlibrary{shapes.geometric}

\definecolor{maincolorMedium}{HTML}{425b9b}

\tikzset{
nonstop/.style={
circle,
minimum size=10mm,
inner sep=0mm,
outer sep=0mm,
rotate=0,
draw
}
}

\definecolor{nonstopRed}{HTML}{EB4F5C}
\definecolor{nonstopYellow}{HTML}{FFE103}
\definecolor{nonstopBlack}{HTML}{02031B}

\newcommand{\ballcolor}{none}

% Example: Pick color by ID
\newcommand{\incolor}{
\pgfmathsetmacro{\rng}{int(random(1,3))}
\ifthenelse{\rng < 2}{ \renewcommand{\ballcolor}{nonstopRed}}{%
\ifthenelse{\rng < 3}{ \renewcommand{\ballcolor}{nonstopYellow} }{%
\renewcommand{\ballcolor}{nonstopBlack}
}
}
}

\newcommand{\createNonstop}[1]{%
\begin{tikzpicture}
\def\hexagonSize{#1}
\pgfmathsetmacro{\J}{2*\hexagonSize-1}
\foreach \j in {1,...,\J} {
\pgfmathsetmacro{\offset}{0.5*Mod(\j,2)}
\ifthenelse{\j > \hexagonSize}
{\pgfmathsetmacro{\hexLength}{\hexagonSize + \J - \j}
\pgfmathsetmacro{\jIndent}{0.5*(\J - \j)}}
{\pgfmathsetmacro{\hexLength}{\hexagonSize + \j-1}
\pgfmathsetmacro{\jIndent}{0.5*(\j-1)}}
\foreach \k in {1,...,\hexLength} {
\incolor
\node[nonstop,fill=\ballcolor] at (\k  -\jIndent,\j) {};
}
}
\end{tikzpicture}
}

\begin{document}

\createNonstop{2}

\createNonstop{3}

\createNonstop{4}

\createNonstop{5}

\end{document}


## 1 Answer

Sorry, my previous post did not include the requirement on the number of colors, which I corrected now. This code runs through a loop of 3*N*(N+1)+1 steps (note that my definition of N is your N+1) and then selects a random number between 1 and n_tot=3*N*(N+1)+1, between 1 and n_tot=3*N*(N+1) and so on, where in each step one color item gets taken out, hence the three counters none, ntwo and nthree. At each step none+ntwo+nthree=n_tot and the counter of each color pile gets reduced. This ensures that there will be (N+1)^2 smarties of the first color, N*(N+1) of the second color and N^2 of the last color. The lattice is just constructed layer by layer.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{shadows.blur}
\newcounter{none}
\newcounter{ntwo}
\newcounter{nthree}
\begin{document}
\begin{tikzpicture}[pics/hegrid/.style={code={
\xdef\LstOne{""}
\setcounter{none}{\the\numexpr(#1+1)*(#1+1)}
\setcounter{ntwo}{\the\numexpr#1*(#1+1)}
\setcounter{nthree}{\the\numexpr#1*#1}
\pgfmathtruncatemacro{\Nm}{int(3*#1*(#1+1)+1)}
\foreach \YY in {\Nm,\the\numexpr\Nm-1,...,1}
{\pgfmathtruncatemacro{\itest}{random(1,\YY)}
\ifnum\itest>\number\value{none}\relax
\ifnum\itest>\the\numexpr\YY-\number\value{nthree}\relax
\addtocounter{nthree}{-1}
\pgfmathsetmacro{\mycol}{{\LstCols}[2]}
\xdef\LstOne{\LstOne,"\mycol"}
\else
\addtocounter{ntwo}{-1}
\pgfmathsetmacro{\mycol}{{\LstCols}[1]}
\xdef\LstOne{\LstOne,"\mycol"}
\fi
\else
\addtocounter{none}{-1}
\pgfmathsetmacro{\mycol}{{\LstCols}[0]}
\xdef\LstOne{\LstOne,"\mycol"}
\fi}
\setcounter{none}{1}
\path [/utils/exec=\pgfmathsetmacro{\mycol}{{\LstOne}[1]}]
node[smartie=\mycol]{};
\foreach \XX in {1,...,#1}
{\foreach \YY [count=\NYY] in {0,...,5}
{\path (\NYY*60:\XX) -- (\YY*60:\XX) foreach \ZZ in {1,...,\XX}
{\pgfextra{\stepcounter{none}%
\pgfmathsetmacro{\mycol}{{\LstOne}[\number\value{none}]}}
node[smartie=\mycol,pos={\ZZ/\XX}]{}};}}}},
smartie/.style={circle,draw,inner sep=3mm,blur shadow,
path picture={\shade[ball color=#1] (0.15,-0.15) circle[radius=9mm];}}]
\edef\LstCols{"red","blue","green!70!black"}
\path (0,0) pic{hegrid=1} (5,0) pic{hegrid=2}
(2,-6) pic{hegrid=3};
\end{tikzpicture}
\end{document}


The ordered pattern is much easier to obtain.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{shadows.blur}
\begin{document}
\begin{tikzpicture}[pics/ordered hegrid/.style={code={
\path [/utils/exec=\pgfmathsetmacro{\mycol}{{\LstCols}[0]}]
node[smartie=\mycol]{};
\foreach \XX in {1,...,#1}
{\foreach \YY [count=\NYY] in {0,...,5}
{\path (\NYY*60+60:\XX) -- (\YY*60+60:\XX) foreach \ZZ in {1,...,\XX}
{\pgfextra{%
\pgfmathtruncatemacro{\myind}{ifthenelse(\NYY<3 || (\NYY==3 && \ZZ == \XX),0,ifthenelse(\NYY<5,1,2))}
\pgfmathsetmacro{\mycol}{{\LstCols}[\myind]}}
node[smartie=\mycol,pos={\ZZ/\XX}]{}};}}}},
smartie/.style={circle,draw,inner sep=3mm,blur shadow,
path picture={\shade[ball color=#1] (0.15,-0.15) circle[radius=9mm];}}]
\edef\LstCols{"red","blue","green!70!black"}
\path (0,0) pic{ordered hegrid=1} (5,0) pic{ordered hegrid=2}
(2,-6) pic{ordered hegrid=3};
\end{tikzpicture}
\end{document}


• Note to myself: mini-issue in the new option parse=true in foreach.
– user121799
Jun 27, 2019 at 2:50
• Wow! This looks amazing! Any idea how to also produce the sorted output image at the bottom? I tried to change your code, but alas it was outside my abilities. Jun 27, 2019 at 9:17
• @N3buchadnezzar Oh sorry, I missed that, too. This one is much easier.
– user121799
Jun 27, 2019 at 15:02