| Bytes | Lang | Time | Link |
|---|---|---|---|
| 103 | Python 3.8 prerelease | 250904T145210Z | V_R |
| 076 | Perl 5 + p | 250408T201312Z | Dom Hast |
| 025 | Jelly | 250408T191934Z | Jonathan |
| 098 | Ruby | 250407T220325Z | Level Ri |
| 036 | 05AB1E | 250407T073439Z | Kevin Cr |
| 028 | Charcoal | 250407T084203Z | Neil |
| 085 | JavaScript Node.js | 250407T022653Z | l4m2 |
Python 3.8 (pre-release), 103 bytes
This may not be the best solution, but I thought it worth posting because it has a theme (reversal). Outputs lists of strings with "1" instead of "∩", which I will argue should be penaltyless, since the literal "1" is not found in the code, although 1 is.
lambda n:print([bin(x)[:1:-1].replace("0"," ")for x in[32,132,32,80,330,594,168,693,1453,427][2-n::3]])
Explanation
The core algorithm is to store each line of output as a binary number, printing 3-4 of these lines depending on the (zero-indexed) input number n.
OP says It's acceptable to have zero space between cups in adjacent pyramids., and I take advantage of this to shorten the number of bits in the binary numbers. The numbers are stored in base 10 in the code.
The output for n=2 has four lines, whereas the other outputs have three. Usually having outputs of different lengths means you can't use the slicing trick on lists with (in this case) [n::3] to get every third number starting at n. We can get around this by reversing the order of the items in the list and slicing with 2-n::3. Only when n=2 is 2-n=0, and the list is just long enough that if and only if 2-n=0 is there space for a fourth item.
For the binary numbers themselves, note that the lines of the outputs start with different characters: some lines with and some with ∩. This makes it hard to encode the outputs as binary without running into issues with leading 0s. However, each line ends with the same character, ∩. This means we can encode ∩ as 1 and as 0 if we encode each output line backwards. This means our code needs to convert our base-10 numbers back to binary (bin(x)), get rid of the 0b prefix (bin(x)[2:]) and reverse with (bin(x)[2:][::-1]). However, these string slices can be combined as bin(x)[:1:-1], saving a few bytes.
So we encode the data backwards as a list of binary numbers and index into the list backwards.
Perl 5 + -p, 76 bytes
$_=('6
1313
01','25
1131
0','5
41
311
0')[$_].1x5;s/./(($")x hex$&).'∩'/ge
Jelly, 25 bytes
ị“ʠTJ‘BŒBS3ƤẒŻƊƬṚa⁽œṡo⁶ỌY
A monadic Link that accepts the state as a positive integer from \$\{1,2,3\}\$ and yields a list of characters. Also, a full program that accepts the same and prints the result.
Note that:
- There is a triangle of spaces above the pyramids
- The pyramids have additional spaces between them
Both appear to be allowed, and both aid the golf.
How?
The left-half of each state's base row is encoded in a byte, which is fetched and processed to build the rest of the state:
ị“ʠTJ‘BŒBS3ƤẒŻƊƬṚa⁽œṡo⁶ỌY - Link: integer, N
“ʠTJ‘ - Code-page indices = [165, 84, 74]
ị - {N} 1-index into {that}
B - convert to binary -> HalfBaseRowBits
ŒB - bounce -> BaseRowBits
Ƭ - collect up while distinct, applying:
Ɗ - last four links as a monad - f(Current):
3Ƥ - for each 3-slice of {Current}
S - sum {the three bits} -> 0, 1, or 2
Ẓ - is prime? (vectorises)
- i.e. [v==2 for v in {3-slice sums}]
Ż - prefix {that} with a zero -> NextRowBits
Ṛ - reverse {these rows}
a⁽œṡ - logical AND 8745 - replace 1s with 8745s
o⁶ - logical OR space - replace 0s with spaces
Ọ - cast to characters - replace 8745s with ∩s
Y - join with newline characters
- (implicit print when run as a full program)
Ruby, 102 98 bytes
->i{"
TyBfx\32*2x"[i*3,j=3+i/2].bytes{|k|puts (" "*j-=1)+("%07b"%k+=6).tr("01"," ∩").chars*" "}}
longer than I hoped but it works. Accepts a number 0..2
05AB1E, 37 36 bytes
•U₅Ā8AÞ‡|ÔδÚ5∍–ŒZ•3äRIè„
ŽYнçšÅвJ.º
Takes the 0-based index as input.
Try it online or verify all three outputs.
Explanation:
•U₅Ā8AÞ‡|ÔδÚ5∍–ŒZ•
# Push compressed integer 38058123976930001615649986047041278960
3ä # Try to split it into 3 equal-sized parts, where the trailing part(s)
# could be one character shorter:
# [3805812397693,"0001615649986","047041278960"]
R # Reverse this list
Iè # Pop and keep the 0-based input'th integer
„ \n # Push string " \n"
ŽYн # Push compressed integer 8745
ç # Convert it to a character with this codepoint: "∩"
š # Convert the earlier string to a list and prepend this: ["∩"," ","\n"]
Åв # Convert the larger integer to this custom base,
# aka, convert it to base-3, and index into this list of three characters
J # Join everything together to a string
.º # Mirror vertically with overlap
# (after which the result is output implicitly)
See this 05AB1E tip of mine (section How to compress large integers?) to understand why •U₅Ā8AÞ‡|ÔδÚ5∍–ŒZ• is 38058123976930001615649986047041278960 and ŽYн is 8745.
Charcoal, 28 bytes
F§⪪”)⊞″?;”³N«G↗↘Iι…∩ ¶ ⁵→→
Try it online! Link is to verbose version of code. Takes 1-indexed input. Explanation:
F§⪪”)⊞″?;”³N«
Split the compressed string 14123233 into groups of 3, cyclically index by the input step, then loop over the digits.
G↗↘Iι…∩ ¶ ⁵
Draw a pyramid of that size, but using a complex fill so that ∩s only appear at alternating positions. Charcoal automatically counts 3 bytes for ∩, which is why I use …...⁵ to repeat the ∩ as this saves a byte.
→→
Move to the next pyramid.
JavaScript (Node.js), 85 bytes
n=>([`8
3424
2`,`46
3242
`,`7
62
522
`][n]+222222).replace(/./g,k=>'∩'.padStart(k))