How tall are the monoliths?

29

5

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]

Graviton

Posted 2017-06-29T22:23:03.393

Reputation: 2 295

2May I assume the input is right padded with spaces? – isaacg – 2017-06-30T02:46:51.567

17Is your [10] monolith not [11] ? – TessellatingHeckler – 2017-06-30T06:47:52.817

Wouldn't the undefined one just be an empty array? – Solomon Ucko – 2017-07-01T02:03:30.137

@isaacg yes, that would be okay – Graviton – 2017-07-01T03:01:54.607

@SolomonUcko technically yes, though to make it simpler for all languages I decided to not have them deal with it. – Graviton – 2017-07-01T03:02:44.957

Ok. So basically, you can implement it like that, but don't have to? – Solomon Ucko – 2017-07-01T13:52:09.477

@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). – Graviton – 2017-07-01T18:30:18.287

I see, that makes sense. – Solomon Ucko – 2017-07-02T12:40:26.977

Answers

15

Jelly, (8?) 9 bytes

Ỵ=”|Sḟ0m2

A monadic link accepting a list of characters as specified and returning a list of integers.

Note: 8 bytes if a list of strings, one per line, was really intended to be an allowed input format - just remove the .

Try it online!

How?

Ỵ=”|Sḟ0m2 - Link: list of characters, s
Ỵ         - split at newlines
  ”|      - literal '|'
 =        - equals (vectorises)
    S     - sum (vectorises, hence counts the number of '|' in every column)
     ḟ0   - filter out zeros (only keep the results from the sides of the towers)
       m2 - modulo index with 2 (keep only the left side measurements)

Jonathan Allan

Posted 2017-06-29T22:23:03.393

Reputation: 67 804

I don't know, but is this okay?

– V. Courtois – 2017-06-30T07:16:45.263

1@V.Courtois I don't see why not, since we'll probably never get such input. – Erik the Outgolfer – 2017-06-30T07:44:52.207

Okay, it's because I saw that some other answers take it in count – V. Courtois – 2017-06-30T08:51:13.627

2@V.Courtois the input you suggested does not fit the specification, similarly adding underscores in the sky, part-way up monoliths, or underground would probably break many other submissions. – Jonathan Allan – 2017-06-30T11:15:24.350

Down-voter - would you care to explain your reasons? – Jonathan Allan – 2017-06-30T11:24:31.117

@JonathanAllan just noticed ^^ – V. Courtois – 2017-06-30T11:48:15.680

8

Jelly, 11 bytes

ỴṚZi€”_ỊÐḟ’

Try it online!

Erik the Outgolfer

Posted 2017-06-29T22:23:03.393

Reputation: 38 134

Wow, you answered that fast. – Graviton – 2017-06-29T22:28:13.030

@Graviton Hehe one should always have this page open somewhere. ;)

– Erik the Outgolfer – 2017-06-29T22:29:21.520

14Explanation, please! – Shaggy – 2017-06-29T22:51:58.120

6

C++, 171 169 bytes

#import<vector>
#import<iostream>
int f(std::vector<std::string>s){for(int a,j,i=0,k=s.size()-1;a=s[k][i];++i)if(a==32){for(j=0;(a=s[k-++j][i])-95;);std::cout<<j<<" ";}}

Try it online!

C++ (GCC), 150 bytes

Thanks to @aschepler!

#import<vector>
#import<iostream>
int f(auto s){for(int a,j,i=0,k=s.size()-1;a=s[k][i];++i)if(a==32){for(j=0;(a=s[k-++j][i])-95;);std::cout<<j<<" ";}}

Try it online!

Steadybox

Posted 2017-06-29T22:23:03.393

Reputation: 15 798

1If using g++, you can use the non-standard f(auto s) and specify it takes any random-access container of random-access containers of char. – aschepler – 2017-07-02T12:22:18.093

6

JavaScript (ES6), 79 78 bytes

-1 byte thanks to @Shaggy

a=>a.map((b,i)=>b.replace(/_/g,(_,j)=>o[j]=a.length-i-1),o=[])&&o.filter(x=>x)

Takes input as an array of strings.

Test Snippet

f=
a=>a.map((b,i)=>b.replace(/_/g,(_,j)=>o[j]=a.length-i-1),o=[])&&o.filter(x=>x)
I.value="           _\n          | |\n  _       | |\n | |  _   | |  _\n_| |_| |__| |_| |_"
<textarea id=I rows=7 cols=30></textarea><br><button onclick="O.value=`[${f(I.value.split`\n`).join`, `}]`">Run</button> <input id=O disabled>

Justin Mariner

Posted 2017-06-29T22:23:03.393

