13
\$\begingroup\$

You have a swimming pool that is filled to the brim with water. You need to empty it, but you can't think of an efficient method. So you decide to use your red solo cup. You will repeatedly fill the cup all the way and dump it outside the pool.

Challenge

How long will it take to empty the pool?

Input

[shape of pool] [dimensions] [shape of cup] [dimensions] [speed]

  • shape of pool will be one of these strings: circle, triangle, or rectangle. Note that these actually refer to the 3-dimensional shapes: cylinder, triangular prism, and rectangular prism.
  • dimensions will be different depending on the shape.
    • circle: [radius] [height]. Volume = π r2 h
    • triangle: [base] [height] [length]. Volume = 1/2(bh) * length
    • rectangle: [width] [length] [height] Volume = lwh
  • shape of cup and dimensions work the same way. The cup can also be either a circle, triangle, or rectangle.
  • speed is the amount of time it takes to empty one cup full of water in seconds.

Output

The number of seconds it takes to empty the swimming pool. This can be rounded to the nearest second.

Notes

  • There will be no units in the input. All distance units are assumed to be the same (a shape won't have a height in inches and a width in feet).
  • Use 3.14 for pi.
  • Input will be made up of strings and floating-point numbers.
  • It will never rain. No water will ever be added.
  • You have a very steady hand. You will fill the cup exactly to the brim every time, and you will never spill any.
  • Once you get near the end, it will get hard to scoop up a full cup of water. You do not need to worry about this. You're very strong, so you can tilt the pool onto its side (without using up any more time).
  • Anytime you make a calculation, it's okay to round to the nearest hundredth. Your final answer will not need to be exact.

Test Cases

Input: triangle 10 12.25 3 circle 5 2.2 5
Output: 10
Even though there is less than 172.7 left on the last scoop, it still takes the whole five seconds to empty it.

Input: triangle 5 87.3 20001 rectangle 5.14 2 105.623 0.2
Output: 804.2

  • You should round to the nearest hundredth after each calculation.
  • The final calculation is rounded up from 804.05567 to 804.2. This is because that last little bit of water must be emptied.

Rules

  • You can write a full program or function.
  • Input should be taken from stdin or function parameters. Output should be printed through stdout or returned.
  • The input format can be rearranged, as long as you specify that in the submission. You can also shorten the strings "circle", "triangle", and "rectangle."
  • Libraries and built-in functions that involve volume or area are not allowed.

Scoring

This is . Submission with least number of bytes wins.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ You'd have problems at the end, once the level of water in the bottom of the pool was lower than the height of the cup. At that point it would get harder and harder to get a full cup. Should this issue be ignored? \$\endgroup\$ Commented Aug 11, 2015 at 15:12
  • 8
    \$\begingroup\$ Yes @DarrelHoffman, let's pretend you're really strong and can tilt the pool onto it's side (without using up any more time). \$\endgroup\$
    – Nick B.
    Commented Aug 11, 2015 at 15:17

11 Answers 11

6
\$\begingroup\$

JavaScript ES6, 100 78 82 81 74 bytes

Thanks to @UndefinedFunction for helping golf off 4 bytes

(a,z,d,f=([a,g,k,p])=>g*k*(a[6]?p/-~!a[8]:3.14*g))=>Math.ceil(f(a)/f(z))*d

Usage:

t(["triangle",10,12.25,3],["circle",5,2.2],5);
\$\endgroup\$
12
  • \$\begingroup\$ Rather than .5*v, couldn't you do v/2? \$\endgroup\$
    – Alex A.
    Commented Aug 11, 2015 at 4:57
  • \$\begingroup\$ @AlexA. oh yeah... completely forgot about that \$\endgroup\$
    – Downgoat
    Commented Aug 11, 2015 at 4:59
  • \$\begingroup\$ @vihan What happens if the pool volume is an exact multiple of the cup volume, like in t(["triangle", [10, 12.25, 3]], ["triangle", [10, 12.25, 3]], 5)? I get 10 but shouldn't the answer be 5? EDIT: just beaten by edc65, same problem. \$\endgroup\$
    – jrich
    Commented Aug 11, 2015 at 16:53
  • \$\begingroup\$ Have a look at my solution, I can't post it because it's way too similar to yours... f=(p,c,s,v=([s,a,b,c])=>s<'r'?a*a*b*3.14:a*b*c/(s<'t'?1:2))=>Math.ceil(v(p)/v(c))*s \$\endgroup\$
    – edc65
    Commented Aug 11, 2015 at 16:56
  • \$\begingroup\$ @edc65 I think this should work now. -~ had issues with the decimal numbers and would result in rounding up an extra step. I've had to add a<'t'?1:2 because (1+(a>'t')) doesn't work for some reason. \$\endgroup\$
    – Downgoat
    Commented Aug 11, 2015 at 17:24
5
\$\begingroup\$

CJam, 46 bytes

{rc:Xr~r~@'c={\_**3.14*}{r~**X't=)/}?}2*/m]r~*

