ASCII Pizza (no pineapple)

23

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!

RGS

Posted 2020-02-17T08:09:43.600

Reputation: 5 047

3(Off topic.) Pizza Hut is serving square pizzas ... but not as small as the cases 1 and 2 in the challenge. – a'_' – 2020-02-17T08:25:31.083

@a'_' that sounds interesting! – RGS – 2020-02-17T08:30:44.487

1Are you trying to out-pizza the hut?!? – Lyxal – 2020-02-17T09:00:04.293

I like pasta - I'll wait for your tagliatelle challenge :) – Galen Ivanov – 2020-02-17T09:50:57.327

1Bonus if your program is spaghetti code – Luis Mendo – 2020-02-17T09:59:28.117

@GalenIvanov still cooking that one – RGS – 2020-02-17T10:56:15.203

8My favorite pizza is spam egg sausage and spam, 'cause that's not got much spam in it. – Arnauld – 2020-02-17T11:54:46.263

1Related – Arnauld – 2020-02-17T13:41:10.130

How flexible is the input format? An answer for example seems to take a sigle string with the initials. Is that allowed? How about a space-right-padded char matrix like this (note the right-padding in each row)?

– Luis Mendo – 2020-02-17T16:09:06.423

@LuisMendo I would say that is still fairly acceptable. – RGS – 2020-02-17T17:46:28.843

@RGS Which of the two options? Or both? Perhaps edit that into the challenge text, so it's clear to everyone – Luis Mendo – 2020-02-17T22:35:35.080

@LuisMendo both; I edited the challenge, hope it is more clear now. – RGS – 2020-02-17T22:40:50.100

2@RGS Thanks. Using the initials may be an important simplification for some answers. Perhaps you should notifiy them? – Luis Mendo – 2020-02-17T22:45:17.463

@LuisMendo done as suggested! Thanks for your feedback. – RGS – 2020-02-17T22:51:43.477

Answers

12

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

Adám

Posted 2020-02-17T08:09:43.600

Reputation: 37 779

Please include one or two of your favourite pizzas in your answer :) ~ What's your favourite pizza @Adám? – Lyxal – 2020-02-17T09:01:13.357

@Lyxal I did. See the TIO link! – Adám – 2020-02-17T09:01:39.153

Nice! +1 for good choice of pizza! :P – Lyxal – 2020-02-17T09:03:28.137

1Really 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 – RGS – 2020-02-17T10:54:47.833

4

@RGS Thank you. The pineapple is a pun on Py'n'APL.

– Adám – 2020-02-17T10:57:02.450

@Adám ah wow, wouldn't get there alone! – RGS – 2020-02-17T13:49:25.190

1Adá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! – RGS – 2020-02-17T22:50:34.243

6

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)

Kevin Cruijssen

Posted 2020-02-17T08:09:43.600

Reputation: 67 575

1+1 really nice submission, even though you put pineapple in your pizza! – RGS – 2020-02-17T10:55:29.523

1@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. – Kevin Cruijssen – 2020-02-17T11:04:11.263

1pineapple doesn't belong on pizza :( – RGS – 2020-02-17T13:50:05.673

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! – RGS – 2020-02-17T22:50:42.233

Seems like you're off by one. For r=2, you output the pizza specified for r=1, and so on.

– Grimmy – 2020-02-18T17:16:53.240

1-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. – Grimmy – 2020-02-18T17:32:07.090

@Grimmy Thanks! And yeah, I miss the "all indices of b in a" in quite a lot of challenges tbh. – Kevin Cruijssen – 2020-02-18T18:45:08.460

6

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

Luis Mendo

Posted 2020-02-17T08:09:43.600

Reputation: 87 464

4

+1 for crossed out 44 still being 44

– RGS – 2020-02-17T17:44:07.310

2I like your diet pizza! Would +1 but really can't do it twice :'( – RGS – 2020-02-18T07:38:21.880

3

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[]

Arnauld

Posted 2020-02-17T08:09:43.600

Reputation: 111 334

Nice job on compressing all the maths you needed!! +1 – RGS – 2020-02-17T13:50:34.097

1Arnauld, 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! – RGS – 2020-02-17T22:50:53.697

3

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!

Gábor Fekete

Posted 2020-02-17T08:09:43.600

Reputation: 2 809

Looking nice! +1 for you cool submission – RGS – 2020-02-17T17:42:59.597

I just have one problem, you seem to be crowding your pizza with ingredients! Each ingredient should show up r times :) – RGS – 2020-02-17T17:46:06.417

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! – RGS – 2020-02-17T22:51:18.917

1You 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 :) ) – Gábor Fekete – 2020-02-18T10:37:25.967

Ok, ping me when you have the number of toppings fixed! :D – RGS – 2020-02-18T14:06:15.047

2

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.

Neil

Posted 2020-02-17T08:09:43.600

Reputation: 95 035

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 – RGS – 2020-02-17T13:51:58.723

@RGS I don't have a Euclidean distance primitive, and SquareRoot(Sum(Power([i, l], 2))) still takes 8 bytes. – Neil – 2020-02-17T14:03:18.403

ah I understand, that helps explaining it – RGS – 2020-02-17T17:41:39.350

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! – RGS – 2020-02-17T22:51:08.897

1@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...) – Neil – 2020-02-18T00:24:03.497