8
\$\begingroup\$

In the video game Minecraft, you can obtain beacons and put them on pyramid-like structures to give you special effects, such as speed or jump boost.

Your task is to, given an effect, construct the beacon pyramid required for it.

There are multiple sizes of beacon pyramids, required for different effects. The largest has a size 9 base, and the smallest has a size 3 base.

These are the effects you can get, and the required pyramid for them (as specified by the official Minecraft wiki:

3:
  Speed I
  Haste I
5:
  Resistance I
  Jump Boost I
7:
  Strength I
9:
  Regeneration I
  Resistance II
  Jump Boost II
  Speed II
  Haste II
  Strength II

Beacons are constructed with the base at the bottom, then it goes up, decreasing the size by 2. Once we hit 1, there should be a beacon + at the top.

A beacon is defined as a +, but it needs a supporting pyramid to work.

You may assume the input is valid (ie, it is one of the effects specified here), and, optionally, you may assume the input is all lowercase. The # character should be used in the pyramid, and + as the beacon.

Examples:

Haste I
 +
###

Resistance I
  +
 ###
#####

Strength I
   +
  ###
 #####
#######

Regeneration I
    +
   ###
  #####
 #######
#########

Speed II
    +
   ###
  #####
 #######
#########

You must also take multiple effects as beacon pyramids can share blocks - however, one beacon cannot do more than one effect. You must use minimal blocks.

When taking multiple effects, you may use any reasonable input format such as a list, newline separated, etc. Additionally, you may take a singleton list for single beacons if you are using lists.

For these examples, I only list one possible solution, but there are multiple acceptable solutions.

Speed I, Haste II
    ++
   ####
  #####
 #######
#########
(another acceptable solution is the following,
these are both valid as they use the same amount of blocks)
    +
   ###
  #####
 #######+
##########
(the following is not valid for the same input; it doesn't use minimal blocks)
    +
   ###
  #####           +
 #######         ###
#########

Strength I, Strength I
   ++
  ####
 ######
########

(don't output things in brackets, if that isn't obvious enough)

\$\endgroup\$
  • \$\begingroup\$ It seems most of this challenge is about the combining of the pyramids, but you don't describe the rules for doing so (if they can "share" blocks, why can we not just output the bigger one?). (Also you say we "may" take multiple, when I think you mean "must be able to") \$\endgroup\$ – Jonathan Allan May 19 '17 at 8:08
  • \$\begingroup\$ @JonathanAllan Clarified. \$\endgroup\$ – Okx May 19 '17 at 8:10
  • \$\begingroup\$ No, I still do not know the rule for combining... \$\endgroup\$ – Jonathan Allan May 19 '17 at 8:11
  • \$\begingroup\$ @JonathanAllan I said that one beacon cannot do more than one effect. Is that not clear enough? \$\endgroup\$ – Okx May 19 '17 at 8:12
  • 3
    \$\begingroup\$ When I first looked at this I thought it would be trivial, and then I saw the part about having multiple beacon effects. :P \$\endgroup\$ – HyperNeutrino May 20 '17 at 16:21
9
\$\begingroup\$

Python 2, 216 195 bytes

def b(e):s=sorted(63372>>len(_)*2-14&3for _ in e)[::-1];f=s[0]+2;r=range(f);print"\n".join(reduce(lambda p,n:[p[i]+"+# "[cmp(i,f-n-2)]for i in r],s[1:],[" "*(f-i-1)+"+#"[i>0]*(2*i+1)for i in r]))

Try it online!

The function for printing the string with the pyramid structure is b, which is called with a list of the effects as its single argument.

This turned out longer than I expected, but I was at least happy that I was able to find the beacon size based on black magic.

Edit: was able to reduce byte count significantly by combining the reduce function into a lambda thanks to Python 2's cmp function.

\$\endgroup\$
  • 4
    \$\begingroup\$ Well done on your black magic ;) \$\endgroup\$ – Okx May 20 '17 at 15:56
7
+100
\$\begingroup\$

Charcoal, 75 71 60 54 48 bytes

A⟦⟧βWS⊞βI§14034244⁻Lι⁷FUPsorted⟦β⟧«G→→↖⁺ι¹#¦+Mι↙

Try it online!

The Python answer is also mine, but I wanted to try my first golf submission in Charcoal!

I also wanted to make sure I can hold down that bounty ;)

