8
\$\begingroup\$

Inspired by this stack of little statues that are currently on my desk at work, given to me by my colleagues from Sri Lanka when they visited The Netherlands:

enter image description here

This is split into two different challenges due to popular demand:
Part 1) Determine the amount of statues (this challenge)
Part 2) Can the statues be stacked?

Challenge 1:

Input:

\$statues\$: a multi-line string (or character matrix), containing only the characters \n|-# (where the |-# can be other characters of your own choice)

Output:

The amount of statues in the input.

Statues input example:

      ##|
####    |
# ##
#  #  |##
----  |######
      |   ###
|##   |##   #
|## - |######
    # |####

The | and - represent the bases of the statues. So with the input above, we'll have the following statues:

       ####
       ## #
       ## ##
####   #  ##
# ##  ## ###  ##      #
#  #  ## ###  ##  #   #
----  ------  --  -  --

So the output will be 5.

Challenge rules:

  • You can use a different consistent character other than #, -, and/or | for the statue if you want ( \n are mandatory, though). Please state which one you've used in your answer if it's different than the defaults.
  • You are allowed to take the \$statues\$ input in any reasonable format. Can be a multi-line string, a list/array/stream of strings, a character matrix, etc.
  • You are allowed to pad the statues input with trailing spaces so it's a rectangle.
  • You can assume statues are always separated by at least one space or blank line from one-another, so something like #|#| or #||# won't be in the input.
  • You can assume the statues will only have a base at ones side, so a statue like this won't be in the input:
##|
##|
--
  • It is possible that a smaller statue is within the rectangular boundaries of another oddly shaped statue. For example, this is possible:
# ##
- ##
  ##
####
# # 
----
  • Statues will never be inside of each other, though. So something like this won't be in the input:
 #####
##   #
#  # #
# ## ##
# -- ##
#     #
##    #
-------
  • You can assume the base determines the width of a statue. So you won't have statues like these in the input:
#######
 #####
 ####     ###
  ---     --

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code (i.e. TIO).
  • Also, adding an explanation for your answer is highly recommended.

Test cases:

      ##|
####    |
# ##
#  #  |##
----  |######
      |   ###
|##   |##   #
|## - |######
    # |####

Output: 5
__________________________________________________

# ##
- ##
  ##
####
# # 
----

Output: 2
__________________________________________________

      #
|###  #
| #   #
|#### -

Output: 2
__________________________________________________

--- ##|
### ##|
###
### |#

Output: 3
__________________________________________________

####             #####|
# ##
###              |#           |#
#####            |#           |##
-----            |#           |#
                 |#
                 |#
                 |#

Output: 4
__________________________________________________

|# |# |# |# |# #| #| #|

Output: 8
__________________________________________________

|##
|   ##
|#  --

Output: 2
__________________________________________________

      |##
----  |####
# ##
###   |#
      |#  ###|
      |#    #|
      |#   ##|
      |#

Output: 4
__________________________________________________

- |##
#      #
  #| ###
  #| ---

Output: 4
__________________________________________________

#
####
----

--
 #

Output: 2
__________________________________________________
##
##
--

--
##
##

Output: 2
\$\endgroup\$
7
  • 2
    \$\begingroup\$ The second-to-last test case has an _ instead of -. This does look better, but it is not intended, right? \$\endgroup\$ – ovs Dec 15 '20 at 13:44
  • \$\begingroup\$ @ovs Woops.. should be fixed. \$\endgroup\$ – Kevin Cruijssen Dec 15 '20 at 14:40
  • \$\begingroup\$ suggested test case \$\endgroup\$ – Razetime Dec 15 '20 at 14:46
  • \$\begingroup\$ @Razetime The statues are guaranteed to be split by at least a space or blank line. But if you want I can add this test case? (I've edited newline to blank line in the rules.) \$\endgroup\$ – Kevin Cruijssen Dec 15 '20 at 14:51
  • \$\begingroup\$ Yeah, that's also similar. \$\endgroup\$ – Razetime Dec 15 '20 at 14:54
3
\$\begingroup\$

Jelly, 11 bytes

,ZŒrFċ¥"Ø^S

Try it online!

The statues have a polished bottom, so they use / instead of - and \ instead of |. The input is a list of strings that must be the same length.

Explanation

,ZŒrFċ¥"Ø^S   Main monadic link
,             Pair the input
 Z            with the input transposed
  Œr          Run-length encode everything
       "      Zip with
      ¥       (
    F           Flatten left argument
     ċ          Count the occurences of right argument
      ¥       )
        Ø^    with "/\"
          S   Sum
\$\endgroup\$
6
\$\begingroup\$

05AB1E, 15 bytes

„-|v€Åγ˜y¢Iø}Š+