Reputation: 4 746

178 bytes: a=>a.map((x,y)=>x.replace(/_/g,(_,z)=>c[z]=a.length-y-1),c=[])&&c.filter(n=>n) – Shaggy – 2017-06-30T13:37:30.770

@Shaggy Nice, I totally didn't think of using replace. Thanks! – Justin Mariner – 2017-06-30T20:45:40.350

5

Dyalog APL, 29 bytes

{0~⍨↑+/(⌈/⍴¨⍵)↑¨(⍳≢⍵)×⌽⍵='_'}

Run with ⎕IO←0.

Try it online!

How?

⌽⍵='_' - where is '_', top lines first

×- multiply by ...

(⍳≢⍵) - the range of (zero indexed)

↑¨ - for each line, pad with zeros by ...

(⌈/⍴¨⍵) - the maximal length

↑+/ - sum the rows zipped and flatten

0~⍨ - removes zeros

Uriel

Posted 2017-06-29T22:23:03.393

Reputation: 11 708

5

05AB1E, 11 bytes

|Rζ'_δkJ®0‚K

Try it online!

ζ has been replaced by .Bø on TIO since it hasn't been pulled there yet.

Erik the Outgolfer

Posted 2017-06-29T22:23:03.393

Reputation: 38 134

5

Python 2, 75 bytes

lambda s:[x.index('_')for x in map(None,*s.split('\n')[::-1])if'_'in x[1:]]

Try it online!

GarethPW

Posted 2017-06-29T22:23:03.393

Reputation: 1 119

5

PowerShell, 133 bytes

param($s)$r=,0*($l=($s=$s-replace'\| \|',' 1 ')[0].Length);1..$s.Count|%{$z=$_-1;0..($l-1)|%{$r[$_]+=(''+$s[$z][$_]-as[int])}};$r-ne0

Looks like it's not very competitive; it does a regex replace to turn the towers into columns of 1, makes an array of 0 the length of the input string, then steps through the lines adding up the 1s.

Tests ready to run:

$s1 = @'
  _                   
 | |        _         
 | |  _    | |        
 | | | |   | |     _  
_| |_| |___| |____| |_
'@-split"`r?`n"


$s2 = @'
 _
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | 
'@-split"`r?`n"

$s3 = @'
           _      
          | |       
  _       | |           
 | |  _   | |  _   
_| |_| |__| |_| |_ 
'@-split"`r?`n"


$s4 = @'
 _   _   _      
| |_| |_| |_____ 
'@-split"`r?`n"

$s5 = @'
     _       _       _       _       _ 
 _  | |  _  | |  _  | |  _  | |  _  | |
| |_| |_| |_| |_| |_| |_| |_| |_| |_| | 
'@-split"`r?`n"

TessellatingHeckler

Posted 2017-06-29T22:23:03.393

Reputation: 2 412

4

Retina, 48 38 bytes

^
¶
{`(¶.*)*¶_(.*¶)+
$#2 $&
}`¶.
¶
G`.

Try it online! Link includes first example. Explanation: A line is prefixed which will collect the results. As each column is repeatedly deleted in turn, those that contains a _ above ground level have the the number of remaining lines in the column counted. Finally the now blank lines are deleted. Edit: Saved 10 bytes thanks to inspriation from @FryAmTheEggman.

Neil

Posted 2017-06-29T22:23:03.393

Reputation: 95 035

Nice, I had a slightly shorter solution, but it wouldn't work on large inputs since it would mess up my ability to sort them. Going column by column is a nice way to avoid that!

– FryAmTheEggman – 2017-06-30T01:48:33.203

@FryAmTheEggman I switched to your method of counting the lines using the _s which makes much more sense than trying to use the |s, thanks! – Neil – 2017-06-30T07:39:25.240

@FryAmTheEggman Doesn't fix the problem, but your sorting stage can be simplified by dropping the lookbehind and sorting by $.%\``, and the final stage can be!`\d+`. And if you change the first stage to a lookahead, you don't need to loop. – Martin Ender – 2017-06-30T07:50:51.047

@FryAmTheEggman And here is a fix to your approach, but it ends up at 46 bytes.

– Martin Ender – 2017-06-30T07:56:14.473

@MartinEnder 45 perhaps? Try it online!

– Neil – 2017-06-30T08:01:28.997

Ah yeah, nice idea. Still too long unfortunately :) – Martin Ender – 2017-06-30T08:05:50.597

If we can assume that the input is padded to a rectangle, here is yet another approach that transposes the input (41 bytes): https://tio.run/##K0otycxL/P9fhevQNhU91QQVLVsuf2WV4gQ9LhCXKzgh3t6WKx7EUedSTIhJ0f7/X0EhXgEL4FKoAUIIiMcUBwnBGQhxsBCcAZLkigcywRiVAQA

