Can you handle the pub?

23

1

Background

It's late Friday afternoon and you and your friends decide to hit the pub later that evening, but before going to the pub you figure you should have a few beverages. However, things escalate quickly; your friend Shaddock Pamplemousse won the lottery earlier this week and decided to bring crates upon crates with different beverages. The security at the pub is very strict, and if you overconsume before trying to enter the premises you are not allowed inside. You are all programmers though - so you figure things will turn out great anyway.

Challenge

You need to program an alcohol meter which outputs truthy/falsy if you're above/below the reasonable pub limit. Before you go down to the pub you enter the amount and beverage type you've consumed during the evening to stdin which your measurement program reads. If it outputs truthy, you are above the pub limit and stay at home. If it outputs falsy, you're good to go.

Input

One integer greater than 0 which represents your body weight in kilograms followed by a newline. This input is followed by a series of one digit amounts and beverages on the following form:

<amount><amount type>o<beverage type>

For one bottle of beer this will look like:

1Bob

Each input is separated by a space.

Input specification

Each beverage has a unit which correspond to the impact caused by it. If you consume more units than your weight divided by two the pub is not an option anymore.

(This may or may not reflect reality)

The following are valid beverages and the corresponding alcoholic units of the beverage:

  • Beer: b, 1 unit

  • Energy drink: e, 0 units

  • Hot sauce: h, 2 units (strong stuff)

  • Juice (made of organic fruits etc): j, 0 units

  • Rum: r, 6 units

  • Tequila: t, 7 units

  • Vodka: v, 6 units

  • Wine: w, 3 units

There are different amount types:

  • Bottle: B

  • Crate: C

  • Glass: G

  • Keg: K

  • Sip: S

Each amount type has a multiplier which multiplies the alcoholic units of the beverage contained in it:

  • Bottle: 3

  • Crate: 25

  • Glass: 2

  • Keg: 50

  • Sip: 0.2

Output

Your program shall output truthy/falsy to stdout if the amount consumed is above/below your body weight divided by 2. If the amount consumed is equal to your weight divided by 2, you should output falsy.

Samples of possible input and output

Input

70
1Bob 3Soj

Output

False

Input

2
1Cov

Output

1

Input

50
1Cob

Output

0

Input

100
4Gow 1Koe 1Bov 1Gow 2Sot

Output

True

The shortest program in bytes wins!

sweerpotato

Posted 2015-11-12T19:41:23.130

Reputation: 2 457

