How much water is left?

Pyth - 17 46 45 52 * .85 - 35 = 9.2 bytes

Filters the input (With the new # filter meta-op!) for a line with ~ in it, then indexes that to the input, and then divides that by the length of the input. If there are none with ~, it errors, and triggers the except clause of .x and prints the string.

.x+*100-1cxK.zh@#\~KlK\%." u(C$éáPãbÉãç*îÂe[W

Try it online here.


Python 3, 37 bytes

lambda x:1-(x+'|~').find('|~')/len(x)

No bonuses. Takes an input string with newlines, including a trailing newline.

Let's look at why the formula works. The fraction of water is the complement of the fraction of air, which we'll derive.

frac_water = 1 - frac_air

Numbering the rows 0, 1, 2, ..., we have

frac_air = water_row_index / num_rows 

The same is true if both are multiplied by the width of each row, counting newlines, which simplify to expressions in the number of characters.

frac_air = (width * water_row_index) / (width * num_rows)
         = water_row_start_char_index / num_chars

The water row start is found by searching the input string x for |~, and the number of chars is just the length.

frac_air = x.find('|~') / len(x)

Finally, in order to make no-water inputs work, we append a fictional water row start |~ to the end before searching, which makes it look like the water level is 0.

The bonuses seemed not worth it. The best I got on the string one is 73-35=38:

lambda x:['This drought goat out of hand',1-x.find('|~')/len(x)]['~'in x]

CJam, 19 17 16 58 * 0.85 - 35 = 14.3 bytes

q'|-_'~#_)\@,d/1\m100*s'%+"This drought goat out of hand"?

Try it online

This version gets both bonuses. The input must have a trailing newline for this solution to work.

Thanks to @Martin Büttner for saving 2 bytes.

Explanation:

q       Get input.
'|-     Remove left/right wall, so that position of first ~ in remaining string
        corresponds to the water level.
_       Make a copy.
'~#     Find ~ character.
_)      Make copy of find result, and increment it. This is 0 if the ~
        was not found, and will be used for the bonus condition.
\       Swap original find result to top.
@,      Rotate copy of remaining input to top, and get its length.
d       Convert to double to get float division.
/       Divide the two values. Since the position of the ~ was indexed from
        the top, this is 1 minus the desired result.
1\m     Subtract value from 1, to get the actual result.
100*    Multiply by 100 to get percent.
s       Convert to string.
'%+     Append % sign.
"This drought goat out of hand"
        Push bonus zero string.
?       Ternary operator to pick calculated result or zero string.

Tags:

Code Golf