38
\$\begingroup\$

Here is an example of an input of monoliths. There are 4 in this example.

  _
 | |        _
 | |  _    | |
 | | | |   | |     _
_| |_| |___| |____| |_

The first monolith is 4 units high, the second is 2, the third is 3, and the last is 1.

The task

Your program should output the heights of the monoliths in order from left to right. The output format can be in any sort of list or array.

Notes

  • The input can be taken as any dimensional string, list of strings, or list of characters.
  • This is , so lowest bytes wins.
  • You are to assume that monoliths always have the same width, and are always at least 1 _ away from another.
  • They can come in any height, and in any quantity.

I/O

  _
 | |        _
 | |  _    | |
 | | | |   | |     _
_| |_| |___| |____| |_   >> [4,2,3,1]

           _
          | |
  _       | |
 | |  _   | |  _
_| |_| |__| |_| |_   >> [2,1,4,1]


 _   _   _ 
| |_| |_| |_____   >> [1,1,1]

____________________   >> undefined behavior

 _
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |   >> [11]

     _       _       _       _       _
 _  | |  _  | |  _  | |  _  | |  _  | |
| |_| |_| |_| |_| |_| |_| |_| |_| |_| |  >> [1,2,1,2,1,2,1,2,1,2]
\$\endgroup\$
9
  • 3
    \$\begingroup\$ May I assume the input is right padded with spaces? \$\endgroup\$
    – isaacg
    Jun 30, 2017 at 2:46
  • 17
    \$\begingroup\$ Is your [10] monolith not [11] ? \$\endgroup\$ Jun 30, 2017 at 6:47
  • 1
    \$\begingroup\$ @SolomonUcko technically yes, though to make it simpler for all languages I decided to not have them deal with it. \$\endgroup\$
    – Graviton
    Jul 1, 2017 at 3:02
  • 2
    \$\begingroup\$ @SolomonUcko Yes, exactly. Primarily because some algorithms might fail at that test, and have to create more code just for that exception. Which drives the average byte count up (which is no fun). \$\endgroup\$
    – Graviton
    Jul 1, 2017 at 18:30
  • 2
    \$\begingroup\$ Bit late to ask, but does the spec guarantee that all monoliths have a single _ on top as in the test cases, or merely that they always have the same width per input? \$\endgroup\$ Mar 26 at 0:31

39 Answers 39

1
2
1
\$\begingroup\$

Pip, 18 17 bytes

15 bytes of code, +2 for -rp flags.

_FI_@?'_MRVgZDs

Takes input from stdin. Try it online!

Explanation

                 g is list of lines from stdin (-r flag); s is space
         RVg     Reverse g
            ZDs  Zip (transpose), filling gaps with a default char of space
        M        Map this function:
   _@?'_          Index of _ in each line (or nil if it doesn't appear)
_FI              Filter, keeping only the truthy (nonzero, non-nil) values
                 Autoprint in repr format (-p flag)
\$\endgroup\$
1
\$\begingroup\$

Pyth, 19 15 14 bytes

f>T0mx_d\_.tQd

Test it online! The input is a list of lines.

Explanations

          .tQd     # Transpose, pad with spaces
    mx_d\_         # For each line, reverse it, find the position of "_" (-1 if not found)
f>T0               # Filter on positions greater than zero
\$\endgroup\$
1
\$\begingroup\$

Octave, 31 bytes

@(a)(s=sum(a>95))(s>0)(1:2:end)

Takes a 2D array of chars as input.

Verify all test cases!

\$\endgroup\$
1
\$\begingroup\$

Perl 6, 65 bytes

