Làm thế nào tôi say và khi tôi có thể lái xe một lần nữa?


8

Đó là cuối tuần và những người tuyệt vời làm gì vào cuối tuần? Tất nhiên là uống! Nhưng bạn có biết những gì không tuyệt vời? Uống rượu lái xe. Vì vậy, bạn quyết định viết một chương trình cho bạn biết bạn đã tải như thế nào và khi nào bạn sẽ có thể lái xe trở lại mà không bị cảnh sát kéo qua và mất giấy phép.

Các thách thức

Đưa ra một danh sách đồ uống bạn thưởng thức tối nay, tính toán nồng độ cồn trong máu và thời gian bạn phải đợi cho đến khi bạn có thể nhảy lên xe và về nhà.

Đầu vào

Đầu vào sẽ là một danh sách đồ uống bạn đã có trong đêm này. Điều này sẽ trông như thế này:

4 shot booze
1 ly rượu
2 chai bia
3 ly nước

Container sẽ luôn luôn là số nhiều.

Như bạn có thể thấy mỗi mục bao gồm:

  • Các loại thức uống (booze, rượu, bia, nước)
  • Hộp đựng đồ uống (ảnh, ly, chai)
  • Số lượng x của đồ uống bạn có loại đó là số nguyên với x> 0,

Mỗi loại đồ uống sẽ thêm một lượng cồn nhất định vào máu của bạn:

rượu -> 0,5 ‰ / 100 ml
bia -> 0,1 / 100 ml
rượu vang -> 0,2 / 100 ml
nước -> -0,1 / 100 ml

Nước là ngoại lệ ở đây, vì nó làm máu bạn chảy ra và làm giảm nồng độ cồn của bạn (sẽ rất tuyệt nếu điều đó thực sự có hiệu quả ...).

Mỗi container có một khối lượng nhất định:

mũi tiêm -> 20 ml
ly -> 200 ml
chai -> 500 ml

Đầu ra

Bạn phải xuất hai số:

  • Độ cồn trong
  • Thời gian tính bằng giờ bạn phải đợi cho đến khi bạn đạt 0,5 ‰ hoặc ít hơn, để bạn có thể lái xe lại. Bạn mất 0,1 mỗi giờ.

Ghi chú

  • Độ cồn không bao giờ có thể giảm xuống dưới không.
  • Cùng đi trong thời gian chờ đợi. Nếu bạn có 0,5 hoặc ít hơn, đầu ra bằng không.
  • Thứ tự của đồ uống không quan trọng, vì vậy nước uống có thể hạ thấp nồng độ cồn xuống dưới 0 trong quá trình tính toán. Nếu nó vẫn ở đó, bạn cần thay thế nó bằng không.

Mức độ cồn cho ví dụ trên sẽ được tính như thế này:

4 phát súng -> 0,4
1 ly rượu vang -> 0,4
2 chai bia -> 1,0
3 ly nước -> -0,6

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

Để đạt 0,5 bạn cần mất 0,7. Bạn mất 0,1 mỗi giờ, vì vậy bạn cần đợi 7 giờ để lái xe lại.

Quy tắc

  • Bạn có thể lấy đầu vào ở bất kỳ định dạng nào bạn muốn, nhưng bạn phải sử dụng các chuỗi chính xác như được đưa ra ở trên. Bạn có thể lấy số là số nguyên.
  • Bạn có thể xuất hai số theo bất kỳ thứ tự nào, chỉ cần làm rõ số nào bạn sử dụng trong câu trả lời của mình.
  • Bạn có thể cho rằng đầu vào sẽ luôn có ít nhất một mục.
  • Chức năng hoặc chương trình đầy đủ cho phép.
  • Quy tắc mặc định cho đầu vào / đầu ra.
  • Tiêu chuẩn áp dụng.
  • Đây là , do đó, số byte thấp nhất sẽ thắng. Tiebreaker là trình trước đó.

Các trường hợp thử nghiệm

Nhập dưới dạng danh sách các chuỗi. Đầu ra mức độ cồn đầu tiên, các giá trị được phân tách bằng dấu phẩy.

