## Challenge

You just adjusted your new chair! It fits you perfectly. However, the wheel is squeaky and you know the repair people will change the adjustment. Problem is, you don't have a ruler, so you'll have to write a program to measure it for you. The repair people can only wait for so long. So your code needs to be as short as possible.

## Examples

O
|
|
| _
| |
|_|_
|
|
O

5,3,2,2,1


O
|  _
|  |
|__|__
|
|
__|__
OOOOO

3,5,2,3,5


O
|      _
|______|______
______|______
OOOOOOOOOOOOO

2,13,1,1,13


## Chair parts

The chair has various components:

O  <- Headrest
|
|  <- Backrest
|  _  <- Armrest
|  |
|__|__ <- Seat
|
|   <- Leg
_|_
OOO  <- Wheels


## Detailed Chair Descriptions

The parts of the chair are:

O
|


Backrest: The number of | is the Backrest Height

O
|
|


Seat: The number of _ is the Seat Width, there is a | in the middle for the armrest.

__|__


Armrest: The number of | is the Armrest Height. This will be inserted in the middle of the seat.

_
|
|


Leg: The number of | is the Leg Height

|
|


Wheels: The wheels are centred below the legs. If they are more than one, all but the centre wheel will have _ in the line above them.

_ _
OOO


## Output

Given a chair, you will be outputting various variables.

The output should be in the following order:

1. Backrest Height
2. Seat Width always odd
3. Armrest Height Always less than backrest height
4. Leg Height
5. Wheel count Always less than or equal to seat width and Always odd

The output may have a trailing newline, or be in an array / list form if it is a function.

/* Configuration */

var QUESTION_ID = 67522; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 43394; // This should be the user ID of the challenge author.

/* App */

comment_page;

return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

}

jQuery.ajax({
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function(data) {
data.items.forEach(function(a) {
});
comment_page = 1;
}
});
}

jQuery.ajax({
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function(data) {
data.items.forEach(function(c) {
if (c.owner.user_id === OVERRIDE_USER)
});
else process();
}
});
}

var SCORE_REG = /<h\d>\s*([^\n,]*[^\s,]),.*?(\d+(?:[.]\d+)?)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

function getAuthorName(a) {
return a.owner.display_name;
}

function process() {
var valid = [];

var body = a.body;
if (OVERRIDE_REG.test(c.body))
body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
});

var match = body.match(SCORE_REG);
if (match)
valid.push({
user: getAuthorName(a),
size: +match,
language: match,
});

});

valid.sort(function(a, b) {
var aB = a.size,
bB = b.size;
return aB - bB
});

var languages = {};
var place = 1;
var lastSize = null;
var lastPlace = 1;
valid.forEach(function(a) {
if (a.size != lastSize)
lastPlace = place;
lastSize = a.size;
++place;

.replace("{{NAME}}", a.user)
.replace("{{LANGUAGE}}", a.language)
.replace("{{SIZE}}", a.size)

var lang = a.language;
if (/<a/.test(lang)) lang = jQuery(lang).text();

languages[lang] = languages[lang] || {
lang: a.language,
user: a.user,
size: a.size,
};
});

var langs = [];
for (var lang in languages)
if (languages.hasOwnProperty(lang))
langs.push(languages[lang]);

langs.sort(function(a, b) {
if (a.lang > b.lang) return 1;
if (a.lang < b.lang) return -1;
return 0;
});