– Martin Ender – 2017-06-30T08:17:10.210

@MartinEnder I shall have to remember that transposition trick! – Neil – 2017-06-30T08:41:23.363

@Neil it's much easier for square inputs, because the linefeeds can remain in the correct position, so you only need that sorting stage and you can drop the s from it. – Martin Ender – 2017-06-30T08:46:04.210

4

Japt, 11 bytes

z ·mb'_ fw0

Test it online!

Explanation

z ·mb'_ fw0   : Implicit input
z             : Rotate the input clockwise. This puts the "floor" against the left side.
  ·           : Split the 2D string into lines.
   m          : Replace each column (now row) X with
    b'_       :   the index of '_' in X (0-indexed). This gives us the output list, with
              :   0's and -1's mixed in representing the columns that are not monoliths.
        f     : Take only the items X where
         w0   :   max(X, 0) is truthy. Since 0 is falsy, this removes anything <= 0.
              : Implicit: output result of last expression

ETHproductions

Posted 2017-06-29T22:23:03.393

Reputation: 47 880

4

Java 8, 133 117 116 114 bytes

a->{for(int l=a.length-1,i=0,j;i<a[0].length;i++)if(a[l][i]<33){for(j=0;a[j][i]<33;j++);System.out.print(l-j+",");}}

Takes the input as a String[] char[][] (← saves 16 bytes).
-2 bytes in exchange for less readable output thanks to @OlivierGrégoire by changing print(l-j+",") to println(l-j).

Explanation:

Try it here.

a->{                         // Method with character 2D-array parameter and no return-type
  for(int l=a.length-1,      //  Length of the 2D char-array - 1
      i=0,j;                 //  Index-integers
    i<a[0].length;i++)       //  Loop (1) over the 2D char-array
    if(a[l][i]<33){          //   If the base of the current column is a space
      for(j=0;a[j][i]<33;    //    Loop (2) over the cells in this column as long as
                             //    we encounter spaces (from top to bottom)
        j++                  //     And increase `j` every time, to go down the column
      );                     //    End of loop (2)
      System.out.println(l-j);
                             //    Print the amount of rows - `j`
    }                        //   End of if-block
                             //  End of loop (1) (implicit / single-line body)
}                            // End of method

Kevin Cruijssen

Posted 2017-06-29T22:23:03.393

Reputation: 67 575

I haven't tried it yet but my idea for this challenge was to go top to bottom and look for _ if found store it's location then order on that, ignoring the bottom row of course. Might help to save bytes... – TheLethalCoder – 2017-06-30T08:09:53.277

@TheLethalCoder That was my initial thought as well, but where do you want to store it in / order it? I originally thought a Map, but those are unsorted so you'll need a LinkedMap. In my head it all sounded a bit too much bytes, but if you can find a way to accomplish it shorter than this feel free to post an answer and I'll +1 it. :) – Kevin Cruijssen – 2017-06-30T08:23:33.537

I only managed to get it down to 150 using Linq but there should be room for golfing it still. – TheLethalCoder – 2017-06-30T09:39:17.170

In C# we have multidimensional arrays like: new[,] instead of the jagged array you are using as new[][]. If you have that in Java it could save you some bytes. – TheLethalCoder – 2017-06-30T13:19:55.237

@TheLethalCoder That's the way Java uses multidimensional arrays I'm afraid. char[] = char-array; char[][] = 2D char-array; char[][][] = 3D char-array; etc. – Kevin Cruijssen – 2017-06-30T13:28:48.857

That's unfortunate we have both in C# so it comes in handy sometimes. – TheLethalCoder – 2017-06-30T13:29:37.717