["4 ly rượu bia", "1 ly rượu vang", "2 chai bia", "3 ly nước"] -> 1.2, 7
["10 lần uống rượu", "1 chai nước"] -> 0,5, 0
["3 ly rượu vang", "2 chai rượu"] -> 6.2, 57
["6 ly bia", "3 ly nước"] -> 0, 0
["Bia 10 ly"] -> 2.0, 15

Chúc mừng mã hóa!


1
"Độ cồn không bao giờ có thể giảm xuống dưới không." - Là mảng theo thứ tự nhượng bộ, hay chỉ trong tổng số? Vậy nếu tôi có 1 shot bia, và sau đó là 2 shot nước, và sau đó là 1 shot bia, thì nó nên sản xuất 0% hay 0,5%?
Kuilin Li

1
@KuilinLi Không phải vậy, thứ tự không quan trọng. Tôi sẽ làm rõ, cảm ơn vì nhận xét!
Denker

1
Vì vậy, nó nên đầu ra 0, và nồng độ cồn về mặt kỹ thuật có thể giảm xuống dưới 0 ở giữa uống? Vì nếu không, chúng ta không có cách nào để biết khi nào nước bị say nếu mảng có nước trong đó ... Chúng ta thậm chí có thể cho rằng, nếu mảng chứa nước, chúng ta sẽ uống nước trước và nó sẽ không ảnh hưởng đến bất cứ điều gì
Kuilin Li

1
@KuilinLi Tôi đã nói rõ trong thử thách bây giờ. Độ cồn có thể giảm xuống dưới 0 trong quá trình tính toán, bạn chỉ cần làm tròn nó về 0 nếu nó vẫn ở đó.
Denker

7
Tôi không uống, vì vậy, mục nhập của tôi làfunction drive(a) { if (a.every(v=>/water/.test(v))) return [0, 0]; throw new TeetotalException; }
Neil

Câu trả lời:


1

Javascript (ES6), 109

Lấy đầu vào dưới dạng các mảng của chuỗi / số nguyên, ví dụ:

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

Đầu ra cho mảng đơn giản ví dụ[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])

Giải thích

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

Chơi tốt nhưng không phải lúc nào cũng hợp lệ: thử[[3,"shots", "booze"]]
edc65

@ edc65 Bắt tốt!
thiệu lại

Nó chỉ cần một chút điều chỉnh và vẫn tốt hơn rất nhiều so với của tôi
edc65

6

TSQL, 301 , 299 , 219 , 206 byte

Đầu vào đi vào bảng tạm thời #I(bạn nói bất kỳ định dạng :)

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

Mã số:

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;

Cảm ơn những ý tưởng để cải thiện nó, Micky T :)


Đối với năm 2012+, bạn có thể sử dụng IIFhàm thay vì các CASEcâu lệnh cho một số byte
MickyT

1
Bạn cũng có thể thay đổi tên cột của mình trong các truy vấn con để tránh phải đủ điều kiện sau đó trong các mệnh đề tham gia, ví dụ JOIN(SELECT .. )A(Y,S)ON Y=N(L+ABS(L))/2,10*((L-.5+ABS(L-.5))/2)ngắn hơn hàm IIF đã đề cập trước đó. Bạn cũng có thể tiết kiệm một chút nếu bạn nhìn vào việc tham gia chéo vào các giá trị về kích thước và cường độ. ví dụSELECT 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]

Ít chơi gôn

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 byte

%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

Được chạy với perl -p . Lấy đầu vào định hướng dòng trên STDIN, tạo đầu ra trên STDOUT.

Phiên bản ít chơi gôn hơn:

# 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

Nhờ dev-null cho các đề xuất tiết kiệm 11 byte.


@ dev-null cảm ơn! Tôi nghĩ rằng chức năng có ý nghĩa cho việc rút ngắn trung gian, và tôi quên kiểm tra xem nó có còn giúp ích không.
David Morris

Nếu bạn luôn nhận được đầu vào hợp lệ thì bạn có thể thay đổi \dthành.
andlrc

Bạn có vui lòng thêm một ví dụ chạy chương trình không, vậy rõ ràng bạn sử dụng định dạng đầu vào và đầu ra nào?
Denker
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.