23
\$\begingroup\$

I like pizza!

Task

Given the radius of a pizza and a list of ingredients, create the corresponding ascii pizza!

Example size 4 pizza with mozzarella cheese, olives and ham:

  #####  
 #@@@@M# 
#H@O@@@@#
#M@@@H@@#
#@OO@@@@#
#@@H@@@@#
#M@M@@@@#
 #O@@@H# 
  #####  

Input

A positive integer r for the size of the pizza and a (possibly empty) list of ingredients (non-empty strings). The list of ingredients can be given in a series of convenient formats, including but not limited to:

  • a list of ingredients, such as ["tomato", "ham", "cheese"];
  • a list of the initials, such as ["t", "h", "c"];
  • a list of left- or right-padded ingredients, such as ["tomato", "ham ", "cheese"] or ["tomato", " ham", "cheese"];
  • a string with the initials, such as "thc".

Output specs

The pizza is built on a square of size 2r+1 characters, with the centre character having coordinates (0,0) for the purposes of this explanation. All characters in the square have integer coordinates. Then,

  • a position is crust # if its coordinates x,y satisfy \$r+1 > \sqrt{x^2 + y^2} \geq r\$;
  • a position is dough @ if its coordinates x,y satisfy \$ r > \sqrt{x^2+y^2}\$.

Then, the ingredients must be put randomly on the pizza. Each ingredient will be represented by its initial and you must place r of each ingredient randomly in the dough characters. You can assume there will be enough space in the pizza. Ingredients cannot be placed on top of eachother, so in the final pizza there must be exactly rl non-dough symbols, in groups of r, if the ingredients list has size l.

For the randomness in the distributions of ingredients on top of the pizza, it suffices that for a fixed r and ingredient list, all ingredient distributions obeying the specs have non-zero probability of occurring.

Examples

r = 1, no ingredients

###
#@#
###

r = 2, no ingredients

#####
#@@@#
#@@@#
#@@@#
#####

r = 5, no ingredients

  #######  
 ##@@@@@## 
##@@@@@@@##
#@@@@@@@@@#
#@@@@@@@@@#
#@@@@@@@@@#
#@@@@@@@@@#
#@@@@@@@@@#
##@@@@@@@##
 ##@@@@@## 
  ####### 

r = 4, ingredients = ["bacon", "mozzarela", "tomato"]

  #####  
 #@@b@m# 
#@@@@@b@#
#@@@btb@#
#@@@@@@t#
#@@@@@@@#
#@mt@@@@#
 #t@mm@# 
  #####  

Reference implementation

Please include one or two of your favourite pizzas in your answer :)


This is so shortest submission in bytes, wins! If you liked this challenge, consider upvoting it... And happy golfing!

\$\endgroup\$
  • 3
    \$\begingroup\$ (Off topic.) Pizza Hut is serving square pizzas ... but not as small as the cases 1 and 2 in the challenge. \$\endgroup\$ – petStorm Feb 17 at 8:25
  • 1
    \$\begingroup\$ Are you trying to out-pizza the hut?!? \$\endgroup\$ – Lyxal Feb 17 at 9:00
  • 1
    \$\begingroup\$ Bonus if your program is spaghetti code \$\endgroup\$ – Luis Mendo Feb 17 at 9:59
  • 8
    \$\begingroup\$ My favorite pizza is spam egg sausage and spam, 'cause that's not got much spam in it. \$\endgroup\$ – Arnauld Feb 17 at 11:54
  • 2
    \$\begingroup\$ @RGS Thanks. Using the initials may be an important simplification for some answers. Perhaps you should notifiy them? \$\endgroup\$ – Luis Mendo Feb 17 at 22:45
12
\$\begingroup\$

APL (Dyalog Extended), 55 bytesSBCS

Anonymous infix lambda. Takes r as left argument () and ingredient initials as right argument ().

{i@((≢i←⍺/⍵)?≢⍸1=n)@{1=n}'@# '[n←(0⍺,⍺+1)⍸⍤1|∘.⌾⍨⍺…-⍺]}

Try it online!