1System.out.println(l-j); looks listy enough for me to spare 2 bytes. Also, in the explanation, you forgot to change length() into length (no incidence on the byte-count as it's correct in the submission). – Olivier Grégoire – 2017-07-01T13:26:14.877

3

Haskell, 75 74 bytes

import Data.List;f=filter(>0).map(length.fst.span(<'!').reverse).transpose

The input is expected as a list of strings (rowwise).

siracusa

Posted 2017-06-29T22:23:03.393

Reputation: 623

Why use a semicolon after the import, when a newline is the same length and more idiomatic? – Jules – 2017-06-30T10:45:47.217

@Jules: Yeah, I usually do – siracusa – 2017-06-30T11:19:47.517

3

MATL, 12 bytes

&nxG2\&fx-Xz

Input is a char matrix, with ; as row separator.

Try it online! Or verify all test cases.

Luis Mendo

Posted 2017-06-29T22:23:03.393

Reputation: 87 464

3

Ruby, 82 bytes

Takes in a list of lines.

->l{l.map! &:chars;(l.pop.zip(*l).map{|s|s.join.count ?|}-[i=0]).select{0<1&i+=1}}

Try it online!

Value Ink

Posted 2017-06-29T22:23:03.393

Reputation: 10 608

3

APL (Dyalog), 14 bytes

0~⍨⍳∘≢+.×'_'=⊖

with ⎕IO←0

Try it online!


This function train equivalent to {((⍳≢⍵)+.×('_'=⊖⍵))~0}

TwiNight

Posted 2017-06-29T22:23:03.393

Reputation: 4 187

3

C#, 150 144 137 bytes

using System.Linq;a=>a.SelectMany((i,h)=>i.Select((c,w)=>new{c,w,d=a.Length-1-h}).Where(o=>o.c==95&o.d>0)).OrderBy(o=>o.w).Select(o=>o.d)

Full/Formatted version:

using System;
using System.Collections.Generic;
using System.Linq;

class P
{
    static void Main()
    {
        Func<char[][], IEnumerable<int>> f = a =>
            a.SelectMany((i, h) => i.Select((c, w) => new { c, w, d = a.Length - 1 - h })
                                    .Where(o => o.c == 95 & o.d > 0))
             .OrderBy(o => o.w)
             .Select(o => o.d);

        Console.WriteLine(string.Concat(f(new char[][]
        {
            "  _                 ".ToArray(),
            " | |       _        ".ToArray(),
            " | |  _   | |       ".ToArray(),
            " | | | |  | |    _  ".ToArray(),
            "_| |_| |__| |___| |_".ToArray(),
        })));

        Console.ReadLine();
    }
}

TheLethalCoder

Posted 2017-06-29T22:23:03.393

Reputation: 6 930

3

Java 8 - 229 Bytes 213 Bytes

s->{Map<Integer,Integer> m=new TreeMap();String[] l=s.split("\n");for(int i=0,j=-1;i<l.length-1;++i){s=l[i];while((j=s.indexOf("_",j+1))>=0){m.put(j,i);}}for(int i:m.values()){System.out.print(l.length-i-1+",");}}

Try it online!

Ungolfed:

public static void foo(String input)
{
    Map<Integer, Integer> map = new TreeMap(); // Raw types!!
    String[] lines = input.split("\n");

    for (int i = 0, j = -1; i < lines.length - 1; ++i)
    {
        input = lines[i];

        while ((j = input.indexOf("_", j + 1)) >= 0)
        {
            map.put(j, i);
        }
    }

    for(int i:map.values())
    {
        System.out.print(lines.length - i - 1 + ",");
    }
}

Woo, first post. Any help improving it would be great. I know I can get rid of that indexOf written twice. Knew it! I toyed with the idea of changing the types in the map from Integer to Long but I think that's a dead end.


I know there is a much, much better Java 8 solution already, but that takes char[][] as input which I think is easier to work with in this case than String.

Michael

Posted 2017-06-29T22:23:03.393

Reputation: 131

1You haven't included the imports (they're required for Java answers). Don't use a Map but an int[] (maybe initialized to new int[99]?). No need for a space after String[] l: String[]l works the same and is shorter. Use println(l.length-i-1) instead of println(l.length-i-1+","). Don't initialize j: just write: ,j;. If you use a int[] as suggested earlier, declare like this: int m[]=new int[99],i=0,j; and remove the declaration from the for-loop. – Olivier Grégoire – 2017-07-01T13:21:07.667

1OlivierGrégoire is indeed right about the required import for Map. As for some golfing of your current code with Map, you can change it to this: import java.util.*;s->{Map m=new TreeMap();String[]a=s.split("\n");int l=a.length-1,j=-1,i=j;for(;++i<l;)for(s=a[i];(j=s.indexOf("_",j+1))>=0;m.put(j,i));for(Object o:m.values())System.out.println(l-(int)o);}. No need for the <Integer,Integer> of the map when you can cast to int; a.length-1 is used twice, so you can use a variable for it; by putting everything inside for-loops you can get rid of all brackets. Oh, and welcome to PPCG! :) – Kevin Cruijssen – 2017-07-01T16:17:29.810

@KevinCruijssen Thanks! Converting the contents of that first for loop to a bodyless for loop was inspiring! Super clever. – Michael – 2017-07-01T17:27:47.843

@Michael You're welcome. :) Oh, and if you haven't seen it yet: Tips for golfing in Java and Tips for golfing in <all languages> might be interesting to read through. Helped me a lot when I first started (and still does sometimes).

