[Question]
  [
## Overview
Given a 3 line string, figure out if the structure falls to the left, balances, or falls to the right.
## Input structure
You can imagine the structure as metal rod with stuff on top, all being balanced on top of a vertical rod.
```
1  7 4        a
===============
        |
```
The first line is the items. Each item's weight is calculated as the ascii value of the character minus 32. (Characters under 32 aren't considered and spaces weigh 0). Keep in mind that an item's force on the rod is its weight times the distance to the pivot point.
The second line is the rod. Each length of rod weighs 1 unit by itself. This line is exclusively equals signs (`=`).
The third line is the pivot point. This can be placed anywhere, and is represented by a number of spaces followed by a single pipe (`|`) character.
# Examples
Input:
```
=====
  |
```
Output: Balance
Input:
```
=====
   |
```
Output: Falls left
Input:
```
    %
=====
   |
```
Output: Balance (Because `%` weighs enough to counteract the weight of the left side of the rod)
Input:
```
 a    a
=======
   |
```
Output: Falls right (because the `a` on the right is further away from the pivot point)
Input:
```
1  7 4        A
===============
        |
```
Output: Falls left
Input:
```
1  7 4        a
===============
        |
```
Output: Falls right (lower case letters are heavy!)
Input:
```
            $ ~
===============
             |
```
Output: Balance
# Notes
* Trailing whitespace is permitted, leading whitespace is not.
* Your program may output in whatever format you like, as long as there are 3 distinct outputs for left, balance, and right.
* Your program must accept the format shown as input.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") so the shortest code in bytes wins
  
