Wie betrunken bin ich und wann kann ich wieder fahren?

8

Es ist Wochenende und was machen die coolen Jungs am Wochenende? Trinken natürlich! Aber weißt du was nicht so cool ist? Trinken und fahren. Sie beschließen also, ein Programm zu schreiben, das Ihnen sagt, wie geladen Sie sind und wann Sie wieder fahren können, ohne von den Bullen überfahren zu werden und Ihren Führerschein zu verlieren.

Die Herausforderung

Berechnen Sie anhand einer Liste von Getränken, die Sie heute Abend genossen haben, Ihren Blutalkoholspiegel und die Zeit, die Sie warten müssen, bis Sie in Ihr Auto steigen und nach Hause kommen können.

Eingang

Die Eingabe wird eine Liste der Getränke sein, die Sie heute Abend hatten. Das wird so aussehen:

4 Schüsse Alkohol
1 Glas Wein
2 Flaschen Bier
3 Gläser Wasser

Container werden immer Plural sein.

Wie Sie sehen können, besteht jeder Eintrag aus:

  • Die Art des Getränks (Alkohol, Wein, Bier, Wasser)
  • Der Behälter für das Getränk (Schüsse, Gläser, Flaschen)
  • Die Menge x der Getränke, die Sie von diesem Typ als Ganzzahl mit x> 0 hatten,

Jede Getränkeart fügt Ihrem Blut eine bestimmte Menge Alkohol hinzu:

Alkohol -> 0,5 ‰ / 100 ml
Bier -> 0,1 ‰ / 100 ml
Wein -> 0,2 ‰ / 100 ml
Wasser -> -0,1 ‰ / 100 ml

Wasser ist hier die Ausnahme, da es Ihr Blut verdünnt und Ihren Alkoholspiegel senkt (wäre so schön, wenn das tatsächlich funktionieren würde ...).

Jeder Container hat ein bestimmtes Volumen:

Schüsse -> 20 ml
Gläser -> 200 ml
Flaschen -> 500 ml

Ausgabe

Sie müssen zwei Zahlen ausgeben:

  • Der Alkoholgehalt in ‰
  • Die Zeit in Stunden müssen Sie warten, bis Sie 0,5 ‰ oder weniger erreicht haben, damit Sie wieder fahren können. Sie verlieren 0,1 ‰ pro Stunde.

Anmerkungen

  • Der Alkoholgehalt kann niemals unter Null fallen.
  • Gleiches gilt für die Wartezeit. Wenn Sie 0,5 ‰ oder weniger haben, geben Sie Null aus.
  • Die Reihenfolge der Getränke spielt keine Rolle, daher kann Trinkwasser den Alkoholgehalt während der Berechnung unter Null senken. Wenn es dort bleibt, müssen Sie es durch Null ersetzen.

Der Alkoholgehalt für das obige Beispiel würde wie folgt berechnet:

4 Schüsse Alkohol -> 0,4 ​​‰
1 Glas Wein -> 0,4 ​​‰
2 Flaschen Bier -> 1,0 ‰
3 Gläser Wasser -> -0,6 ‰

=> 0,4 ​​+ 0,4 + 1 - 0,6 = 1,2 ‰

Um 0,5 ‰ zu erreichen, müssen Sie 0,7 ‰ verlieren. Sie verlieren 0,1 ‰ pro Stunde, müssen also 7 Stunden warten, um wieder zu fahren.

Regeln

  • Sie können die Eingabe in jedem gewünschten Format vornehmen, müssen jedoch die oben angegebenen genauen Zeichenfolgen verwenden. Sie können die Zahlen als ganze Zahlen nehmen.
  • Sie können die beiden Zahlen in beliebiger Reihenfolge ausgeben. Machen Sie einfach klar, welche Sie in Ihrer Antwort verwenden.
  • Sie können davon ausgehen, dass die Eingabe immer mindestens einen Eintrag enthält.
  • Funktion oder volles Programm erlaubt.
  • Standardregeln für die Eingabe / Ausgabe.
  • Es gelten Standardlücken .
  • Dies ist , also gewinnt die niedrigste Byte-Anzahl. Tiebreaker ist eine frühere Einreichung.