– Kevin Cruijssen – 2017-07-01T18:43:48.187

3

MATL, 10 bytes

ooYssqtO>)

Input is a padded character matrix.

Try it online!

beaker

Posted 2017-06-29T22:23:03.393

Reputation: 2 349

2

Mathematica, 48 47 39 bytes

Last/@(Reverse@Most@#~Position~"_")&

Try it online!

Function which expects a rectangular array of characters. Takes Most of the array (all but the last row), Reverses it, then takes the Transpose*, then finds all Positions at which the _ character appears. The relevant heights are the Last elements of each Position.

* is the 3 byte private use character U+F3C7 which represents \[Transpose] in Mathematica. Note that this doesn't work in Mathics, so the TIO link just uses Transpose.

ngenisis

Posted 2017-06-29T22:23:03.393

Reputation: 4 600

2

JavaScript (ES6), 108 104 88 bytes

Saved 16 bytes thanks to @JustinMariner

i=>i.map((s,h)=>{while(t=r.exec(s))m[t.index]=i.length-h-1},m=[],r=/_/g)&&m.filter(e=>e)

Input taken as an array of strings

let input = [
'  _',
' | |           _',
' | |  _   _   | |',
' | | | | | |  | |     _',
'_| |_| |_| |__| |____| |_'
]

let anonymousFunction =
i=>i.map((s,h)=>{while(t=r.exec(s))m[t.index]=i.length-h-1},m=[],r=/_/g)&&m.filter(e=>e)

console.log(anonymousFunction(input))

alexanderbird

Posted 2017-06-29T22:23:03.393

Reputation: 251

88 bytes here

– Justin Mariner – 2017-06-30T00:58:30.543

Thanks @JustinMariner! I'm stoked about the variable initialization as unused parameters given to Array.map, that's a cool trick. – alexanderbird – 2017-06-30T16:58:35.177

Do you really need to assign the RegEx to a variable? You could use it directly in the exec and save a few bytes. – Shaggy – 2017-06-30T21:26:52.660

Actually, it is necessary - the while loop iterates over each match on a line, and without the internal state of the regex in the variable it would match the first occurance each time and loop infinitely. Each iteration it would create a new regex so exec would match the first. It actually crashes the stack exchange snippet editor if you inline the regex. Unless I'm missing something? – alexanderbird – 2017-06-30T21:51:19.843

@shaggy I forgot to tag you in my last comment – alexanderbird – 2017-07-01T04:14:57.573

2

CJam, 15 14 bytes

1 byte saved thanks to @BusinessCat

{W%z'_f#{0>},}

This is a block that takes an array of strings on the stack and outputs an array.

Explanation:

W%    e# Reverse
z     e# Zip
'_f#  e# Get the index of '_' in each element (-1 if not found)
{0>}, e# Filter where positive

Esolanging Fruit

Posted 2017-06-29T22:23:03.393

Reputation: 13 542

You can save 1 byte by reversing the whole array before transposing. – Business Cat – 2017-06-30T13:30:38.287

2

SOGL V0.12, 9 bytes

I{ _WH╥?O

Try it Here!
Takes input as an array of arrays of strings (characters).

Explanation:

I          rotate the array clockwise
 {         for each element
   _       push "_"
    W      get its index in the array (0 if not found, 1 if its the ground, >1 if its what we need)
     H     decrease that
      ╥    palindromize (duplicates the number, if it's <0, then errors and pushes 0, if =0, pushes 0, if >0, then pushes the number palindromized (always truthy))
       ?   if that, then
        T  output in a new line the original decreased index

dzaima

Posted 2017-06-29T22:23:03.393

Reputation: 19 048

1

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)

DLosc

Posted 2017-06-29T22:23:03.393

Reputation: 21 213

1

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

Jim

Posted 2017-06-29T22:23:03.393

Reputation: 1 442

1

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!

rahnema1

Posted 2017-06-29T22:23:03.393

Reputation: 5 435

1

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.

Sean

Posted 2017-06-29T22:23:03.393

Reputation: 4 136

0

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)

Xanderhall

Posted 2017-06-29T22:23:03.393

Reputation: 1 236

-1

Takes in a multiline string. Credit for the setup (header and footer) goes to @GarethPW

Python 2, 29 bytes

lambda s:len(s.split('\n'))-1

Try it online!

This will simply split the array by newline and return length-1.

emtree

Posted 2017-06-29T22:23:03.393

Reputation: 49

This doesn't fulfill the entire challenge. You must return an array or list with all the heights, not just the tallest. – Scott Milner – 2017-06-30T22:00:53.523