{m:ex/^^(\N+)_([\N*\n]+:)/.sort(*[0].chars).map(+*[1].comb("
"))}

Try it online!

  • m:exhaustive/^^(\N+)_([\N*\n]+:)/ searches the input string for all underscores, and returns a match object for each, where the first capturing parentheses contain the preceding part of the line on which the underscore is found, and the second capturing parentheses contain the entire rest of the string. The rest of the string must contain at least one newline, so we don't count the underscores at ground level. The :exhaustive flag allows these matches to overlap.
  • .sort(*[0].chars) sorts these match objects by the number of characters in the part of the line preceding each underscore. This orders them left-to-right.
  • .map(+*[1].comb("\n")) maps each match object to the number of newline characters in the part of the input string trailing each underscore--that is, the height. The \n is an actual newline character, saving one byte.
\$\endgroup\$
1
\$\begingroup\$

PHP, 119 bytes

function($s){$r=array_map(null,...$s);foreach($r as$k=>&$v)if($v=array_count_values($v)['|'])echo($v+$r[$k+2]=0)." ";};

Let's break this down! Our input here is a 2D array of chars.

$r=array_map(null,...$s) // Neat little snippet to transpose the array

foreach($r as$k=>&$v)    // Loop through the array, grabbing each row of our 2D array 
(which is now each column of the monolith)

if($v=array_count_values($v)['|']) // Count the number of '|' characters in the column 
(which is the height of our monolith), and if it's greater than 0 (truthy in PHP)...

echo($v+$r[$k+2]=0)." "; // Output that number, and simultaneously set the row 2 indices
                            down to null (to remove duplicate values)
\$\endgroup\$
1
\$\begingroup\$

Japt, 9 bytes

Takes input as an array of lines.

Õ®x2 èSÃf

Try it (header splits input string to array) or run all test cases

Õ®x2 èSÃf     :Implicit input of array
Õ             :Transpose
 ®            :Map
  x2          :  Trim left
     è        :  Count
      S       :    Spaces
       Ã      :End map
        f     :Filter
\$\endgroup\$
1
\$\begingroup\$

Jelly, 9 bytes

ṖZ=”_UT€F

Try it online!

Unfortunately, Jonathan Allan's answer is still shorter, as I assume input is a list of lines, so don't count the . However, I reckon this is an interesting enough approach to post

How it works

ṖZ=”_UT€F - Main link. Takes a list of lines L on the left
Ṗ         - Remove the last line
 Z        - Transpose
  =”_     - Check each character for equality with "_"
     U    - Reverse each row
       €  - For each row
      T   - Yield the indices of 1
        F - Flatten
\$\endgroup\$
1
\$\begingroup\$

R, 114 99 bytes

\(u){`+`=length
for(j in 2:+u-1){F=c(a<-which(u[[j]]=="_"),F)
T=c(rep(+u-j,+a),T)}
T[order(F)][-1]}

Attempt This Online!


The monoliths are looking like barplots, and so, it is natural to use R. Surprisingly though, nobody has yet golfed this in R.

  • The function takes as an input a list of vectors (1D arrays) of chacters; I have added strsplits to the function call (see the link below) for better readability
  • f(strsplit(strsplit("____________________","\n")[[1]],"")) throws an error

History:

  • -14 bytes thanks to pajonk
  • -1 byte golfed myself
\$\endgroup\$
3
  • 3
    \$\begingroup\$ Nice solution! Some golfs for -14 bytes: ato.pxeger.com/… \$\endgroup\$
    – pajonk
    Mar 23 at 20:20
  • 3
    \$\begingroup\$ @pajonk impressive golfing! would you like to write your own answer? \$\endgroup\$ Mar 24 at 10:30
  • 1
    \$\begingroup\$ Nah, the core algorithm is yours, from me just some minor improvements. \$\endgroup\$
    – pajonk
    Mar 24 at 12:50
0
\$\begingroup\$

Haskell + hgl, 20 bytes

fl gt0<fa"_"~<<tx<Rv

Attempt This Online!

Some late night golfing, I'll probably find a way shorter version tomorrow.

Explanation

  • Rv reverse the rows
  • tx transpose
  • fa"_" find the index of _ in the column ignoring columns without a _
  • fl gt0 remove 0s

Reflection

  • All of the following presets with _ could have been useful here:
    • ce '_'
    • e '_'
    • fa"_"
  • Related to that it might be nice to have a version of ce which takes a list and counts all elements in that list appearing in the input. This would be generally useful but would also save a byte on using ce to find specific characters.
  • eq0 is 3 bytes, but seems generally useful. If it were 2 bytes we could do fn q0 here instead of fl gt0 to save a byte.
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.