11
\$\begingroup\$

At the time of writing this puzzle, there are soon to be 269 puzzles related to primes. To celebrate/mourn this event (269 is prime), this challenge will be about exploding primes. In preparation for this task, I've obtained a permit (legal, I assure you) for dynamite charges of military grade, along with enormous dynamite itself. Unfortunately, I also have a lot of junk in my warehouse, and I've packaged everything (and I mean everything) into ASCII text.

From sizes 1 to 6 (actual input sizes can be arbitrarily large), here are examples of my enormous dynamite:

                             +
                          ___L__ 
                     +   |      |
                   __L__ |      |
               +  |     ||      |
             __L_ |     ||      |
         +  |    ||     ||      |
        _L_ |    ||     ||      |
     + |   ||    ||     ||      |
    _L |   ||    ||     ||      |
 + |  ||   ||    ||     ||      |
 L |  ||   ||    ||     ||      |
| ||  ||   ||    ||     ||      |
|_||__||___||____||_____||______|
                                                                  __________________ 
                                               _______________   |                  |
                               ____________   |               |  |                  |
                  _________   |            |  |               |  |                  L-*
        ______   |         |  |            L-*|               L-*|                  |
 ___   |      L-*|         L-*|            |  |               |  |                  |
|___L-*|______|  |_________|  |____________|  |_______________|  |__________________|

The pattern for size n vertical dynamite is two 2n-high columns of | separated by n spaces in the middle/_s on the bottom and top. The bottom _s will be surrounded by |s, but the top _s will be surrounded by spaces. There will be an L under a + replacing the mid-point (biased right) of the top _s.
The pattern for size n horizontal dynamite is two n-wide rows of _ separated by n-1 space-filled rows in the middle. There will be n+1-high columns on the left and right, out of which the top character will be a space, and others will be |. There will be an L with a * on the right replacing the mid-point (biased upwards) of the right |s.

As my best and brightest assistant, you will need to help me determine how many primes each ASCII package (input grid) can destroy. Your task is to count all the valid dynamite within a package, taking into account the size. You will output a string like so: BOOM! # prime(s) primed for destruction, where # is the total computed dynamite size in the package.

Examples

Input:
 ______ 
|      L-*
|______|
Output:
BOOM! 2 prime(s) primed for destruction
Reasoning:
Single piece of dynamite of size 2

Input:
Output:
BOOM! 0 prime(s) primed for destruction
Reasoning:
Empty string contains no dynamite

Input:
   __+_
   \_|_\
   /_|_/
  ___L___
~~\_____/~~
Output:
BOOM! 0 prime(s) primed for destruction
Reasoning:
Despite being cute and non-empty, this ASCII ship from my warehouse has no dynamite in it

Input:
 ____________ 
|            |
|    ___     L-*
|   |___L-*  |
|____________|
Output:
BOOM! 1 prime(s) primed for destruction
Reasoning:
Dynamite is non-recursive - the outer dynamite doesn't count at all, 
but the inner dynamite is valid and will blow up 1 prime.

Input:
 +
 L
| |
|_|
Output:
BOOM! 0 prime(s) primed for destruction
Reasoning:
A space character is missing to the right of the L - the box must be 
fully complete, although the + for vertical and -* for horizontal dynamite 
are not necessarily space-padded; all that is required for those elements 
is that they be aligned with the L.

Input:
                     +   
                   __L__ 
                + |     |
             __L_ |     |
         +  |    ||     | _____________________ 
        _L_ |    ||     ||                     |
     + |   ||    ||     ||                     |
    _L |   ||    ||     ||                     |
 + |  ||   ||    ||     ||                     L-*
 L |  ||   ||    ||     ||                     |
| ||  ||   ||    ||     ||                     |
|_||__||___||____||_____||_____________________|
Output:
BOOM! 18 prime(s) primed for destruction
Reasoning:
The size-4 dynamite is malformed, but all the other pieces of dynamite 
are valid. Summing the dynamite sizes within this package yields 
1 + 2 + 3 + 5 + 7 = 18 units of dynamite.

Input:
   A
  C+C
 M L M
E | | E
 M|_|M
  C C
   A
Output:
BOOM! 1 prime(s) primed for destruction
Reasoning:
The dynamite's box is properly surrounded by spaces, and the tip is not 
required to be surrounded by spaces. Therefore, this is a valid piece of 
dynamite that can explode 1 prime.

Input:
 +
 L ______ 
| |      L-*
|_|______|
Output:
BOOM! 3 prime(s) primed for destruction
Reasoning:
Although the 2 pieces of dynamite intersect, each on their own satisfies
the parameters for enormous dynamite. Therefore, the pieces can explode
1 + 2 = 3 primes together.

Rules

Input will be an ASCII grid/string of characters in any reasonable format. Output must be a correctly computed string consisting of BOOM! # prime(s) primed for destruction, where # is the total computed dynamite size in the input.