Explanation:

{                                    }2*       e# Repeat two times:
 rc:X                                          e#   Read a token, take first char, assign to X
     r~r~                                      e#   Read and eval two tokens
         @'c={         }            ?          e#   If the char was 'c':
              \_*                              e#     Square the first token (radius)
                 *                             e#     Multiply by the second one (height)
                  3.14*                        e#     Multiply by 3.14
                        {          }           e#   Else:
                         r~                    e#     Read and eval a token
                           **                  e#     Multiply the three together
                             X't=)/            e#     Divide by 2 if X == 't'
                                               e# Now the two volumes are on the stack
                                        /m]    e# ceil(pool_volume / cup_volume)
                                           r~* e# Read and evaluate token (time) and multiply

Try it online.

\$\endgroup\$
0
3
\$\begingroup\$

Python 3, 340 304 bytes

def l(Y,Z):r=Z[1]*3.14*(Z[0]**2)if Y[0]in'c'else Z[0]*Z[1]*Z[2];return r/2 if Y[0]is't'else r
def q(i):import re,math;M,L,F,C=map,list,float,math.ceil;p,d,c,g,s=re.match("(\w)\s([\d .]+)\s(\w)\s([\d .]+)\s([\d.]+)",i).groups();k=lambda j:L(M(F,j.split(' ')));d,g=k(d),k(g);return C(C(l(p,d)/l(c,g))*F(s))

Usage:

q(i)

Where i is the string of information.

Examples:

  • q("t 10 12.25 3 c 5 2.2 5")
  • q("t 5 87.3 20001 r 5.14 2 105.623 0.2")

Note: The names of the shapes have been shortened to their first letters, respectively.

\$\endgroup\$
4
  • \$\begingroup\$ You can save one byte by replacing "0.5" with ".5". \$\endgroup\$
    – Potatomato
    Commented Aug 11, 2015 at 9:17
  • \$\begingroup\$ The parentheses in "(Z[0]**2)" are unnecessary. Replacing "(Z[0]**2)" with "Z[0]**2" should save 2 characters without affecting the function's results. Additionally, the space in "/2 if" (from "return r/2 if Y[0] ...) can be removed, saving one character. \$\endgroup\$
    – Potatomato
    Commented Aug 11, 2015 at 11:36
  • \$\begingroup\$ I've tried this and it affected the results. @Potatomato \$\endgroup\$
    – Zach Gates
    Commented Aug 11, 2015 at 11:37
  • \$\begingroup\$ The changes I have proposed seem to work fine (repl.it/BBNh/1 shows that the same values are returned). \$\endgroup\$
    – Potatomato
    Commented Aug 11, 2015 at 11:44
3
\$\begingroup\$

Javascript (ES6), 91

Taking input as strings for the shapes, arrays of numbers for the dimensions, and a single number for the speed:

(a,b,c,d,e)=>(1+(v=(y,x)=>x[0]*x[1]*(y[6]?x[2]/(y[8]?1:2):x[0]*3.14))(a,b)/v(c,d)-1e-9|0)*e

This defines an anonymous function, so to use add g= before it. Then, it can be called like alert(g("triangle", [10, 12.25, 3], "circle", [5, 2.2], 5))

Explanation:

(a,b,c,d,e)=>    //define function
                   //a = pool shape, b = pool dimensions
                   //c = cup shape, d = cup dimensions
                   //e = speed