A⟦⟧β                        assign an empty list to β
WS                         while the next string input ι is truthy: (aka while the input is not an empty line)
    ⊞βI§14034244⁻Lι⁷       push level for ι into β (explained below)
FUPsorted⟦β⟧«             for each level ι in the sorted version of β:
    G→→↖⁺ι¹#                draw a triangle of "#"s with side lengths ι + 1
    ¦+                       draw a "+" (already on top vertex)
    Mι↙                     move down and left by ι cells (preparation for next level)
                             implicit end of for

All of the beacon names of the same length share a beacon level. As such, we can determine the beacon level of an effect from mapping the length (minus 7 to base it at zero) to the numbers in the string "14034244" (there is a 0 for clarity because length 9 does not correspond to an effect). This same idea is used in my Python answer, but with bit shifting to produce the numbers 0-3.

\$\endgroup\$
  • 1
    \$\begingroup\$ Thanks for using Charcoal! Also, I'd recommend adding the -a flag to print the AST if you want a kind of explanation in the TIO link as well \$\endgroup\$ – ASCII-only Jun 17 '17 at 3:25
  • 1
    \$\begingroup\$ Also, 48 bytes, from changing the input to variable to the input nilary operator \$\endgroup\$ – ASCII-only Jun 17 '17 at 3:28
  • 1
    \$\begingroup\$ Note, I'll be updating soon so WS⊞υI§14034244⁻Lι⁷F▷sυ«G→→↖⁺ι¹#¦+Mι↙ will be valid so keep in mind that υ and ▷s will be new \$\endgroup\$ – ASCII-only Jun 17 '17 at 4:48
  • \$\begingroup\$ Thank you so much for the tips! I look forward to golfing more in Charcoal :D \$\endgroup\$ – notjagan Jun 17 '17 at 15:52
2
\$\begingroup\$

Jelly, 68 bytes

FṀ‘
0;Ṗ
|Ç€|Ḋ€Ç|
⁽lƑb4‘ị@L€ṢµI‘ż@IṚṭṀṭ0Fs2+\µḅÑ‘Ṭ;0sѵ+ÇÐLị“#+ ”Y;”#

Try it online!

I think the reason this is longer than the Charcoal answer (even though I was able to do my 'black magic' in 10 bytes) is because Charcoal was built for two-dimensional drawing. I ended depending on a 2D cellular automaton to find the positions of #s given the positions of +s to create triangles.

How it Works (main link split for readability)

FṀ‘
0;Ṗ
|Ç€|Ḋ€Ç|
⁽lƑb4‘ị@L€ṢµI‘ż@IṚṭṀṭ0Fs2+\µḅÑ‘Ṭ;0sѵ+ÇÐLị“#+ ”Y;”# - Main link, input is list of strings
⁽lƑb4‘ị@L€Ṣ     - list of strings to list of heights (1,2,3,4)
⁽lƑ               - the number 28147
   b4‘            - base 4 and incremented: [2, 3, 4, 2, 4, 4, 1, 4]
        L€        - lengths of each input string
      ị@          - index into the list to get a list of heights
          Ṣµ      - sort and store for the next link:
I‘ż@IṚṭṀṭ0Fs2+\ - get list of coordinates for `+`s
I‘ż@I             - [0,1] between each element. Add [1,1]*n between each pair of elements with difference n
     Ṛ            - Reverse
      ṭṀṭ0        - prepend [0,maximum]
          Fs2     - format the array as a list of coordinate pairs
             +\   - cumulative sum
ḅÑ‘Ṭ;0sÑ        - convert to binary rectangular matrix:
ḅÑ‘               - change each coordinate pair (y,x) to y*width+x (Ñ is the width)
   Ṭ              - boolean array with 1s at the above indices
    ;0            - append a zero for formatting reasons
      sÑ          - split into rows of the right width
µ+ÇÐL           - add locations of `#`s:  the matrix now has 2s at future `+`s, 1s at `#`s, and `0`s at spaces
  ÇÐL             - repeatedly apply a step of the cellular automoton: 1s at `#`s and `+`s, and 0s at space
µ+                - add this to the matrix of `+`s which has 1s at `+`s.
ị“#+ ”Y;”#      - format into a string
ị“#+ ”            - index into the string "#+ ".
      Y           - join by newlines.
       ;”#        - append a `#` character to finish up the formatting.
\$\endgroup\$

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.