Your answer may be a function or full program (both will be scored according to the same metrics).

Exploiting standard loopholes is forbidden.

Scoring

This is - shortest code wins. Go out there and explode some primes :)

\$\endgroup\$
  • 5
    \$\begingroup\$ I'm (slowly) refurbishing on an old record player from 1959 whose capacitors look exactly like that and explode the same way. BOOM! \$\endgroup\$ – Arnauld Nov 13 at 17:12
  • \$\begingroup\$ @Arnauld That's pretty interesting - sounds like you're inadvertently well prepared for a prime-hunting expedition \$\endgroup\$ – Avi Nov 13 at 17:14
5
+100
\$\begingroup\$

JavaScript (ES8),  298 ... 272  267 bytes

Takes input as an array of strings.

a=>`BOOM! ${a.map((s,y)=>s.replace(/ _*(L?)_*(?= )/g,(s,L,x)=>t+=(w=s.length,L?y&&s[d=w+1>>1]+a[y-1][k=w*2-1,x+d]=='L+'&&~-w:k=w/3|0)*(v=L?0:++k+1>>1,g=c=>!--k||(a[y+k]+g).indexOf('|'.padEnd(w,c)+(--v?'|':'L-*'),x)==x&g())`_`),t=0)|t} prime(s) primed for destruction`

Try it online!

How?

For each line, we look for the following pattern:

/ _*(L?)_*(?= )/g

The above regular expression matches a space followed by a sequence of _ with or without a single L within it, followed by a space. We use a lookahead for this last space, so that it can be combined with the first space of another pattern immediately following.

If a L is captured, the pattern is interpreted as the top of a vertical dynamite stick. In this case, we make sure that the L is located at the expected position and that there is a + above it.

If no L is captured, the pattern is interpreted as the top of a horizontal dynamite stick.

In both cases, we use the recursive helper function \$g\$ to test the body of the stick. There's a special case in this function to make sure that we have L-* at the end of the middle row of a horizontal stick. All other rows are expected to be a sequence of _ or spaces surrounded by two |.

Commented

Wrapper

a => `BOOM! ${...} prime(s) primed for destruction`

Main code

a.map((s, y) =>                  // for each string s at position y in the input a[]:
  s.replace(                     //   for each string s
    / _*(L?)_*(?= )/g,           //   matching / _*(L?)_*(?= )/
    (s, L, x) =>                 //   with L = captured 'L' and x = position:
      t += (                     //     update t:
        w = s.length,            //       w = length of matched string
        L ?                      //       if a 'L' was captured:
          y &&                   //         if y is not equal to 0
          s[d = w + 1 >> 1] +    //         and the character at floor((w+1)/2)
          a[y - 1]               //         followed by the character above it ...
          [k = w * 2 - 1, x + d] //         (set k to 2w-1)
          == 'L+' && ~-w         //         ... form the string 'L+', yield w-1
        :                        //       else:
          k = w / 3 | 0          //         yield k = floor(w/3)
      ) * (                      //       multiply this by the result of g():
        v = L ? 0                //         if a 'L' was captured, set v to 0
              : ++k + 1 >> 1,    //         else, increment k and set v to floor((k+1)/2)
        g = c =>                 //         g is a recursive function taking a character c:
          !--k ||                //           decrement k and stop if it's equal to 0
          (a[y + k]              //           otherwise, take the entry at y+k,
                    + g)         //           coerce it to a string in case it's undefined,
          .indexOf(              //           look for the position of this substring:
            '|'.padEnd(w, c) +   //             a '|' followed by c repeated w-1 times
            (--v ? '|' : 'L-*'), //             followed by either a '|' or 'L-*' if v = 0
            x                    //             starting from x
          ) == x                 //           and make sure it's equal to x
          & g()                  //           recursive call with c undefined
      )`_`                       //       initial call to g with c = '_'
  ),                             //   end of replace()
  t = 0                          //   start with t = 0
) | t                            // end of map(); return t
\$\endgroup\$
4
\$\begingroup\$

Perl 5 (-Minteger -00p), 323 bytes

Gives the correct output for tests, to be golfed more

for$s(2..y/
//){$t=$s-1>>1;$u=$s/2-1;$v=2*$s-1;s/^ (___){$s} .*
(\|(   ){$s}\|.*
){$t}\|(?3){$s}L-\*.*
(?2){$u}\|(?1){$s}\||^...{$u}\+.*
 __{$u}L_{$t} .*
(\| {$s}\|.*
){$v}\|_{$s}\|/$\+=$s;$&/gme}s/^ ___ .*
\|___L-\*|^.\+.*
 L .*
\| \|.*
\|_\|/$\++;$&/gme;s/^.//gm&&redo}{$\|=0;$\="BOOM! $\ prime(s) primed for destruction"

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Nicely done! I look forward to further golfification :P \$\endgroup\$ – Avi Nov 14 at 20:49

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.