( 1+     //part of the rounding up below

  (v=(y,x)=>       //define volume function

      x[0] * x[1] *     //multiply first 2 values of dimension by:

          (y[6] ?
               x[2] /     //if rectangle or triangle, the 3rd dimension
                   (y[8] ? 1 : 2)     //but if triangle divide by 2
                :
               x[0] * 3.14     //or if circle the radius * pi
          )    //(implicit return)

  )(a,b) / v(c,d)     //call the volume function for the pool/cup, and divide

         -1e-9 |0    //but round up the result

) * e     //and multiply by e
//(implicit return)



My original solution took a single string, and was 111 bytes long:

s=>(1+(v=x=>s[i++]*s[i++]*(s[x][6]?s[i++]/(s[x][8]?1:2):s[i-2]*3.14))((i=1)-1,s=s.split` `)/v(i++)-1e-9|0)*s[i]

This also defines an anonymous function, so to use add f= before it. Then, it can be called like alert(f("triangle 5 87.3 20001 rectangle 5.14 2 105.623 0.2"))

\$\endgroup\$
3
\$\begingroup\$

K5 (oK), 123 bytes

v:{((({y*3.14*x*x};{z*(x*y)%2};{x*y*z})@"ctr"?s)..:'t#1_x;(1+t:2+~"c"=s:**x)_x)};f:{{(.**|r)*_(~w=_w)+w:x%*r:v y}.v[" "\x]}
\$\endgroup\$
3
\$\begingroup\$

Julia, 122 116 95 89 79 bytes

f(p,P,c,C,s)=(V(a,x)=prod(x)*(a<'d'?3.14x[1]:a>'s'?.5:1);ceil(V(p,P)/V(c,C))*s)

This assumes that only the first letter of the shape names will be given. Otherwise the solution is 6 bytes longer.

Ungolfed + explanation:

function f(p::Char, P::Array, c::Char, C::Array, s)
    # p - Pool shape (first character only)
    # P - Pool dimensions
    # c - Cup shape (first character only)
    # C - Cup dimensions
    # s - Speed

    # Define a function to compute volume
    function V(a::Char, x::Array)
        prod(x) * (a < 'd' ? 3.14x[1] : a > 's' ? 0.5 : 1)
    end

    # Return the ceiling of the number of cups in the pool
    # times the number of seconds per cup
    ceil(V(p, P) / V(c, C)) * s
end

Saved 21 bytes thanks to edc65 and 10 thanks to UndefinedFunction!

\$\endgroup\$
5
  • \$\begingroup\$ Don't you have a ceil in Julia, to use instead of floor, cutting all the check about integer result? \$\endgroup\$
    – edc65
    Commented Aug 11, 2015 at 6:06
  • \$\begingroup\$ @edc65 How did I not see that?! Thanks, that saved 21 bytes! \$\endgroup\$
    – Alex A.
    Commented Aug 11, 2015 at 13:33
  • \$\begingroup\$ Would it be possible to replace a>'s'?prod(x)/2:prod(x) with prod(x)/(a>'s'?2:1) ? (possibly even without the parentheses, I don't have a juilia ide on hand, and haven't been able to test this) \$\endgroup\$
    – jrich
    Commented Aug 11, 2015 at 15:37
  • \$\begingroup\$ Or potentially even replacing a<'d'?3.14x[1]^2*x[2]:a>'s'?prod(x)/2:prod(x) with prod(x)*(a<'d'?3.14x[1]:a>'s'?.5:1) ? (Again, untested) \$\endgroup\$
    – jrich
    Commented Aug 11, 2015 at 15:49
  • \$\begingroup\$ @UndefinedFunction Yep, that works! Thanks, that shaved off 10 bytes! \$\endgroup\$
    – Alex A.
    Commented Aug 11, 2015 at 21:08
3
\$\begingroup\$

F#, 217 186 184 160 bytes

Damn indentation requirements!

let e(p,P,c,C,s)=
 let V(s:string)d=
  match(s.[0],d)with
  |('c',[x;y])->3.14*x*x*y
  |('t',[x;y;z])->((x*y)/2.)*z
  |('r',[x;y;z])->x*y*z
 ceil(V p P/V c C)*s

Usage:

e("triangle",[5.;87.3;20001.],"rectangle",[5.14;2.;105.623],0.2);;

Update

Thanks to Alex for remarking on single space indentation, which F# seems to support

Managed to knock a load more off by changing from array to list types in the match statement

\$\endgroup\$
5
  • 1
    \$\begingroup\$ If you can use a single space or tab for indentation, you can get this down to 186 bytes. But what you have now is actually 211, not 217. \$\endgroup\$
    – Alex A.
    Commented Aug 11, 2015 at 13:46
  • \$\begingroup\$ @AlexA.A single space works, I'll update - thanks! Why is/was it 211, not 217, when I put it in notepad, it's showing as 217 chars, and saving it to a file shows 217 too (Sorry, first golf, so could be wrong on how to calculate size) \$\endgroup\$
    – Psytronic
    Commented Aug 11, 2015 at 17:27
  • \$\begingroup\$ I was counting bytes using this handy tool. Windows uses two-byte line breaks so that may explain the discrepancy. \$\endgroup\$
    – Alex A.
    Commented Aug 11, 2015 at 21:01
  • \$\begingroup\$ @AlexA. Ahh, thanks, that makes sense! This version should be 180 then I guess. \$\endgroup\$
    – Psytronic
    Commented Aug 12, 2015 at 20:17
  • \$\begingroup\$ Rather than x**2. can you do x*x? That sould save 2 bytes. \$\endgroup\$
    – Alex A.
    Commented Aug 12, 2015 at 20:20
2
\$\begingroup\$

Python 2.7 306 Bytes

import math as z,re
t,m,r,w=float,map,reduce,[e.split() for e in re.split(' (?=[a-z])| (?=\d+(?:\.\d+)?$)',raw_input())]
def f(S,D):i=r(lambda x,y:x*y,D);return((i,i*.5)[S[0]=='t'],3.14*i*D[0])[S[0]=="c"]
print z.ceil(r(lambda x,y:x/y,m(lambda q:f(q[0],q[1:]),m(lambda x:[x[0]]+m(t,x[1:]),w[:-1]))))*t(*w[-1])

Takes input from stdin.
Testing it-

$ python pool.py
triangle 10 12.25 3 circle 5 2.2 5
10.0
$ python pool.py
triangle 5 87.3 20001 rectangle 5.14 2 105.623 0.2
804.2
\$\endgroup\$
2
\$\begingroup\$

Python 2, 222 146 139 119 103 93 bytes

Fairly straightforward implementation. Thanks to Sp3000 for the -(-n//1) trick for ceiling, which should work in all cases (i.e. haven't found an issue with it yet).

u=lambda q,k,l,m=1:k*l*[3.14*k,m][q>'c']*-~(q<'t')/2.
f=lambda a,b,c,d,s:-u(a,*c)//u(b,*d)*-s

Input should be formatted like so:

f(shape1, shape2, dimensions1, dimensions2, speed)
"Where shape1 and shape2 are one of 'c','r','t', dimensions1 is a list of the dimensions
 of the first shape, dimensions 2 is a list of the dimensions for the second shape, and
 speed is the speed of emptying in seconds."

Usage:

>>> f('t', 'r', [5, 87.3, 20001], [5.14, 2, 105.623], 0.2)
804.2
>>> f('t', 'c', [10, 12.25, 3], [5, 2.2], 5)
10.0

Ungolfed:

import math

def volume(shape, dimensions):
    out = dimensions[0] * dimensions[1]
    if shape == 'c':
        out *= 3.14 * dimensions[0]
    else:
        out *= dimensions[2]
    if shape == 't':
        out /= 2.0
    return out

def do(shape1, shape2, dimensions1, dimensions2, speed):
    volume1 = volume(shape1, dimensions1)
    volume2 = volume(shape2, dimensions2)
    return math.ceil(volume1 / volume2) * speed

Original solution, 222 bytes

This was made when the rules still needed you to input the whole word rather than a letter. I used the fact that hash(s)%5 mapped them to circle -> 2, triangle -> 3, rectangle -> 1, however if I just take one letter as input, I think I can get this shorter.

from math import*
u=lambda p,q:[[p[0]*p[1]*p[-1],3.14*p[0]**2*p[1]][1<q<3],0.5*p[0]*p[1]*p[-1]][q>2]
def f(*l):k=hash(l[0])%5;d=4-(1<k<3);v=l[1:d];r=hash(l[d])%5;g=4-(1<r<3);h=l[1+d:d+g];s=l[-1];print ceil(u(v,k)/u(h,r))*s

Usage:

>>> f('triangle',10,12.25,3,'circle',5,2.2,5)
10.0
>>> f('triangle',5,87.3,20001,'rectangle',5.14,2,105.623,0.2)
804.2
\$\endgroup\$
3
  • \$\begingroup\$ Well, if you want to cheat.. ;) \$\endgroup\$
    – Cyphase
    Commented Aug 11, 2015 at 13:57
  • \$\begingroup\$ @Cyphase How is it cheating? All I did was rearrange input, which is the same as what a lot of people did here.. \$\endgroup\$
    – Kade
    Commented Aug 11, 2015 at 14:01
  • \$\begingroup\$ (Oh hey, didn't see that it was you.) I was just kidding :). I'm going to try it with customized input as well. \$\endgroup\$
    – Cyphase
    Commented Aug 11, 2015 at 14:06
1
\$\begingroup\$

Python 2/3, 252 249 bytes

import re,math;i=[float(x)if re.match('[\d.]+',x)else x for x in re.sys.stdin.readline().split()]
for o in[0,[4,3][i[0]<'d']]:
 w=i[o+1]*i[o+2]*i[o+3]
 if i[o]<'d':w*=3.14*i[o+1]/i[o+3]
 if i[o]>'s':w*=.5
 a=a/w if o else w
print(math.ceil(a)*i[-1])

Usage Examples:

$ echo 'triangle 10 12.25 3 circle 5 2.2 5' | python stack_codegolf_54454.py
10.0
$ echo 'triangle 5 87.3 20001 rectangle 5.14 2 105.623 0.2' | python stack_codegolf_54454.py
804.2

The Python 2 only and Python 3 only versions are only different in how they receive input; raw_input() for Python 2 and input() for Python 3, as opposed to re.sys.stdin.readline() for the Python2/3 version.

Python 2, 240 237 bytes

import re,math;i=[float(x)if re.match('[\d.]+',x)else x for x in raw_input().split()]
for o in[0,[4,3][i[0]<'d']]:
 w=i[o+1]*i[o+2]*i[o+3]
 if i[o]<'d':w*=3.14*i[o+1]/i[o+3]
 if i[o]>'s':w*=.5
 a=a/w if o else w
print(math.ceil(a)*i[-1])

Python 3, 236 233 bytes

import re,math;i=[float(x)if re.match('[\d.]+',x)else x for x in input().split()]
for o in[0,[4,3][i[0]<'d']]:
 w=i[o+1]*i[o+2]*i[o+3]
 if i[o]<'d':w*=3.14*i[o+1]/i[o+3]
 if i[o]>'s':w*=.5
 a=a/w if o else w
print(math.ceil(a)*i[-1])

Changes:

Changed for o in[0,3if i[0]<'d'else 4]: to for o in[0,[4,3][i[0]<'d']]:. Thanks to Vioz for the inspiration :).

\$\endgroup\$
3
  • \$\begingroup\$ No, wait, never mind. That won't work, since the for loop is over [0, 3 if i[0] < 'd' else 4]. It's late (early?) :P. \$\endgroup\$
    – Cyphase
    Commented Aug 11, 2015 at 13:52
  • \$\begingroup\$ Oh, I missed it :P Nevermind. \$\endgroup\$
    – Kade
    Commented Aug 11, 2015 at 13:56
  • \$\begingroup\$ But I can use that technique in the for statement :). \$\endgroup\$
    – Cyphase
    Commented Aug 11, 2015 at 14:00
1
\$\begingroup\$

Pyth - 40 39 36 35 34 bytes

Uses simple method, mapping over both containers and then reducing by division.

*h/Fmc*Ftd@,/JChd58c.318@d1Jc2PQeQ

Takes input comma separated from stdin, with the first letter of each shape like: "t", 10, 12.25, 3, "c", 5, 2.2, 5.

Test Suite.

\$\endgroup\$
1
  • \$\begingroup\$ This is SO SHORT! Awesome job! :) \$\endgroup\$
    – Nick B.
    Commented Aug 16, 2015 at 14:43

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.