{} "dfn"; left argument (leftmost Greek letter), right argument (rightmost Greek letter)

'@# '[] index the string with:

  -⍺ negate r

  ⍺… generate integer range from r to -r

  ∘.⌾⍨ generate table of complex coordinates

  | magnitudes

  ()⍸⍤1 for each row's elements, find ɩndex the [a,b) ɩnterval in which the magnitude falls:

   ⍺+1 increment r

   0⍺, prepend [0,r]

   n← store in n (1: dough; 2: crust; 3: outside pizza)

i@()@{1=n} place the characters of i (to be defined) at the following subset of positions at which n is 1 (i.e. we have dough):

  1=n mask where n is 1

  ɩndices of trues

   count them

  ()? pick the following number of random indices from 1 to that:

   ⍺/⍵ replicate each ingredient initial letter to r copies

   i← store in i

    tally that

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Please include one or two of your favourite pizzas in your answer :) ~ What's your favourite pizza @Adám? \$\endgroup\$ – Lyxal Feb 17 at 9:01
  • \$\begingroup\$ @Lyxal I did. See the TIO link! \$\endgroup\$ – Adám Feb 17 at 9:01
  • 1
    \$\begingroup\$ Really nice job :D +1 for your work here! I'm just a bit sad you put pineapple in your pizza... But that is a matter of taste \$\endgroup\$ – RGS Feb 17 at 10:54
  • 4
    \$\begingroup\$ @RGS Thank you. The pineapple is a pun on Py'n'APL. \$\endgroup\$ – Adám Feb 17 at 10:57
  • 1
    \$\begingroup\$ Adám, I have edited the question to make input specs a bit more clear and a bit more loose. Maybe you can save some characters if the ingredient list is, say, a list of initials? Maybe check the clearer input specs. Sorry for the trouble! \$\endgroup\$ – RGS Feb 17 at 22:50
6
\$\begingroup\$

MATL, 44 43 40 34 bytes