Testfälle

Eingabe als Liste von Zeichenfolgen. Gibt zuerst den Alkoholgehalt aus, die Werte werden durch ein Komma getrennt.

["4 Schuss Alkohol", "1 Glas Wein", "2 Flaschen Bier", "3 Gläser Wasser"] -> 1,2, 7
["10 Schuss Alkohol", "1 Flasche Wasser"] -> 0,5, 0
["3 Gläser Wein", "2 Flaschen Alkohol"] -> 6,2, 57
["6 Schuss Bier", "3 Gläser Wasser"] -> 0, 0
["10 Gläser Bier"] -> 2,0, 15

Viel Spaß beim Codieren!

Denker
quelle
1
"Der Alkoholgehalt kann niemals unter Null fallen." - Ist das Array in der Reihenfolge der Konzession oder nur insgesamt? Wenn ich also 1 Schuss Bier und dann 2 Schuss Wasser und dann 1 Schuss Bier habe, sollte es 0% oder 0,5% ausgeben?
Kuilin Li
1
@ KuilinLi Es ist nicht, Reihenfolge spielt keine Rolle. Ich werde klarstellen, danke für den Kommentar!
Denker
1
Es sollte also 0 ausgegeben werden und der Alkoholgehalt kann mitten im Trinken technisch unter Null fallen? Denn sonst können wir nicht wissen, wann das Wasser getrunken wurde, wenn das Array Wasser enthält ... Wir könnten sogar davon ausgehen, dass wir, wenn das Array Wasser enthält, das Wasser zuerst trinken und es keine Auswirkungen auf hat etwas.
Kuilin Li
1
@ KuilinLi Ich habe es jetzt in der Herausforderung deutlich gemacht. Der Alkoholgehalt kann während der Berechnung unter Null fallen. Sie müssen ihn nur auf Null runden, wenn er dort bleibt.
Denker
7
Ich trinke nicht, also ist mein Eintragfunction drive(a) { if (a.every(v=>/water/.test(v))) return [0, 0]; throw new TeetotalException; }
Neil

Antworten:

1

Javascript (ES6), 109

Nimmt Eingaben als Arrays von Arrays von Strings / Integer auf, z

[[4, "shots", "booze"],
[1, "glasses", "wine"],
[2, "bottles", "beer"],
[3, "glasses", "water"]]

Ausgaben für ein einfaches Array, z[1.2, 7]

a=>(b=0,c={s:2,g:20,b:50,o:2,e:10,i:5,a:-10},a.map(([d,e,f])=>b+=d*c[e[0]]/c[f[1]]),g=b>0?b:0,[g/10,g?g-5:0])

Erklärt

a => (
b = 0,                                           // Counter For Alcohol Level
c = {s:2, g:20, b:50, o:2, e:10, i:5, a:-10},    // Look up for values
a.map(                                           // Loops over array
  ([d, e, f]) =>                                 // Sets d,e,f to respective array indexes 
     b += d * c[e[0]] / c[f[1]]                  // Increases Level by values from lookup
  ),
g = b > 0 ? b : 0,                               // If Level is lower than 0 make it = 0
[g / 10, g ? g - 5 : 0])                         // Output: Level / 10 and Level - 5 bound to 0
reubn
quelle
Gut gespielt, aber nicht immer gültig: try[[3,"shots", "booze"]]
edc65
@ edc65 Guter Fang!
Reubn
Es muss nur ein wenig
angepasst werden
6

TSQL, 301 , 299 , 219 , 206 Bytes

Die Eingabe erfolgt in die temporäre Tabelle #I(Sie haben ein beliebiges Format angegeben :)

