Quão bêbado estou e quando posso dirigir de novo?


8

É fim de semana e o que os caras legais estão fazendo nos finais de semana? Bebendo, é claro! Mas você sabe o que não é tão legal? Beber e dirigir. Então, você decide escrever um programa que diz a você como está carregado e quando poderá dirigir novamente sem ser detido pela polícia e perder sua licença.

O desafio

Dada uma lista de bebidas que você apreciou esta noite, calcule o seu nível de álcool no sangue e o tempo que você precisa esperar até entrar no seu carro e chegar em casa.

Entrada

Entrada será uma lista de bebidas que você tomou esta noite. Isso ficará assim:

4 tiros bebida
1 taça de vinho
2 garrafas de cerveja
3 copos de água

Os contêineres sempre serão plurais.

Como você pode ver, cada entrada consiste em:

  • O tipo de bebida (bebida, vinho, cerveja, água)
  • O recipiente para a bebida (doses, copos, garrafas)
  • A quantidade x das bebidas que você tomou desse tipo como número inteiro com x> 0,

Cada tipo de bebida adiciona uma certa quantidade de álcool ao seu sangue:

bebida -> 0,5 0.5 / 100 ml
cerveja -> 0,1 ‰ / 100 ml
vinho -> 0,2 ‰ / 100 ml
água -> -0,1 ‰ / 100 ml

A água é a exceção aqui, pois diminui o sangue e diminui o nível de álcool (seria muito bom se isso realmente funcionasse ...).

Cada contêiner possui um certo volume:

doses -> 20 ml
copos -> 200 ml
garrafas -> 500 ml

Resultado

Você precisa gerar dois números:

  • O nível de álcool em ‰
  • O tempo em horas em que você deve esperar até atingir 0,5 ‰ ou menos, para poder dirigir novamente. Você perde 0,1 ‰ por hora.

Notas

  • O nível de álcool nunca pode cair abaixo de zero.
  • O mesmo vale para o tempo de espera. Se você tiver 0,5 ‰ ou menos, produza zero.
  • A ordem das bebidas não importa; portanto, a água potável pode diminuir o nível de álcool abaixo de zero no processo de cálculo. Se ele permanecer lá, você precisará substituí-lo por zero.

O nível de álcool para o exemplo acima seria calculado da seguinte forma:

4 doses de bebida -> 0,4 ​​‰
1 taça de vinho -> 0,4 ​​‰
2 garrafas de cerveja -> 1,0 ‰
3 copos de água -> -0,6 ‰

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

Para atingir 0,5 ‰, você precisa perder 0,7 ‰. Você perde 0,1 ‰ por hora, e precisa esperar 7 horas para dirigir novamente.

Regras

  • Você pode pegar a entrada no formato que quiser, mas precisa usar as strings exatas, conforme indicado acima. Você pode pegar os números como números inteiros.
  • Você pode produzir os dois números em qualquer ordem, apenas deixe claro qual deles você usa na sua resposta.
  • Você pode assumir que a entrada sempre terá pelo menos uma entrada.
  • Função ou programa completo permitido.
  • Regras padrão para entrada / saída.
  • Brechas padrão se aplicam.
  • Isso é , e a menor contagem de bytes vence. O desempate é uma submissão anterior.

Casos de teste

Entrada como lista de strings. Emite primeiro o nível de álcool, valores separados por vírgula.

["4 doses de bebida", "1 copo de vinho", "2 garrafas de cerveja", "3 copos de água"] -> 1,2, 7
["10 doses de bebida", "1 garrafa de água"] -> 0,5, 0
["3 copos de vinho", "2 garrafas de bebida"] -> 6,2, 57
["6 shots beer", "3 glasses water"] -> 0, 0
["10 copos de cerveja"] -> 2,0, 15

Feliz codificação!


1
"O nível de álcool nunca pode cair abaixo de zero." - A matriz está em ordem de concessão ou apenas no total? Então, se eu tomar 1 dose de cerveja, 2 doses de água e 1 dose de cerveja, deve produzir 0% ou 0,5%?
— Kuilin Li 14/02/16

1
@KuilinLi Não é, a ordem não importa. Vou esclarecer, obrigado pelo comentário!
— Denker

1
Portanto, deve produzir 0, e o nível de álcool pode tecnicamente cair abaixo de zero no meio da bebida? Porque, caso contrário, não temos como saber quando a água estava bêbada se a matriz contiver água ... Poderíamos até assumir que, se a matriz contiver água, beberemos a água primeiro e ela terá efeito nulo. qualquer coisa.
— Kuilin Li 14/02/16

1
@KuilinLi Deixei claro no desafio agora. O nível de álcool pode cair abaixo de zero no processo de cálculo, basta arredondar para zero se permanecer lá.
— Denker 14/02

7
Eu não bebo, então minha entrada éfunction drive(a) { if (a.every(v=>/water/.test(v))) return [0, 0]; throw new TeetotalException; }
— Neil

Respostas:


1

Javascript (ES6), 109

Recebe entrada como matrizes de matrizes de strings / inteiros, por exemplo

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

Saídas para um array simples, por exemplo[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])

Explicado

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

Bem jogado, mas nem sempre válida: try[[3,"shots", "booze"]]
— edc65

@ edc65 Boa captura!
— 21716 reubn

Ele só precisa de um pouco de ajuste e ainda muito melhor do que a minha
— edc65

6

TSQL, 301 , 299 , 219 , 206 bytes

A entrada entra na tabela temporária #I(você disse qualquer formato :)

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

Código:

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;

Obrigado pelas idéias para melhorá-lo, Micky T :)


Para 2012+ você pode usar a IIFfunção em vez de CASEdeclarações para alguns bytes
— MickyT

1
Você também pode alterar os nomes das colunas nas subconsultas para evitar a qualificação nas cláusulas de junção, por exemplo, JOIN(SELECT .. )A(Y,S)ON Y=Ne (L+ABS(L))/2,10*((L-.5+ABS(L-.5))/2)é menor que a função IIF mencionada anteriormente. Você também pode economizar um pouco se tentar fazer uma junção cruzada nos valores de tamanho e resistência. por exemploSELECT V,N,Q*S FROM(VALUES(...))A(N,S),(VALUES(...)B(V,Q)
— MickyT 14/02

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]

Menos golfe

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]
)

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

Para ser executado com perl -p. Pega entrada orientada a linha em STDIN, produz saída em STDOUT.

Versão com menos golfe:

# 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

Obrigado a dev-null por sugestões de economia de 11 bytes.


@ dev-null obrigado! Acho que a função fazia sentido para um encurtamento intermediário e esqueci de verificar se ainda estava ajudando.
— David Morris

Se você sempre terá entrada válida, então você pode mudar \dpara.
— andlrc

Você poderia adicionar um exemplo de execução do programa, para ficar claro qual formato de entrada e saída você usa?
— Denker
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.