for (var i = 0; i < langs.length; ++i) {
var language = jQuery("#language-template").html();
var lang = langs[i];
language = language.replace("{{LANGUAGE}}", lang.lang)
.replace("{{NAME}}", lang.user)
.replace("{{SIZE}}", lang.size)
language = jQuery(language);
jQuery("#languages").append(language);
}

}
body {
text-align: left !important
}
width: 290px;
float: left;
}
#language-list {
width: 290px;
float: left;
}
font-weight: bold;
}
table td {
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tr>
<td></td>
<td>Author</td>
<td>Language</td>
<td>Size</td>
</tr>

</tbody>
</table>
</div>
<div id="language-list">
<h2>Winners by Language</h2>
<table class="language-list">
<tr>
<td>Language</td>
<td>User</td>
<td>Score</td>
</tr>
<tbody id="languages">

</tbody>
</table>
</div>
<table style="display: none">
<tr>
<td>{{PLACE}}</td>
<td>{{NAME}}</td>
<td>{{LANGUAGE}}</td>
<td>{{SIZE}}</td>
</td>
</tr>
</tbody>
</table>
<table style="display: none">
<tbody id="language-template">
<tr>
<td>{{LANGUAGE}}</td>
<td>{{NAME}}</td>
<td>{{SIZE}}</td>
</td>
</tr>
</tbody>
</table>

# Language Name, N bytes


where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

# Ruby, <s>104</s> <s>101</s> 96 bytes


If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

# Perl, 43 + 2 (-p flag) = 45 bytes


You can also make the language name a link which will then show up in the leaderboard snippet:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

• Is the armrest measured? – J Atkin Dec 23 '15 at 18:38

## Lua, 187 Bytes

I think I might be able to golf it some more, but I think this is good at the moment. Also, if the output needs to be comma-separated I can fix that, but this still meets the requirements methinks.

Also, input is fed in one line at a time. After the wheels are input, press enter with an an empty line to finalize input.

c={}i=1t=""while c[i-1]~=""do c[i]=io.read():gsub("%s+","")t=t..c[i]a=(not a and c[i]:find("_")and i or a)s=(not s and c[i]:find("_|_")and i or s)i=i+1 end print(s-1,c[s]:len()-1,s-a,#c-s-2,c[#c-1]:len())


Ungolfed

c={}
i=1
while c[i-1]~=""do
a=(not a and c[i]:find"_"and i or a)   --armrest position
s=(not s and c[i]:find"_|_"and i or s) --seat position
i=i+1
end
print(s-1, c[s]:len()-1, s-a, #c-s-2, c[#c-1]:len())


(Positions are measured top-to-bottom, so the top 'O' is position 1, and the wheels are the largest position.

• Backrest height is the position of the seat minus one, compensating for the 'O' at the top.
• Seat size is the length of th string at the seat's position minus one, compensating for the backrest.
• Armrest height is the position of the seat minus the position of the armrest.
• Leg height is the height of the chair (#c) minus the position of the seat minus 2, to compensate for the wheels and seat.
• Wheel count is the length of the final string.

# Groovy, 161 bytes!!!

Yay!! Not in last!!

f={s->a=s.split(/\n/)
b=a.findIndexOf{it.contains('|_')}
d=b-a.findIndexOf{it.contains('_')}
print"$b,${a[b].count('_')+1},$d,${a.size()-b-2},${s.count('O')-1}"}  Ungolfed: f={String s -> split = s.split(/\n/) bottomOfChairBack = split.findIndexOf {it.contains('|_')} armHeight = bottomOfChairBack-split.findIndexOf {it.contains('_')} width = split[bottomOfChairBack].count('_')+1 height = split.size() - bottomOfChairBack - 2 wheelCount = s.count('O')-1 return [bottomOfChairBack, width, armHeight, height, wheelCount] }  Tests of ungolfed program: assert f('''O | | | _ | | |_|_ | | O''') == [5, 3, 2, 2, 1] assert f('''O | _ | | |__|__ | | __|__ OOOOO''') == [3,5,2,3,5] assert f('''O | _ | | |__|__ | | __|__ OOOOO''') == [3,5,2,3,5] assert f('''O | _ |______|______ ______|______ OOOOOOOOOOOOO''') == [2,13,1,1,13]  # Pyth, 575453 50 bytes Probably can be golfed further. -3 bytes thanks to issacg for the single character string trick. =kjb.z =H/k+b\| -/k\_=G-/k\O2 --/k\|H=Nt/k+bd N hG  Explanation: =kjb.z =k Assign k z Input jb. Join list by newlines =H/k+b\| =H Assign H / +b\| Count occurrences of "\n|" k In input (Implicit: print backrest height) -/k\_=G-/k\O2 =G Assign G -/k\O2 The number of wheels minus 1 -/k\_ Count the number of "_" (Implicit: print seat width) --/k\|H=Nt/k+bd =N Assign N /k+bd Count the number of lines starting with " " t Subtract 1 (N is now the leg height) /k\| Count the number of "|" - H Subtract the "|" for the backrest - Subtract leg height (Implicit: print armrest height) N Print leg height hG Print the number of wheels  • To make a one-character string, use \. So "_" = \_ – isaacg Dec 24 '15 at 9:36 • Ouch, no way am I going to beat this ;) – J Atkin Dec 24 '15 at 15:23 # Perl, 93+2=9590+1=91 83+1= 84 bytes Apparently the output doesn't need comma-separating Invoke with perl -n chair.pl chairInput (1B penalty for the flag). END{print$b,2+$u-$o,$a,$.-$b-2,$o-1}$u+=s/_//g;$o+=s/O//g;s/^\|//&&$b++&&/\|/&&$a++


Ungolfed:

END{         # Put the END block first to save 1 ;
print
$b, 2+$u-$o,$a,
$.-$b-2, # $. is the number of lines total$o-1
}
$u+=s/_//g; # count _s incrementally$o+=s/O//g; # count Os incrementally
s/^\|// && $b++ # it's backrest if it starts with | && /\|/ &&$a++ # and it's armrest if it has another one


## Previous version:

Invoke with perl -0n chair.pl < chairInput

s/^\|//&&$b++?/\|/&&$a++:$h++for split" ",$_;$,=",";print$b,2+s/_//g-($o=s/O//g),$a,$h-3,$o-1


Explanation:

s/^\|// && $back++ # the backrest is all lines starting with | ? /\|/ &&$arm++ # the armrest is all of those lines with another |
: $height++ # otherwise it counts for the seat height for split" ",$_;       # literal newline for 1 byte saved
$,=","; # output separator print$back,
2+s/_//g-($o_count=s/O//g), # you can find the seat size # from the different between the number # of Os and _s$arm,
$height-3,$o_count-1


# Python 3, 160 158 bytes

This code works but only on the following conditions: 1) armrest height > 0 otherwise the _ count breaks and 2) seat width > 1 otherwise the armrest blocks the width-one seat and the _ count breaks.

def f(s):
a=s.split("\n");x=[];y=[];l=len(a)
for i in range(l):
m=a[i].count("_")
if m:x+=i,;y+=m,
return x,y+1,x-x,l-x-2,s.count("O")-1