SELECT * INTO #I FROM (
  VALUES
    (4,'shots','booze')
   ,(1,'glasses','wine')
   ,(2,'bottles','beer')
   ,(3, 'glasses','water')
) A (Q, V, N)

Code:

SELECT IIF(L<0,0,L),IIF(10*L-.5<0,0,10*L-.5)FROM(SELECT SUM(Q*S*P)L FROM(VALUES('bo%',.5),('be%',.1),('wi%',.2),('wa%',-.1))A(W,S),(VALUES('s%',.2),('g%',2),('b%',5))B(X,P),#I WHERE N LIKE W AND V LIKE X)A;

Danke für die Ideen, es zu verbessern, Micky T :)

Liesel
quelle
Für 2012+ könnten Sie die IIFFunktion anstelle von CASEAnweisungen für einige Bytes verwenden
MickyT
1
Sie können Ihre Spaltennamen auch in den Unterabfragen ändern, um zu vermeiden, dass Sie sich dann in den Join-Klauseln qualifizieren müssen, z. B. JOIN(SELECT .. )A(Y,S)ON Y=Nund (L+ABS(L))/2,10*((L-.5+ABS(L-.5))/2)ist kürzer als die zuvor erwähnte IIF-Funktion. Sie können auch etwas sparen, wenn Sie die Werte für Größe und Stärke kreuzweise verknüpfen möchten. zBSELECT V,N,Q*S FROM(VALUES(...))A(N,S),(VALUES(...)B(V,Q)
MickyT
3

JavaScript (ES6), 131

a=>a.map(s=>([a,b,c]=s.split` `,t+=a*[50,20,2]['bgs'.search(b[0])]*~-'0236'['aeio'.search(c[1])]),t=0)&&[t>0?t/100:0,t>50?t/10-5:0]

Weniger Golf gespielt

a=>(
  t=0,
  a.map(s=>(
    [a,b,c] = s.split` `,
    t += a * [50,20,2]['bgs'.search(b[0])] // char 0 is unique
           * [-1,1,2,5]['aeio'.search(c[1])] // char 1 is unique 
           // golfed: add 1 to get a string of dingle digits, the sub 1 using ~-
    )
  ),
  [ t>0 ? t/100 : 0, t>50 ? t/10-5 : 0]
)
edc65
quelle
1

Perl, 133 119 + 3 = 136 122 Bytes

%u=(o,.5,e,.1,i,.2,a,-.1,g,2,b,5,s=>.2);/(\d+) (.).* .(.)/;$x+=$1*$u{$2}*$u{$3}}{$_=($x>0?$x:0).$".($x-.5>0?$x-.5:0)*10

Zum Laufen mit perl -p. Übernimmt eine linienorientierte Eingabe in STDIN und eine Ausgabe in STDOUT.

Weniger Golfversion:

# char->number conversion table
# declared using barewords except for 's', which can't be a bareword
# because it's a keyword
%u=(o,.5, e,.1, i,.2, a,-.1, g,2, b,5, s=>.2);

# extract the number, first letter of first word, second letter of
# second word
/(\d+) (.).* .(.)/;

# do unit conversion and multiply up all factors
$x += $1 * $u{$2} * $u{$3}

# hack for -p to produce an END { ... print } block
}{

# format output
$_ = ($x > 0 ? $x : 0) . $" . ($x-.5 > 0 ? $x-.5 : 0)*10

Vielen Dank an dev-null für Vorschläge zum Einsparen von 11 Bytes.

David Morris
quelle
@ dev-null danke! Ich denke, die Funktion machte Sinn für eine Zwischenverkürzung, und ich habe vergessen zu prüfen, ob sie noch hilft.
David Morris
Wenn Sie immer eine gültige Eingabe erhalten, können Sie \dzu.
andlrc
Würden Sie bitte einen Beispiellauf des Programms hinzufügen, damit klar ist, welches Eingabe- und Ausgabeformat Sie verwenden?
Denker