1>

  • It seems that the o is a format character, though you've not said so specifically. You should clarify this (as o also refers to olive oil.) 2. What do we output if we are exactly on the limit? or doesn't it matter?
  • < – Level River St – 2015-11-12T20:42:16.457

    1Good call; I totally missed that. I'm removing olive oil (who drinks that anyway?) Below or equal to the limit should output falsy. I'll add that. – sweerpotato – 2015-11-12T20:52:51.440

    1Will there ever be more than one digit of drink? Eg, 43Gow? – Morgan Thrapp – 2015-11-12T22:00:27.030

    6+1 good question, but it's Friday afternoon and I need to go out for a beer. Maybe Monday:) – MickyT – 2015-11-13T02:33:31.210

    1I intended for it to be any amount really - except for negative amounts. I didn't think that would come off as ambiguous. I realize if I change this it will invalidate your answer, and that's not how we do things. Amount will be clarified as one digit. – sweerpotato – 2015-11-13T07:24:28.747

    I had originally assumed it was multi-digit numbers, but the test cases only showed one digit. – Morgan Thrapp – 2015-11-13T13:41:19.633

    1♪99Bob on the wall~♪ – ATaco – 2016-12-06T00:48:47.650

    Answers

    4

    CJam, 53 bytes

    6:B50:C2*:K4:G.4:S];q"behjrtvwo ""10206763*"er~*]:-U<
    

    Try it online in the CJam interpreter.

    How it works

    6:B          e# Push 6 and save it in B.
    50:C         e# Push 50 and save it in C.
    2*:K         e# Multiply by 2 to push 100 and save it in K.
    4:G          e# Push 4 and save it in G.
    .4:S         e# Push 0.4 and save it in S.
                 e#
                 e# The letters representing the types will now push its doubled
                 e# (to avoid diving the weight by 2) associated multiplier.
    ];           e# Clear the stack.
    q            e# Read all input.
    "behjrtvwo " e# Push the string of beverages, concatenated with "o ".
    "10206763*"  e# Push the string of associated units of alcohol and '*'.
    er           e# Transliterate. This replaces each beverage letter with the
                 e# associated units of alcohol, and each 'o' and ' ' with '*'.
                 e#
                 e# For example, the input
                 e# 70
                 e# 1Bob 3Soj
                 e# is transformed into
                 e# 70
                 e# 1B*1*3S*0
                 e#
    ~            e# Evaluate the resulting string.
                 e#
                 e# For the example this does the following:
                 e#   + Push 70.
                 e#   + Push 1, push 6, multiply, push 1, multiply.
                 e#   + Push 3, push 0.4, multiply, push 0.
                 e#
    *            e# Multiply the last two (for the lack of a trailing space).
    ]            e# Collect all results in an array.
    :-           e# Reduce by subtraction; subtract all other elements from the
                 e# first element (body weight).
    U<           e# Compare the result with 0.
    

    Dennis

    Posted 2015-11-12T19:41:23.130

    Reputation: 196 637

    8

    Python 3, 131

    Now we're golfing with snakes!

    Saved 18 bytes thanks to shebang.
    Saved 4 more bytes thanks to DSM.
    Saved a lot of bytes thanks to tzaman.

    Many thanks to tzaman for his brilliant trick of abusing .find() returning -1 if it doesn't find a value.

    Currently this assumes this drink format is exactly the way it's stated in the challenge, eg, only 1 digit worth of each drink.

    w=input()
    print(sum([6,50,4,100,.4]['BCGKS'.find(b)]*int(a)*int('1267730'['bhrtvw'.find(v)])for a,b,_,v in input().split())>int(w))
    

    Morgan Thrapp

    Posted 2015-11-12T19:41:23.130

    Reputation: 3 574

    I think it may be good if you dropped the dicts and did everything in the print statement. So, remove m and replace the m[p[-1]] bit with [3,25,2,50,.2]['BCGKS'.find(p[-1])], and the same with d. I got down to 168 with those changes to your code. – Kade – 2015-11-12T22:10:15.437

    4

    Minkolang 0.11, 59 bytes

    126763355*25l*2l$:"SKGCBwvtrhb"m(0pI)n(no0qoxo0q**2*-$I)`N.
    

    Try it here.

    Explanation

    126763355*25l*2l$:    Pushes the values of the characters
    "SKGCBwvtrhb"         Pushes the characters themselves
    m                     Merge; interleaves the first and second halves of the stack
    (                     Open while loop
     0p                   Put character's value in character's place in the codebox
       I)                 Close while loop when stack is empty
    n                     Read in integer (weight)
    (                     Open while loop
     n                    Read in integer, ignoring any non-numeric characters
      o0q                 Read in character and get its value from the codebox
         ox               Read in character and dump it
           o0q            Read in character and get its value from the codebox
              **          Multiply the three numbers together
                2*-       Multiply by 2 and subtract from weight
                   $I)    Close while loop when input is empty
    `                     1 if less than 0, 0 otherwise
     N.                   Output as integer and stop.
    

    El'endia Starman

    Posted 2015-11-12T19:41:23.130

    Reputation: 14 504

    I guess CJam is getting outdated... I need to finish my language then – anOKsquirrel – 2015-11-12T23:18:04.307

    @anOKsquirrel: Or rather, you just haven't golfed it enough. :) – El'endia Starman – 2015-11-12T23:18:29.647

    Or rather, both. :P – anOKsquirrel – 2015-11-12T23:20:31.767

    No, actually, I'm just bad :p – anOKsquirrel – 2015-11-12T23:26:15.393

    3

    CJam, 54 bytes

    ldlS/{A,s"CbretjvwSBK"+f#A,[25X6T7T6Z.2Z50Y]+f=:*-}/0<
    

    Bit fiddly and probably suboptimal, but I think this works okay. Try it online.

    Explanation

    ld             Read first line, convert to double
    lS/            Read second line, split by space
    {...}/         For each item in the second line...
      A,s"..."+f#    Get index in "0123456789CbretjvwSBK", or -1 if not found
      A,[...]+f=     Index into [0 1 2 3 4 5 6 7 8 9 25 1 6 0 7 0 6 3 0.2 3 50 2]
      :*             Take product
      -              Subtract from weight
    0<             Check if < 0
    

    Note that the numeric array has 2 at the end, meaning that Gho, which are missing from the first string, get mapped to 2.

    Sp3000

    Posted 2015-11-12T19:41:23.130

    Reputation: 58 729

    2

    CJam, 77

    qN%~S%{:BW="behjrtvw"\#10206773s:~\=[3 25 2 50 .2]"BCGKS"B-3=#=*1mO}%:+\~2/\>
    

    anOKsquirrel

    Posted 2015-11-12T19:41:23.130

    Reputation: 361

    2

    VBA, 251 bytes

    Function k(x) As Boolean:q=Split(x):g="b1e0h2j0r6t7v6w3":h="B03C25G02K50S.2":For i=1 To UBound(q):j=j+Left(q(i),Len(q(i))-3)*Mid(h,InStr(h,Mid(Right(q(i),3),1,1))+1,2)*Mid(g,InStr(g,Mid(Right(q(i),3),3,1))+1,1):Next i:If q(0)/2<j Then k=1
    End Function
    

    Using : rather then Newline doesn't make it shorter, But it does look more golfy!

    Readable Format

    Function b(x) As Boolean
    q = Split(x)
    g = "b1e0h2j0r6t7v6w3"
    h = "B03C25G02K50S.2"
    For i = 1 To UBound(q)
    j = j + Left(q(i), Len(q(i)) - 3) * _          'Left most digits would be the Quantity
    Mid(h, InStr(h, Mid(Right(q(i), 3), 1, 1)) + 1, 2) * _  'Find the Container value in h
    Mid(g, InStr(g, Mid(Right(q(i), 3), 3, 1)) + 1, 1)      'Find the Drink value in g
    Next i
    If q(0) / 2 < j Then b = 1 'Checks if Drunk or not
    End Function
    

    Pretty Sure this can be golfed. my String Manipulation with Mid(Right()) seems excessively wordy, But running the array though StrReverse makes it longer. If we assume you only drink 0-9 of any particular drink at a time we can save a handful of bytes

    Take input as one string with weight separated by a space as VBA dose not support multi line input

    JimmyJazzx

    Posted 2015-11-12T19:41:23.130

    Reputation: 691

    2

    Ruby, 153 bytes

    I need to get rid of the gsubs somehow

    w=gets.to_i;$><<(eval(gets.chars{|c|c[/[0-9]/]!=p ? ($_[c]+='*'):0}.tr('behjrtvwo BG','10206763*+32').gsub('C','25').gsub('K','50').gsub('S','0.2'))>w/2)
    

    Peter Lenkefi

    Posted 2015-11-12T19:41:23.130

    Reputation: 1 577

    2

    JavaScript, 131 134 139 bytes

    This is a full program and basically an adaption of my PHP answer:

    for(c=prompt,b=c(a=c(s=i=0));b[i];i+=2)s+=b[i++]*{B:3,C:25,G:2,K:50,S:.2}[b[i++]]*{b:1,h:2,r:6,t:7,v:6,w:3}[b[++i]]||0;alert(s>a/2)
    

    It reads two values using prompt and alerts the result as [true|false].


    Edits

    • Saved 5 bytes by using a logical expression ||0 instead of declaring the beverages with 0 units. Thanks to user81655.
    • Saved 3 bytes by storing prompt in a variable and shortening the initialization. Thanks to Stefnotch.

    insertusernamehere

    Posted 2015-11-12T19:41:23.130

    Reputation: 4 551

    1You could save 6 bytes by changing ,e:0,j:0}[b[++i]] to }[b[++i]]|0. – user81655 – 2015-11-14T10:19:53.623

    @user81655 Yesterday I was thinking, how to get rid of those 0-values. Well, I didn't think of that. Had to use || instead of the bitwise operator. Still 5 bytes less. Thanks. – insertusernamehere – 2015-11-14T10:27:49.313

    No problem. I forgot about the possible non-integer values. – user81655 – 2015-11-14T10:46:11.073

    1for(s=i=0,a=prompt(),b=prompt(); can be changed to: for(c=prompt,b=c(a=c(s=i=0)); – Stefnotch – 2015-11-14T18:19:03.067

    1@Stefnotch That's clever. I like it. Thanks for saving 3 bytes. – insertusernamehere – 2015-11-15T16:42:11.933

    1

    Keg, 165 bytes (SBCS)

    ¿®w?(: =[_]")0®u(!4/|\0-&:B=[&3*&|:C=[&55**&|:G=[&2*&|:K=[&\2*&|&15/*&]]]]__:b=[&1*&|:e=[&0&|:h=[&2*&|:j=[&0&|:r=[&6*&|:t=[&7*&|:v=[&6*&|&3*&]]]]]]]_©u&+®u)©w2/:©u<.
    

    Try it online!

    I feel as if though a Keg answer has never been more appropriate! This could probably be golfed, but I don't think it can.

    Explained

    ¿®w                                                                         #Take the weight and store it in a variable
    ?(: =[_]")                                                                  #Take the second line and remove spaces
    0®u                                                                         #Store the units in a variable
    (!4/|                                                                       #For every part in the input
    \0-&                                                                        #Store the amount of drink in the register
    :B=[&3*&|:C=[&55**&|:G=[&2*&|:K=[&\2*&|&15/*&]]]]__                         #Determine the beverage multiplier
    :b=[&1*&|:e=[&0&|:h=[&2*&|:j=[&0&|:r=[&6*&|:t=[&7*&|:v=[&6*&|&3*&]]]]]]]_   #Determine the drink
    ©u&+®u)                                                                     #Add the amount to units
    ©w2/:©u<.                                                                   #Check the condition and print
    

    Lyxal

    Posted 2015-11-12T19:41:23.130

    Reputation: 5 253

    1

    bash (+ bc + GNU sed), 200 196 194 bytes

    read x
    read y
    y="$(sed 's/^/((/;s/$/))/;s/ /)+(/g;s/o/*/g;s/b/1/g;s/[ej]/0/g;s/h/2/g;s/[rv]/6/g;s/w/3/g;s/t/7/g;s/B/*3/g;s/C/*25/g;s/G/*2/g;s/K/*50/g;s/S/*0.2/g'<<<"$y")"
    echo "$y>$x/2"|bc -l
    

    user2064000

    Posted 2015-11-12T19:41:23.130

    Reputation: 270

    1

    PHP, 163 169 bytes

    for($a=fgets(STDIN),$b=fgets(STDIN),$v=[b=>1,h=>2,r=>6,t=>7,v=>6,w=>3,B=>3,C=>25,G=>2,K=>50,S=>.2];$b[$i];$i+=2)$s+=$b[$i++]*$v[$b[$i++]]*$v[$b[++$i]];echo$s>$a/2;
    

    Outputs 1 or nothing, works for all test cases.


    I still wonder what this hot sauce is, having 2 units.


    Edits

    • Saved 6 bytes by merging the two arrays for drinks and multiplier and by removing 0 from 0.2.

    insertusernamehere

    Posted 2015-11-12T19:41:23.130

    Reputation: 4 551

    1

    Javascript, 159 bytes

    function b(t){return a={B:3,C:25,G:2,K:50,S:.2,b:1,h:2,w:3,r:6,v:6,t:7},t.split(/\W/).reduceRight(function(t,n,r){return r?n[0]*a[n[1]]*a[n[3]]+t||t:t>n/2},0)}
    

    Since Javascript requires a library to access STDIN, this code is just a function that accepts the entirety of the input, i.e. b("100\n4Gow 1Koe 1Bov 1Gow 2Sot")

    Wasmoo

    Posted 2015-11-12T19:41:23.130

    Reputation: 634

    1As a note: prompt() is generally accepted as a valid alternative to STDIN in JavaScript. – insertusernamehere – 2015-11-13T23:24:37.127

    1You could save 30 bytes by going ES6 and using the arrow-operator: b=t=>(a={B:3,C:25,G:2,K:50,S:.2,b:1,h:2,w:3,r:6,v:6,t:7},t.split(/\W/).reduceRight((t,n,r)=>r?n[0]*a[n[1]]*a[n[3]]+t||t:t>n/2,0)). – insertusernamehere – 2015-11-13T23:44:30.933

    1

    Python 3, 157 bytes

    n,l,d,u=int(input()),input(),"behjrtvwBCGKS",[1,0,2,0,6,7,6,3,3,25,2,50,.2]
    print(sum(map(lambda x:int(x[0])*u[d.find(x[1])]*u[d.find(x[3])],l.split()))>n/2)
    

    uno20001

    Posted 2015-11-12T19:41:23.130

    Reputation: 321