Try it online!

Commented:

„-|              # push string literal "-|"
   v        }    # iterate over this string
    €Åγ          #   run-length encode each line of the input / transposed input
                 #   this pushes the chunk elements and the chunk lengths
       ˜         #   flatten the list
        y¢       #   count the chunks of the current character
          Iø     #   push the transposed input to the stack for the second iteration
             Š   # triple-swap: move the transposed input to bottom
              +  # sum both counts
\$\endgroup\$
5
\$\begingroup\$

Ruby, 93 86 61 58 bytes

Saved seven bytes, thanks to Razetime!
Saved three bytes, thanks to ovs!

->s{((s.transpose*"").scan(/\|+/)+(s*"").scan(/-+/)).size}

Try it online!

Takes input as a matrix of characters.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ -3(takes list of lines) \$\endgroup\$ – Razetime Dec 15 '20 at 14:15
  • \$\begingroup\$ Thanks, I further saved 3 bytes by s*"" ;-) \$\endgroup\$ – vrintle Dec 15 '20 at 14:21
  • 1
    \$\begingroup\$ -1 using *"" again \$\endgroup\$ – Razetime Dec 15 '20 at 14:23
  • \$\begingroup\$ You can replace (&:join) with a block {_1*""} if you're fine with using 2.7 \$\endgroup\$ – Razetime Dec 15 '20 at 14:26
  • 1
    \$\begingroup\$ If you concatenate both scan results and take the length of that, this is 3 bytes shorter: ->s{((s.transpose*"").scan(/\|+/)+(s*"").scan(/-+/)).size}. \$\endgroup\$ – ovs Dec 15 '20 at 15:10
5
\$\begingroup\$

Retina 0.8.2, 37 bytes

-+|(?<=(.)*)¦(?!.*¶(?<-1>.)*(?(1)$)¦)

Try it online! Uses ¦ instead of |. Explanation:

-+|

Count runs of -s, or...

(?<=(.)*)¦(?!.*¶(?<-1>.)*(?(1)$)¦)

... any ¦s which do not have a ¦ directly underneath them on the next line. This uses a .NET balancing group to ensure that the two ¦s are vertically aligned.

\$\endgroup\$
3
\$\begingroup\$

Perl 5 (-p), 50, 30 bytes

Using I instead of | (first rule), and padding input with trailing spaces so it's a rectangle (third rule).

/
/;$_=()=/-+|I(?!.{@{-}}I)/gs

Try it online!

How

  • /-+|I(?=.{@{-}}I)/gs to match - runs or | not followed by | bellow
  • (()=...) list context
  • $_= list is coerced to int size

Saved 13 bytes negating the lookahead, similarly to @Neil's retina answer.

\$\endgroup\$
1
  • \$\begingroup\$ Nice use of the Saturn operator =()=! \$\endgroup\$ – Neil Dec 16 '20 at 10:33
2
\$\begingroup\$

Charcoal, 36 bytes

WS«Fι«F²⊞υ›⁼κ§-|λ⁼⊟KD²✳∨⊗λ⁴κκ»⸿»⎚IΣυ

Try it online! Link is to verbose version of code. Finally managed to beat Retina. Explanation:

WS«

Repeat on each line of input.

Fι«

Repeat on each character.

F²⊞υ›⁼κ§-|λ⁼⊟KD²✳∨⊗λ⁴κ

If the character is a - or a |, then check whether the character to the left is also a - or character above is also a | as appropriate. Record whether this character therefore begins a new statue.

κ»⸿»

Print the character and start a new line for every line of the input.

⎚IΣυ

Print the total number of statues seen.

My previous 38-byte approach used direct calculation:

WS⊞υιIΣ⁺Eυ⁻№ι-L⌕Aι--EEθ⭆υ§λκ⁻№ι|L⌕Aι||

Try it online! Link is to verbose version of code. Requires padded input. Explanation: Each base of each horizontal statue contains a number n -s. But it also contains n-1 --s, if you include overlaps, which the FindAll command does. Therefore the number of horizontal statues in a line is the number of -s minus the number of overlapping --s. It then remains to transpose the input and count the difference between the number of |s and the number of overlapping ||s.

\$\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.