Q_Zvqt!YytGQ<Zc64bG<(i1GY"7MfynZr(

Inputs are: r and a string with the initials of ingredients.

Try it online with ham, onion, pepper and mushroom! Or maybe try a diet pizza.

Explanation with example

Consider inputs 3 and 'AP'.

Q     % Implicit input: r. Add 1
      % STACK: 4
_Zv   % Symmetric inverse range
      % STACK: [4 3 2 1 2 3 4]
q     % Subtract 1, element-wise
      % STACK: [3 2 1 0 1 2 3]
t!    % Duplicate, transpose
      % STACK: [3 2 1 0 1 2 3], [3; 2; 1; 0; 1; 2; 3] 
Yy    % Hypotenuse, element-wise with broadcast
      % STACK: [4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426;
                3.6056    2.8284    2.2361    2.0000    2.2361    2.8284    3.6056;
                3.1623    2.2361    1.4142    1.0000    1.4142    2.2361    3.1623;
                3.0000    2.0000    1.0000         0    1.0000    2.0000    3.0000;
                3.1623    2.2361    1.4142    1.0000    1.4142    2.2361    3.1623;
                3.6056    2.8284    2.2361    2.0000    2.2361    2.8284    3.6056;
                4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426]
t     % Duplicate.
      % STACK: [4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426;
                3.6056    2.8284    2.2361    2.0000    2.2361    2.8284    3.6065;         
                                                ···
                4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426],
               [4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426;
                3.6056    2.8284    2.2361    2.0000    2.2361    2.8284    3.6065;         
                                                ···
                4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426]
GQ<   % Less than r plus 1? Element-wise
      % STACK: [4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426;
                3.6056    2.8284    2.2361    2.0000    2.2361    2.8284    3.6065;         
                                                ···
                4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426],
               [0 1 1 1 1 1 0;
                1 1 1 1 1 1 1;
                1 1 1 1 1 1 1;
                1 1 1 1 1 1 1;
                1 1 1 1 1 1 1;
                1 1 1 1 1 1 1;
                0 1 1 1 1 1 0]
Zc    % Replace 0 by space and 1 by '#'
      % STACK: [4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426;
                3.6056    2.8284    2.2361    2.0000    2.2361    2.8284    3.6065;         
                                                ···
                4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426],
               [' ##### ';
                '#######';
                '#######';
                '#######';
                '#######';
                '#######';
                ' ##### ' ]
64    % Push 64 (ASCII for '@') 
      % STACK: [4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426;
                3.6056    2.8284    2.2361    2.0000    2.2361    2.8284    3.6065;         
                                                ···
                4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426],
               [' ##### ';
                '#######';
                '#######';
                '#######';
                '#######';
                '#######';
                ' ##### ' ],
               64
b     % Bubble up
      % STACK: [' ##### ';
                '#######';
                '#######';
                '#######';
                '#######';
                '#######';
                ' ##### ' ],
               64,
               [4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426;
                3.6056    2.8284    2.2361    2.0000    2.2361    2.8284    3.6065;         
                                                ···
                4.2426    3.6056    3.1623    3.0000    3.1623    3.6056    4.2426]
G<    % Less than r? Element-wise
      % STACK: [' ##### ';
                '#######';
                '#######';
                '#######';
                '#######';
                '#######';
                ' ##### ' ],
               64,
               [0 0 0 0 0 0 0;
                0 1 1 1 1 1 0;
                0 1 1 1 1 1 0;
                0 1 1 1 1 1 0;
                0 1 1 1 1 1 0;
                0 1 1 1 1 1 0;
                0 0 0 0 0 0 0]
(     % Write value 64 (that is, '@') into char matrix at positions indexed by mask
      % STACK: [' ##### ';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                ' ##### ']
i     % Input: string
      % STACK: [' ##### ';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                ' ##### '],
               'AP'
1GY"  % Push first input (r) again. Repeat each letter that many times
      % STACK: [' ##### ';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                ' ##### '],
               'AAAPPP'
7Mf   % Push 0-1 mask again. Linear index (column-major order) of non-zero entries
      % STACK: [' ##### ';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                ' ##### '],
               'AP',
               [9; 10; 11; ...; 41]
yn    % Duplicate from below. Number of elements
      % STACK: [' ##### ';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                ' ##### '],
               'AAAPPP',
               [9; 10; 11; ...; 41]
               6
Zr    % Random sample without replacement (example result shown)
      % STACK: [' ##### ';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                '#@@@@@#';
                ' ##### '],
               'AAAPPP',
               [13; 18; 11; 24; 30; 25]      
(     % Write 'AAAPPP' into char matrix at positions given by the linear indices
      % STACK: [' ##### '
                '#@@@P@#';
                '#@@P@@#';
                '#AAP@@#';
                '#@@@@@#';
                '#A@@@@#';
                ' ##### ']
      % Implicit display
|improve this answer|||||
\$\endgroup\$
  • 4
    \$\begingroup\$ +1 for crossed out 44 still being 44 \$\endgroup\$ – RGS Feb 17 at 17:44
  • 2
    \$\begingroup\$ I like your diet pizza! Would +1 but really can't do it twice :'( \$\endgroup\$ – RGS Feb 18 at 7:38
6
\$\begingroup\$

05AB1E, 42 41 40 38 34 bytes

ÝRûãnOtï¹.S…# 1sèƶDþ.rI¹и'@Þ«‡¹·>ô

Output as a character-matrix.

-2 bytes because the specs changed (character-list input instead of ingredients-list).
-4 bytes thanks to @Grimmy.

Try it online or verify all test cases. (The footer is to pretty-print the result. Feel free to remove it to see the actual character-matrix result.)

Explanation:

Ý              # Push a list in the range [0, (implicit) input-integer]
 R             # Reverse it to range [input, 0]
  û            # Palindromize this list (i.e. [3,2,1,0] → [3,2,1,0,1,2,3])
   ã           # Take the cartesian product with itself, to get a list of all coordinates
n              # Square both the x and y of each coordinate
 O             # Take the sum of each
  t            # And then the square-root of that
   ï           # Truncate it to an integer
    ¹.S        # And compare each to the first input
               # (-1 if larger than the input; 0 if equals; -1 if smaller)
       …# 1    # Push string "# 1"
           sè  # And index the list into this string, where the -1 is the trailing character
ƶ              # Multiply the 1s by their 1-based index
 Dþ            # Duplicate the list, and only leave the integers (the indices)
   .r          # And randomly shuffle those
     I         # Push the second input-list of ingredient-characters
      ¹и       # Repeat this list the first input amount of times
        '@Þ   '# Push an infinite list of "@"
           «   # Append it to the repeated ingredient-characters
            ‡  # Transliterate the shuffled indices to this list
¹·<            # Push the first input again; double it; and decrease it by 1
               # (alternative: `Dgt` - Duplicate; length; square-root)
   ô           # Split the list into parts of that size
               # (after which the resulting character-matrix is output implicitly)
|improve this answer|||||
\$\endgroup\$
  • 1
    \$\begingroup\$ +1 really nice submission, even though you put pineapple in your pizza! \$\endgroup\$ – RGS Feb 17 at 10:55
  • 1
    \$\begingroup\$ @RGS I knew someone would comment about the pineapple. xD I know loads of people think Pizza Hawaii shouldn't exist, but I personally like it. ;p Although Pizza Funghi (Mushrooms) without the pineapple is fine as well. \$\endgroup\$ – Kevin Cruijssen Feb 17 at 11:04
  • 1
    \$\begingroup\$ pineapple doesn't belong on pizza :( \$\endgroup\$ – RGS Feb 17 at 13:50
  • \$\begingroup\$ Kevin, I have edited the question to make input specs a bit more clear and a bit more loose. Maybe you can save some characters if the ingredient list is, say, a list of initials? Maybe check the clearer input specs. Sorry for the trouble! \$\endgroup\$ – RGS Feb 17 at 22:50
  • 1
    \$\begingroup\$ -4 bytes with better radius code (and -2 by dropping €н since that's now allowed). Your ingredient code is better than what I had. If only we had Jelly's (all indices of b in a), that would save 5 bytes for my approach. \$\endgroup\$ – Grimmy Feb 18 at 17:32
3
\$\begingroup\$

Python 3.8 (pre-release), 186 177 176 bytes

from random import*
def f(r,i=[],s=''):i=['@',*next(zip(*i),[])];t=range(-r,R:=r+1);print([s:=s+[' #'[(d:=x*x+y*y)<R*R],choice(i)][d<r*r]+'\n'*(x==r)for y in t for x in t][-1])

Try it online!

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Looking nice! +1 for you cool submission \$\endgroup\$ – RGS Feb 17 at 17:42
  • \$\begingroup\$ I just have one problem, you seem to be crowding your pizza with ingredients! Each ingredient should show up r times :) \$\endgroup\$ – RGS Feb 17 at 17:46
  • \$\begingroup\$ Gábor, I have edited the question to make input specs a bit more clear and a bit more loose. Maybe you can save some characters if the ingredient list is, say, a list of initials? Maybe check the clearer input specs. Sorry for the trouble! \$\endgroup\$ – RGS Feb 17 at 22:51
  • 1
    \$\begingroup\$ You are right, it actually works with just a string or padded strings even but I'm still working on the number of ingredients to put on the pizza (I like a lot of toppings for now :) ) \$\endgroup\$ – Gábor Fekete Feb 18 at 10:37
  • \$\begingroup\$ Ok, ping me when you have the number of toppings fixed! :D \$\endgroup\$ – RGS Feb 18 at 14:06
3
\$\begingroup\$

JavaScript (ES7),  177 175  172 bytes

Takes input as (r)(list), where list is filled with initials. Returns an array of characters.

r=>a=>a.map(i=>(g=i=>(s[p=Math.random()*r**3|0]!='@'||(s[p]=i,--n))&&g(i))(i,n=R),s=[...(g=x=>y+r?` #@
`[x+r?((d=x*x--+y*y)<r*r)+(d<R*R):(--y,x=R,3)]+g(x):'')(y=R=r++)])&&s

Try it online!

Commented

r => a =>                     // r = radius, a[] = list of ingredients
  a.map(i =>                  // for each ingredient i in a[]:
    ( g = i => (              //   g is a recursive function taking i
        s[                    //     test s at
          p = Math.random()   //     a random position p in [0 .. r**3 - 1]
              * r**3 | 0      //
        ] != '@' ||           //     abort if it doesn't contain '@'
        (s[p] = i, --n)       //     otherwise, put the ingredient there and decrement n
      ) && g(i)               //     do a recursive call if the above result is truthy
    )(i, n = R),              //   initial call to g with i and n = R
    s = [...                  //   build the base pizza s[]
      ( g = x =>              //   g is another recursive function taking x
        y + r ?               //     if y is not equal to -r:
          ` #@\n`[            //       pick the relevant character:
            x + r ?           //         if x is not equal to -r:
              (               //
                (d = x * x--  //           d = x² + y²; decrement x
                   + y * y)   //
                < r * r       //           add 1 if it's less than r² (-> '#')
              ) +             //
              (d < R * R)     //           add 1 if it's less than R² (-> '@')
            :                 //         else:
              (y--, x = R, 3) //           decrement y, set x = R, append a linefeed
          ] +                 //
          g(x)                //       recursive call
        :                     //     else:
          ''                  //       stop recursion
      )(y = R = r++)          //   initial call to g with x = y = R = r; increment r
    ]                         //   
  ) && s                      // end of map(); return s[]
|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Nice job on compressing all the maths you needed!! +1 \$\endgroup\$ – RGS Feb 17 at 13:50
  • 1
    \$\begingroup\$ Arnauld, I have edited the question to make input specs a bit more clear and a bit more loose. Maybe you can save some characters if the ingredient list is, say, a list of initials? Maybe check the clearer input specs. Sorry for the trouble! \$\endgroup\$ – RGS Feb 17 at 22:50
2
\$\begingroup\$

Charcoal, 51 48 bytes

E⊕θ⭆E⊕θ₂⁺×ιι×λλ⎇›θλ@§ #›⊕θλ‖O↑←FηFθ§≔KA‽⌕AKA@§ι⁰

Try it online! Link is to verbose version of code. Now supports full topping names by using a less convenient input format, but could save 2 bytes by switching back to initials. Explanation:

E⊕θ⭆E⊕θ₂⁺×ιι×λλ⎇›θλ@§ #›⊕θλ

Draw the bottom right hand quarter of the pizza base.

‖O↑←

Reflect to complete the pizza base.

FηFθ

Loop through each topping repeatedly.

§≔KA‽⌕AKA@§ι⁰

Find a random dough character and overwrite it with the first letter of the topping.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Cool submission! +1 The bit about drawing the bottom right quarter of the pizza looks really long, in comparison to the topic placement, for e.g. I thought charcoal would be shorter here! :O \$\endgroup\$ – RGS Feb 17 at 13:51
  • \$\begingroup\$ @RGS I don't have a Euclidean distance primitive, and SquareRoot(Sum(Power([i, l], 2))) still takes 8 bytes. \$\endgroup\$ – Neil Feb 17 at 14:03
  • \$\begingroup\$ ah I understand, that helps explaining it \$\endgroup\$ – RGS Feb 17 at 17:41
  • \$\begingroup\$ Neil, I have edited the question to make input specs a bit more clear and a bit more loose. Maybe you can save some characters if the ingredient list is, say, a list of initials? Maybe check the clearer input specs. Sorry for the trouble! \$\endgroup\$ – RGS Feb 17 at 22:51
  • 1
    \$\begingroup\$ @RGS Actually I think it was my original mistake of using a list of initials that triggered the discussion. I did this because Charcoal doesn't have a convenient list input format. As it happens, if I use the inconvenient list input format, that saves me 2 bytes, which I can then spend on full ingredient names. (Or I could just use the inconvenient format with initials, and just claim the 2 byte saving...) \$\endgroup\$ – Neil Feb 18 at 0:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.