[Answer]
# JavaScript (ES6), ~~116~~ ~~111~~ ~~108~~ 106 bytes
*-5 bytes by summing via `eval(array.join`+`)` instead of `array.reduce()`.*  
*-3 bytes by defaulting to `1` instead of `32 - 31`, allowing parentheses to be removed.*  
*-2 bytes since pivot point is the length of the last line - 1*
```
(s,[t,r,b]=s.split`
`)=>Math.sign(eval([...r].map((_,i)=>(t.charCodeAt(i)-31||1)*(i-b.length+1)).join`+`))
```
Outputs `-1`, `0`, or `1`, for left, balanced, or right, respectively. Ended up similar to [Chas Brown's python answer](https://codegolf.stackexchange.com/a/129695/69583), so credit goes there.
Can save 4 bytes if the first line is padded to match the length of the rod by using  
`(31-t.charCodeAt(i))*(b.length+~i)`.
## Test Snippet
Includes additional output (`Left`/`Balanced`/`Right`) along with the number.
```
f=
(s,[t,r,b]=s.split`
`)=>Math.sign(eval([...r].map((_,i)=>(t.charCodeAt(i)-31||1)*(i-b.length+1)).join`+`))
```
```
<textarea id=I rows=3 cols=20></textarea><br><button onclick="O.value=I.value?`${x=f(I.value)} (${['Left','Balanced','Right'][x+1]})`:''">Run</button> <input id=O disabled>
```
### Another 106 byte method
```
(s,[t,r,b]=s.split`
`)=>Math.sign(eval(r.replace(/./g,(_,i)=>"+"+(t.charCodeAt(i)-31||1)*(i-b.length+1))))
```
Instead of `join`ing an array on `+`s, we create a string of numbers, each prefixed by `+`. The leading `+` gets ignored.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~112~~ 110 bytes
```
def f(s):w,b,p=s.split('\n');return cmp(sum((ord((w+' '*-~i)[i])-31)*(i-p.find('|'))for i in range(len(b))),0)
```
[Try it online!](https://tio.run/##jY/fTsIwFMav7VOcBM1psSMMUBLNLtTES18AuChbB022bmm7EBPCq891bGYoJp6r9vu@3/lTfrp9oWd1ncgUUmrZ04FveRnZiS0z5SiuNbJnI11lNMR5SW2VU1qYhNLDPQKOg5NiK7VhwTxkY6qCcpIqnVA8ImNpYUCB0mCE3kmaSU23jDE@ZfUInLQOYmGlJSOYQi6FtoBbkQkdS@QQhL32LrLMQiZT18g/VKN2e4eE@PV9R@o7flQ5h@YUclMapR3gWyM2bOf1su0f/m4OK3w9D7fIL7rz4QablU9vOpSQdmjIARFJ5IsAHJsP66wZHzoX1rylGhHurgcW54DwEXGO/A49tKEQYAkL6OqlD0cDqK0h@XiFFP8il9@b93ULpz/JAV5/AQ "Python 2 – Try It Online")
EDIT: Finally managed to eliminate the `enumerate` and `rjust` for a measly 2 bytes... meh!
Takes in a string; outputs -1,0, or 1 for falls left, balances, falls right, respectively.
First pass at 112 bytes was:
```
def f(s):w,b,p=s.split('\n');return cmp(sum((ord(c)-31)*(i-p.find('|'))for i,c in enumerate(w.rjust(len(b))),0)
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 24 bytes
```
ṪO_31
ỴµṪLạÐ€ṪL$×Çṣ0S€IṠ
```
[Try it online!](https://tio.run/##y0rNyan8///hzlX@8caGXA93bzm0Fcjxebhr4eEJj5rWgNgqh6cfbn@4c7FBMFDA8@HOBf///1dAAioKdVy2qIALWV6hBgA "Jelly – Try It Online")
`-1` for falling left, `0` for balancing, `1` for falling right (full program).  
`[-1]` for falling left, `[0]` for balancing, `[1]` for falling right (function).
First line must have trailing spaces, last line must not.
Explanation (we start with bottom line):
First of all, we're working with individual lines, so we need to somehow get them. That's a job for `Ỵ`. Then, we need to treat the `\n`-split version of the input as if it was the original input, so we use `µ` to make a monadic chain applied to the current value.
Now we begin real work, and our first job would be computing the factors of the weights. Essentially this is a range [distance from far left to pivot..0..distance from pivot to far right]. First of all, we have to find the 1-based index of the pivot, which is essentially the length of the last line without trailing spaces. So we pop the last line (pivot line) from our original list with `Ṫ`, since we won't need it anymore, and then we take its length with `L`. We then need to take the length of the rod, for which we do the same thing to the now-last line (rod line) with `ṪL$`. Finally, to get the range, we map **|*x* - *y*|** to [1..rod length], where ***x*** is the pivot index and ***y*** is each element of the list we map upon. We do this using `ạÐ€`, where `ạ` calculates **|*x* - *y*|** and `Ð€` makes a range from 1 up to and including the rod length. Now we'll have the range we want.
After that, we have to multiply each integer, representing a piece of the rod, with its corresponding weight. To calculate the weights, we use `Ç`, going to the top line of our code. We take the remaining line with `Ṫ`, its charcodes with `O`, and then we calculate ***x* - 31** using `_31`, ***x*** being each charcode. We then assign space to weight 1 (0 + rod piece = 1), `!` to weight 2 (1 + 1) etc. We're done with the top line, so now `Ç` would return the list of weights, which we multiply with the corresponding integers representing the rod pieces with `×`.
After that, we split with `ṣ0` on the pivot point, represented by a 0 (since any weight there won't affect the result), resulting in a list of the form [[1st weight, 2nd weight...weight just before pivot], [weight just after pivot, weight after the one before...last weight]]. Those lists represent the sides of the rod, left and right. We now sum each of the lists using `S€` to get the total weights on each side, and use `I` to take the delta, which will be negative if left side is heavier, zero if they're equal-weighted, and positive if right side is heavier. So, to return the final result using this properly to our advantage, we take the sign with `Ṡ`.
[Answer]
## Haskell, ~~212~~ 171 bytes (188 if take input as one string)
```
o!p=map(fst)(zip[p-0,p-1..]o)
x#p=sum(zipWith(\c w->(max(fromEnum c-32)0)*w)x(x!p))+sum(x!p)
x?c=length(takeWhile(==c)x)
```
**171 bytes variant**
```
r a b c=signum(take(b?'=')(a++repeat ' ')#(c?' '))
```
**188 bytes variant**
```
x%y=lines x!!y
r i=signum(take(i%1?'=')(i%0++repeat ' ')#(i%2?' '))
```
Explanation
```
o!p=map(fst)(zip[p-0,p-1..]o)        Creates weights coefs list. 
                                     o - list, p - pivot position
                                     for list "abcdf" and p=3 (pivot under 'd')
                                     outputs [3,2,1,0,-1]
x#p                                  Calculates total balance
                                     x-list of "objects" on lever, p-pivot place
  sum(zipWith                        sum of zipped lists
   (\c w->(max(fromEnum c-32)0)*w)   weight of ascii "object" times
                                     distance from pivot
    x(x!p))                          x-ascii objects, 
                                     (x!p)-distances list(weight coefs)
  +sum(x!p)                          balance of lever ("==") itself
x?c=length(takeWhile(==c)x)          length of list before non c element met
                                     used to find '|' position
                                     and length of "===" lever
                                     before right whitespaces met
r a b c=                             Sums it all up =)
                                     a-ascii objects, b-lever, c-pivot line
   signum(                           1-tips left, 0-balance, -1-tips right
     take(b?'=')(a++repeat ' ')      takes all object on lever 
                                     plus whitespaces up to length of the lever
      #                              calculate the balance
       (c?' ')                       determine place of pivot
```
[Answer]
# [Python 2](https://docs.python.org/2/), 90 bytes
```
def f(s):L=len(s)/3;print cmp(sum((ord(s[i])-31)*(i-s[-L:].find('|'))for i in range(L)),0)
```
Expects input lines to be padded (with spaces) to the correct length. Outputs `-1` for *falls left*, `0` for *balanced*, and `1` for *falls right*.
**[Try it online!](https://tio.run/##dYvBCoJAFEX3fsXbzXuhlhkEhov2/oFJiM7URL4ZZpQI/PepqBYtOpt74HDtfTwbXofQSwUKPRVVeZX8lGW@s07zCN1g0U8DonE9@lo3lOQZLVAnvk6qokmV5h7FLIiUcaBBM7iWTxIronhFoWu9hBLEgUV6MZqxdu3tqNlOI1L8xxuKFL6eFDKALWzgwz4qf4m@ZX7PAw "Python 2 – Try It Online")**
---
## 94 bytes
For +4 bytes we can have a version which, using a `while` loop, requires *stripped* lines rather than *padded* lines:
```
def f(s):
 i=r=0
 while''<s[i]:r+=(ord(s[i])-31)*(i-s[-3::-1].find('='));i+=1
 print cmp(r,0)
```
**[Try it online!](https://tio.run/##dYvLCsIwEEX3@QU3s8uMfdCqIESz8DtqkdI2dETTkFSK4L9HCrpw4Vndw@W45zSMdhNj1xswGEgJYO11IWAe@NbLlTyGimvlE42j73ARyrYlrZGzUGVbpbKyzg3bDqWWRAdOdCnAebYTtHeHPi0otk3oQYM8W5lfR7ZY@Wa@sHWPCSn9s2sSBpeSYgmwhx18OAn9i/g@rzc "Python 2 – Try It Online")**
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 30 bytes
```
O_31×J_¥A+\sṪ€µ÷ḢṪ_2Ṡ
ỴṪLç@ỴḢ$
```
[Test Suite](https://tio.run/##y0rNyan871pRkJpcomCgo2uoY6BjCKKAjP/@8caGh6d7xR9a6qgdU/xw56pHTWsObT28/eGORUBOvNHDnQu4Hu7eAmT7HF7uAGLtWKTyH0gXG0ceblcBqo78/18BBLhsQYBLQaGGC5UPFVBFEUgECSVChGCChgoK5gomClDgCJO0RVIEBugqE/GoVEACKgp1OFVClAMA "Jelly – Try It Online")
Outputs 0 for balanced, 1 for right, and -1 for left.
**How it Works**
```
O_31×J_¥A+\sṪ€µ÷ḢṪ_2Ṡ - helper function. Arguments position of pivot and first line
O                        - char codes of first line
 _31                     - subtract 31 to get weight
    ×                    - elementwise product with:
     J_¥                 - distances from the pivot
        A                - absolute value
         +\              - cumulative sum
           s             - split to get [[...,left weight],...,[..., right + left weight]]
            Ṫ€           - last element of each sublist: [left weight, ... right weight]
              µ÷Ḣ        - get ratio of each element over left weight: ratio n indicates
                              right + left = n × left ===> right = left if n = 2
                 _2      - subtract 2: positive is right>left and negative is right<left
                   Ṡ     - return the sign of this
ỴṪLç@ỴḢ$              - main link. Argument: 3 line string.
   ç@                  - apply helper function with arguments:
Ỵ                        - split by linefeeds
 Ṫ                       - last line
  L                      - length (returns position of pivot)
       $               - and
     Ỵ                   - split by linefeeds
      Ḣ                  - first line              
```
[Answer]
## Ruby, 543 bytes
```
def willittip(s)
leftw=0;
rightw=0;
arr=[];
fields=s.split("\n")
pos=fields[2].index("|")
fields[0].split("").each do |i|
arr << i.ord-32
end
arr[pos+1..-1].each_with_index do |x,y|
rightw=rightw+1
if x>0
if pos>0
rightw=rightw+x*(pos-y).abs
else
rightw=rightw+x
end
end
end
arr[0..pos-1].each_with_index do |x,y|
leftw=leftw+1
if x>0
if pos>0
leftw=leftw+x*(pos-y).abs
else
leftw=leftw+x
end
end
end
if leftw==rightw
return "Equal"
elsif leftw<rightw
return "Right"
elsif leftw>rightw
return "Left"
end
end
```
[Answer]
# [APL (Dyalog)](https://www.dyalog.com/), 43 bytes\*
```
{×(¯31+⎕UCS⊃⍵)+.×(⍳≢⊃⍵)-'|'⍳⍨⊃⌽⍵}⎕TC[2]∘≠⊆⊢
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///P@1R24Tqw9M1Dq03NtR@1Dc11Dn4UVfzo96tmtp6QOFHvZsfdS6Ciuiq16iDBHpXgAR69gLFaoFaQpyjjWIfdcx41LngUVfbo65F///nAU2FGKZgaMClfmi9oVVaYk5OsUJOalqJtYKBVVJiTmJecmqKjgJMpigzPaNEnStNAagPqFvdFgTUdfJ01BUUanCIo0gAuQqqYAncShJBihIRirArM1RQMFcwUYACR2TltmjawAC33kSS9CogARWFOoJ6oQYAAA "APL (Dyalog Unicode) – Try It Online")
`⊆⊢` partition the argument into runs of characters that are
`⎕TC[2]∘≠` different from the **2**nd **T**erminal **C**ontrol character (Linefeed)\*\*
`{`…`}` apply the following anonymous function on the list of strings:
 `⊃⌽⍵` in the first string of the reversed list (i.e. the last)
 `'|'⍳⍨` find the **ɩ**ndex of the pivot point
 `(`…`)-` subtract that from the following list:
  `⊃⍵` the first string
  `≢` its length
  `⍳` all the **ɩ**ndices of that
 `(`…`)+.×` weighted sum with those weights and the following values:
  `⊃⍵` the first string
  `⎕UCS` code points in the **U**niversal **C**haracter **S**et
  `¯31+` add negative thirty-one (32 for the required offset minus one for the rod)
 `×` signum of that
---
\* For 1 byte per char, use `{×(¯31+⎕UCS↑⍵)+.×(⍳≢↑⍵)-'|'⍳⍨↑⌽⍵}⎕TC[3]∘≠⊂⊢` with `⎕ML←3`. [Try it online!](https://tio.run/##SyzI0U2pTMzJT///qG@qr8@jtgnG/9OAZPXh6RqH1hsbagOFQ52DH7VNfNS7VVNbDyj8qHfzo85FUBFd9Rp1kEDvCpBAz16gWC1QS4hztHHso44ZjzoXPOpqetS16P//PKCpEMMUDA241A@tN7RKS8zJKVbISU0rsVYwsEpKzEnMS05N0VGAyRRlpmeUqHOlKQD1AXWr24KAuk6ejrqCQg0OcRQJIFdBFSyBW0kiSFEiQhF2ZYYKCuYKJgpQ4Iis3BZNGxjg1ptIkl4FJKCiUEdQL9QAAA "APL (Dyalog Unicode) – Try It Online")  
\*\* `⎕TC` is deprecated and used here only for golfing purposes. In production code,
 one should use `⎕UCS 10`.
[Answer]
# [Haskell](https://www.haskell.org/) (Lambdabot), 142 bytes
```
l=length
g[a,c,b]=splitAt(l b)$a++(' '<$[1..l c-l a])
k e=sum$zipWith((*).(-31+).ord)e[1..]
f=signum.uncurry(-).(k.drop 1.reverse***k).g.lines
```
[Try it online!](https://tio.run/##fZExT8MwEIV3/4oTCqqdJhYRSCx4qMrIztBmcFsnsXJxItsBgRB/PTiQQsLQN53uvc9nnyvpaoU46KZrrYdta7xtkW@sbV/J1HyUXvJtJe2i8aSdH1CgMqWvSLmTyTE55MJ1qP3GU4QDi@R6TVeweoh2GecIxxRB5ozUoITrm@hdd8/aV5TGjNP0Nlsz3toTU2M6J4VwujR9w3tz7K19o2lI1fxk2w4ybtWLsk7FcVwzXnLURrnhIBEEwA3Bwo9FRmw5FmlGiDZd7x0IArADerU3YtTeAHxcJQFkwUiWxuiEk85OaMD1P3sGghwDcgr8RcIVzpEM4B7uYNLmNyrmyLeWk5ecvMzN5sFMEXxe4M7w9J6ckEZqE1bXWW18gCUi0PNPCMF4oa3zUDD4WSwZvgA "Haskell – Try It Online")
### Ungolfed version:
```
-- for readability, allows reading top-down/left-right
(.>) = flip (.)
ungolfed =
     lines                                 -- separate out lines into..
  .> (\[a,b,c] ->                          -- a,b,c (first,second,third)
                                           -- ' ' pad the first line & split on pivot
       splitAt (length c) (a ++ replicate (length b - length a) ' ')
     )
  .> (weight.drop 1.reverse *** weight)    -- reverse left half, drop element above pivot & get weight for both
  .> uncurry (-)                           -- subtract right from left
  .> signum                                -- get sign
-- get ord of the character subtract 31 ('=' char from bar),
-- then multiply with scales ([1..]) and sum it all up
weight es = sum $ zipWith (ord .> subtract 31 .> (*)) es [1..]
```
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 106 ~~107~~ ~~121~~ ~~123~~ ~~124~~ ~~129~~ ~~131~~ bytes
```
c,b,l,i;f(char*a){l=strlen(a)/3;for(i=b=c=0;32/a[l*2+c];++c);for(;i<l-1;b+=(a[i]-31)*(i++-c));a=b>0?2:!b;}
```
Return 0 for falling left, 1 for balance and 2 for falling right.
Require all three lines to have same length and finish with `\n` to determine the length of string.
[Try it online!](https://tio.run/##pY5BTsMwEEX3OcUQUcnjxGriICFhGcQ5mi7GbgOWjEEmrNpy9eBEUZVVKeKvZkbvP40VL9YOgy1N6UunOmZfKXLCg9efffT7wAjXjereI7O6UowKzyVu7FbrRqqisKiMFsJz5kWNayks9xPtEk0btxV1lTCHptBs2huJnDmRiqTNY/UkH26MOg0u9PBGLjDMDhmkfMR06li@2rUhL9MwHqENekwbAI7jliOq6/DE/4av/oDTeKa5cK5cfqkGuIc7mPN8LuulZMoR5vevldH/ZLDILXxfkM3GhSzu@68YoFLZafgB "C (gcc) – Try It Online")
[Answer]
# Mathematica, 91 ~~92~~ bytes
```
Sign[(v=(g=ToCharacterCode)@#&@@(d=#~StringSplit~"
")-31).(Range@(l=Length)@v-l@g@Last@d)]&
```
The first line should have the same length with the rod. The third line should contain no trailing spaces.
Return -1, 0, 1 for falling left, balance and falling right.
[Answer]
# [C# (.NET Core)](https://www.microsoft.com/net/core/platform), ~~127~~ ~~95~~ 90 + 18 = 108 bytes
For this function the first line must be right padded with spaces to be the same length as the rod and the third line must not have trialing spaces. This conditions are allowed (see comments of the question).
```
s=>s.Split('\n')[0].Select((c,i)=>(c-31)*(i-s.Split('\n')[2].Length+1)).Sum().CompareTo(0)
```
[Try it online!](https://tio.run/##rY/BSsNAEIbv@xRDUbqjzdKo4KFuQAqeKggRPJgelnVbF5LZmt0IovXVY5LWUj0IDf7Hmf/7mNE@0q40deUtLSF988EUYmbpZcKYzpX3cMfeGTTxQQWr4dXZJ7hVljh2482yzRa@qUhf@VA2vhFYCgksQELtZeJFuspt4MOMhvg4novU5EYHzvXIoky4js5jPOE2@lk8m4uZoWV4Po0RRVoVHMXUFStVmnvHx1g3p/66YerIu9yIh9IG03xj@IIPukJGsk1GAB8DxEkv8kD0uCeq2obawgfjMcAlXHw3r3caua/r0tep/sUJezmCzz@cGzHszGu2rr8A "C# (.NET Core) – Try It Online")
Outputs:
-1 for tip left  
 0 for balance  
 1 for tip right
[Answer]
# Python 3, 217 bytes
### Also works in Python 2.7
```
def f(s):i,b,p=s.split('\n');c=p.find('|');l=sum((ord(e)-32)*(c-i.find(e))for e in i[:c])+sum(x for x in range(1,c+1));r=sum((ord(e)-32)*i[c:].find(e)for e in i[c:])+sum(x for x in range(len(b[c:])));return(l>r)-(r>l)
```
***Returns 1 for left-side, -1 for right-side, or zero if balanced.***
## Readable version:
```
def f(s):
    i,b,p = s.split('\n')
    c = p.find('|')
    l = sum((ord(e)-32)*(c-i.find(e))for e in i[:c])+sum(x for x in range(1, c+1))
    r = sum((ord(e)-32)*i[c:].find(e)for e in i[c:])+sum(x for x in range(len(b[c:])))
    return(l>r)-(r>l)
```
[Answer]
# PHP, 105 bytes
```
for([$a,$b,$c]=explode("
",$argn);$b[$i];)$w+=(strpos($c,"|")-$i++)*8*(max(1,ord($a[$i])-31));echo$w<=>0;
```
prints `-1`/`0`/`1` for left/balance/right. Run as pipe with `-nR` or [try it online](http://sandbox.onlinephpfunctions.com/code/48a38d554247a0501168feec482beadb8c9fc21c).
**breakdown**
```
for([$a,$b,$c]=explode("\n",$argn); # import input
    $b[$i];)                        # loop through bar
    $f+=                                # add to force:
        ($i-strpos($c,"|"))             # distance (<0 if left, >0 if right of pivot)
        *8                              # *8
        *(max(1,ord($a[$i++])-31));     # *weight
echo$f<=>0;                         # print -1 if $f<0, 1 if $f>0, 0 if $f==0
```
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 31 bytes
```
Ａ⁰ξＦＬθＡ⁺ξ×⁻ι⌕ζ|⁻℅§θι³¹ξＩ⁻›ξ⁰‹ξ⁰
```
[Try it online!](https://tio.run/##LY3BCsIwEETv/YqlIGwghYrH4qEIilCxB38gtLEuxJRmoxTpv8eE9l12dmeZ6V7KdaMyIdTMNFgsJcyiyp6jA2y0HfwLJyFgc1vzYZwlPOitGW9k40oSzmR7/EnIl1wICev97nqyymDtr7bXM04SKLmHvUgjtbSOrMeTYr9lXZxWXrtUUcafRjOvOlKFAJFddkxkUS6h@IaCzR8 "Charcoal – Try It Online") Link is to verbose version of code. Outputs 0 for balance or -1 or 1 for falling left or right. Edit: Changes in Charcoal now mean that `≔ΣＥθ×⁻κ⌕ζ|⁻℅ι³¹ξＩ⁻›ξ⁰‹ξ⁰` works for 24 bytes: [Try it online!](https://tio.run/##LYtNCsIwEEb3OcVQECYQQXFZXIhQNxYFvcDQBh1Mo2ZSKdK7x5T6Vo/vp7lTaJ7kUtqJ8M3jpe@wphe@DVy5s4I1@17wYaBi3@LXQDEWWhuY81No2ZNDzslmradi0KU6B/YR9yTx/z8ES9EGHAys8uZoRWbPlClBZqG2EyrrmJYf9wM "Charcoal – Try It Online") Link is to verbose version of code. Note: Both answers require padded input, but can be adapted to accept unpadded input at a cost of 3 bytes: `≔⁰ξＦＬη≔⁺ξ×⁻ι⌕ζ|⁻℅§◨θＬηι³¹ξＩ⁻›ξ⁰‹ξ⁰` [Try it online!](https://tio.run/##RY1NCsIwEIX3PcVQECYQoeKyuCiCIigW8QKhic1ATDGJEqR3jw0t@BZv/njzdVq4bhAmpcZ76i1WHCKri8fgAM/K9kGjZgyWa2veHiOHOz2VxwvZaSQOB7ISvxzKsWSMw7y/OklWGGzCyUoVsRXyRr0O@OLw/8yBsm03LJeMbh3ZgHvhwwI4OiWCcplbsZz1fu4n1Smtil1WAWNaf8wP "Charcoal – Try It Online") `≔ΣＥ◨θＬη×⁻κ⌕ζ|⁻℅ι³¹ξＩ⁻›ξ⁰‹ξ⁰` [Try it online!](https://tio.run/##LY3BCsIwEETv/YpQEDYQQfFYPIigF4tF/YGlDc3SNGo2lSL999hQ5zS8xzC1QV8/0cZ4YKbWwX3oocQXVNjcqDUB3kpctGuDASOlEg/qNUNJbmDolDiRa@CrRD7lyS786htyaIFmstvKJEZZZJUnF@CIHP77s9cYtIdRiY1MN8xLn1PEuMr2KZmY4vpjfw "Charcoal – Try It Online") Links are to verbose version of code.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 18 bytes
```
ỴµḢO_31×Ẉạ€/$ṣ0§IṠ
```
[Try it online!](https://tio.run/##y0rNyan8///h7i2Htj7cscg/3tjw8PSHuzoe7lr4qGmNvsrDnYsNDi33fLhzwf/D7UcnPdw5QzPy/38lJSUuWxDgUlCoAXJ0FJBFEEJAtoIqNvFEkEwiRAZNzlBBwVzBRAEKHGFqbJHUggEODYmENSggARWFOpwa4LoA "Jelly – Try It Online")
This started as a golf of [Erik's answer](https://codegolf.stackexchange.com/a/129798/66833) (so be sure to go upvote it), but it developed to be different enough, and Erik is no longer active on the site, that I thought posting a separate answer would be fine.
Outputs `[0]` for balanced, `[1]` for tipping right and `[-1]` for tipping left
## How it works
```
ỴµḢO_31×Ẉạ€/$ṣ0§IṠ - Main link. Takes a string S on the left
Ỵ                  - Split S into a list of lines [I, R, P]
 µ                 - Use this list as the arguments
  Ḣ                - Pop and yield I
   O               - Convert to ordinals
    _31            - Subtract 31, mapping space to 1, ! to 2 etc.
            $      - Previous 2 links as a monad f([R, P]):
        Ẉ          -   Get the length of each
           /       -   Reduce by:
          €        -     Convert len(R) to a range and over each element:
         ạ         -       Take the absolute difference with len(P)
       ×           - Multiply these lists together
             ṣ0    - Split at 0, the pivot point
               §   - Sum of each side
                I  - Difference between the sides
                 Ṡ - Sign
```
]