Sakit kepala saat liburan

14

Peringatan: JANGAN menerima saran medis dari pos ini. Jika Anda menginginkan saran medis, pergi ke profesional yang berkualitas.

Aku sedang sakit kepala. Saya perlu pil sakit kepala.

Saya akan memberi tahu Anda beberapa dosis terakhir yang saya miliki, dan Anda memberi tahu saya kapan saya bisa mendapatkan dosis berikutnya, tanpa overdosis.

Saya akan memberi Anda string ini: P: 00:00, I: 02:00, P: 04:00, I: 06:00

Dan Anda akan memberi saya ini: Next P: 08:00, I: 10:00

Memasukkan:

String yang mewakili waktu setiap obat telah diminum, dalam format berikut:

P: 00:00, I: 02:00, P: 04:00, I: 06:00

Ini berarti Paracetamol diambil pada pukul 00:00 dan 04:00, dan Ibuprofen diambil pada pukul 02:00 dan 06:00

Output (diperbarui):

Tali dengan waktu obat berikutnya masing-masing dapat diambil, dalam format berikut:

Next P: 08:00, I: 10:00
  • Urutan output harus dalam urutan obat yang harus diambil. - Jika Ibuprofen akan diambil pada 09:35 dan Paracetamol dan 10:22, maka hasilnya akan menjadiNext I: 09:35, P: 10:22
  • Jika waktu untuk dosis berikutnya masing-masing obat adalah sama, urutan hasilnya tidak masalah: Next P: 08:00, I: 08:00ATAUNext I: 08:00, P: 08:00
  • Jika hanya satu obat yang diminum (dalam string input), maka hanya obat yang harus dalam string output: Next P: 02:00

Aturan:

  • Hanya akan ada dua jenis obat, Paracetamol 'P' dan Ibuprofen 'I'.
  • Parasetamol dapat dikonsumsi setiap 4 jam sekali, maksimal 4 kali dalam periode 24 jam.
  • Ibuprofen juga dapat dikonsumsi setiap 4 jam, maksimal 4 kali dalam periode 24 jam.
  • Paracetamol dan Ibuprofen dapat dikonsumsi bersamaan, atau pada waktu yang berbeda. Satu tidak diperhitungkan terhadap dosis yang lain.
  • Waktu dalam string input akan selalu berurutan, tetapi dapat bergulir di tengah malam (23:00 -> 03:00)
  • Waktu dalam string input tidak akan menjangkau lebih dari 24 jam
  • Maksimal 4 kali untuk setiap obat (total 8 maks)
  • Masukan akan selalu kosong dan mengandung setidaknya satu obat dan satu kali

Contoh:

Dua dosis masing-masing pada interval dua jam:

"P: 00:00, I: 02:00, P: 04:00, I: 06:00" -> "Next P: 08:00, I: 10:00"

Parasetamol dosis tunggal

"P: 22:00" -> "Next P: 02:00"

Dosis parasetamol maksimum dalam 24 jam, dosis Ibuprofen tunggal

"P: 04:05, P: 08:10, P: 12:15, I: 12:30, P: 16:25" -> "Next I: 16:30, P: 04:05"

Kasus uji:

"I: 06:00" -> "Next I: 10:00"
"P: 22:00" -> "Next P: 02:00"
"P: 22:00, P: 02:00, I: 06:00" -> "Next P: 06:00, I: 10:00"
"P: 00:00, I: 02:00, P: 04:00, I: 06:00" -> "Next P: 08:00, I: 10:00"
"P: 04:05, P: 08:10, P: 12:15, I: 12:30, P: 16:25" -> "Next I: 16:30, P: 04:05"
"I: 06:32, P: 08:15, I: 10:44, P: 13:03" -> "Next I: 14:44, P: 17:03"
"P: 07:30, I: 07:30, P: 11:30, I: 11:30, P: 15:30, I: 15:30, I: 19:30" -> "Next P: 19:30, I: 07:30"
"I: 07:30, P: 11:30, I: 11:30, P: 15:30, I: 15:30, P: 19:30, I: 19:30" -> "Next P: 23:30, I: 07:30"
"P: 07:30, I: 07:30, P: 11:30, I: 11:30, P: 15:30, I: 15:30, P: 19:30, I: 19:30" -> "Next P: 07:30, I: 07:30" OR "Next I: 07:30, P: 07:30"

Ini adalah kode golf, jadi jawaban terpendek int byte menang.

MEMPERBARUI:

Hasilnya sekarang bisa singkatan dari Paracetamol dan Ibuprofen; PdanI

Erresen
sumber
Saya akan senang memiliki beberapa pengaruh pada format input dan output - meta post
Gurupad Mamadapur
Output @GurupadMamadapur mungkin, tetapi mengekstraksi waktu dan jenis obat dari input adalah setengah dari tantangan
Erresen
Saya akan merekomendasikan Anda mengizinkan orang untuk menyingkat parasetamol dan ibuprofen sebagai hasil karena mereka menambahkan panjang yang tidak perlu untuk pengiriman
Cyoce
@Cyoce ya saya setuju, mencoba solusi sendiri dan itu sebenarnya agak rumit - memperbarui aturan untuk memungkinkan keluaran yang disingkat
Erresen
@ Lynn setuju & diperbarui
Erresen

Jawaban:

4

JavaScript (ES6), 367 362 354 358 byte

Versi golf:

A=i=>i>9?""+i:"0"+i,B=(s,a=":")=>s.split(a),C=(a,b,c,d)=>[...[s,t]=B((b>3?c:d)||":"),a+` ${A(s=b>3?+s:(+s+4)%24)}:`+A(t=+t)],F=s=>{a=B(s,m=", ");for(b=c=d=e=f=p=q=0;f<a.length;g=="P:"?(b++,d=d?h:p=h):(c++,e=e?h:q=h))[g,h]=B(a[f++]," ");[i,j,k]=C("P",b,p,d),[n,o,l]=C("I",c,q,e),r=B(h)[0];return"Next "+c?b?n*60+(n<r)*1440+j<i*60+(i<r)*1440+o?l+m+k:k+m+l:l:k}

Tidak dikelompokkan / dikomentari:

// Returns a zero-padded string of the argument.
A=i=>i>9?""+i:"0"+i,

// Since we do a lot of splitting, alias it. Making the
// second argument optional (and defaulting to ':') saved
// 3 bytes
B=(s,a=":")=>s.split(a),

// Constructs a string for output, along with the time
// of the next dose, in the format [hour, minute, string].
// Arguments:               type
// a -> type (P/I)          String
// b -> amount of doses     Number
//      taken
// c -> first dose taken    String
// d -> last dose taken     String
//
// The first two values are split from the string, but
// before the array is returned, they are converted to
// integers (during the string construction).
C=(a,b,c,d)=>[...[s,t]=B((b>3?c:d)||":"),a+` ${A(s=b>3?+s:(+s+4)%24)}:`+A(t=+t)],

// Main function. Returns the time(s) for the next dose.
// Argument:                type
// s -> list of times of    String
//      and types of 
//      doses taken
F=s=>{
    a=B(s,m=", "); // Split the input by comma + space,
                   // and save that string, since we
                   // need it later when constructing
                   // the output string.
    // For loop has been restructured. Original:
    // for(b=c=f=0;f<a.length;g=="P:"?(b++,d=d?h:p=h):(c++,e=e?h:q=h))
    //     [g,h]=B(a[f++]," ");
    b = 0; // P-dose counter
    c = 0; // I-dose counter
    d = 0; // Last P-dose
    e = 0; // Last I-dose
    p = 0; // First P-dose
    q = 0; // First I-dose
    for (f = 0; f < a.length; f++) {
        [g, h] = B(a[f], " ");  // g contains the type,
                                // h contains the time
        if (g == "P:") {
            b++;                // increase the counter

            if (d == 0) {   // store h in p if this is
                p = h;      // the first dose of this
            }               // type
            d = h;
        } else {
            // See the above code block for comments
            c++;

            if (e == 0) {
                q = h;
            }
            e = h;
        }
    }
    // End of restructured for loop.

    // Construct the output strings, and get the times.
    // See comments at C function.
    [i, j, k] = C("P", b, p, d);
    [n, o, l] = C("I", c, q, e);

    // Get the amount of hours of the dose taken last.
    // We use this to get the correct order of the two
    // times.
    r = B(h)[0];

    // Return statement has been restructured. Original:
    // return "Next "+c?b?n*60+(n<r)*1440+j<i*60+(i<r)*1440+o?l+m+k:k+m+l:l:k
    //==================================================
    // Start creating the output string.
    output = "Next "
    // Use the following checks to figure out what needs
    // to be part of the output and in what order.
    if (c > 0) {
        if (b > 0) {
            // Compare the times of next doses
            // P_time = (i + (i < r) * 24) * 60
            // I'm using implicit conversion of
            // booleans to numbers. If the next
            // dose is past midnight, add 1 * 24
            // to the time, so it is compared
            // correctly.
            // Then add the minutes to the number.
            P_time = i*60+(i<r)*1440+o;
            I_time = n*60+(n<r)*1440+j;

            if (I_time < P_time) {
                output += l + m + k; // I first
            } else {
                output += k + m + l; // P first
            }
        } else {
            output += l; // Just I
        }
    } else {
        output += k; // Just P
    }

    // Finally, return the output
    return output;
}

Untuk menggunakannya, panggil F dengan string sebagai argumen seperti:

F("P: 04:00, I: 06:00")
Luke
sumber
Ini bagus, tapi saya punya beberapa masalah. Tampaknya gagal jika hanya ada satu jenis pil di input, misalnya F("P: 22:00")-> ReferenceError: q is not defined. Input ini akan berjalan jika P&I telah direferensikan sebelumnya, tetapi dengan detail lama untuk saya.
Chris M
Terima kasih! Saya baru saja mengujinya dan Anda benar tentang kesalahan referensi. Saya kira variabel q tidak diatur ulang dan saya tidak membayar cukup perhatian selama pengujian. Terima kasih telah memberi tahu saya, saya akan memperbaikinya nanti.
Lukas
Ternyata menjadi perbaikan yang mudah, tapi harganya 4 byte.
Lukas
1

Python 3 - 437 byte

a=input();i=p=l=-1;j=q=0
for x in a.split(", ")[::-1]:
    for y, z in [x.split(": ")]:
        s=lambda q,r,t:[t,sum([a*b for a,b in zip([60,1],map(int,q.split(':')))])][r%4<2]+[0,240][r<2]
        if y=="I":j+=1;i=s(z,j,i)
        else:q+=1;p=s(z,q,p)
        l=[l,p+i-239][j+q<2]
r=lambda d,e:("","%s: %02d:%02d, "%(d,(e/60)%24,e%60))[e>-1];p+=[1440,0][p>=l];i+=[1440,0][i>=l];print("Next "+[r("I",i)+r("P",p),r("P",p)+r("I",i)][p<i][:-2])

Penjelasan:

a=input();i=p=l=-1;j=q=0
for x in a.split(", ")[::-1]: #Read in reverse order, a="P: 01:00"
    for y, z in [x.split(": ")]:#Y="P", Z="00:00"
        s=
        lambda q,r,t:[t,sum([a*b for a,b in zip([60,1],map(int,q.split(':')))])]#Convert "01:01" to 61
        [r%4<2]#In case it's the first or fourth string calculate a new value, otherwise: return the original value
        +[0,240][r<2]#In case it's the last string: add 4 hours. Otherwise, leave it.
        if y=="I":j+=1;i=s(z,j,i)#Calculate for i
        else:q+=1;p=s(z,q,p)#Calculate for p
        l=[l,p+i-239][j+q<2]#Sets the last record. Since we read in reverse order, this should be the first one. We've added 4 hours though so remove those again
r=lambda d,e:("","%s: %02d:%02d, "%(d,(e/60)%24,e%60))[e>-1];#Print function, don't print anything when we have no value
p+=[1440,0][p>=l];i+=[1440,0][i>=l];    #Add a day if record is before the last record so we can correctly calculate the order
print("Next "+[r("I",i)+r("P",p),r("P",p)+r("I",i)][p<i][:-2])#print it and remove the last ","
Carra
sumber
1

PHP, 228 241 239 227 226 byte

membutuhkan PHP 7

Next<?foreach(explode(", ",$argv[1])as$d){[$m,$h,$i]=explode(":",$d);$x[$m][++$$m]=24+$h+$i/60;}foreach($x as$m=>$d)$r[$m]=$d[$$m-3]?:$d[$$m]-20;sort($r);foreach($r as$m=>$t)$o[]=" $m: ".date("i:s",$t%24*60);echo join(",",$o);

kerusakan

Next<?                              // print "Next"
foreach(explode(", ",$argv[1])as$d) // loop through string split by comma+space
{
    [$m,$h,$i]=explode(":",$d);         // separate drug, hours and minutes
    $x[$m][++$$m]=24+$h+$i/60;          // append time to array, track count in ${$m}
}                                       // (i.e. $P for drug "P" etc.)
foreach($x as$m=>$d)                // loop through drugs
    $r[$m]=                             // add time to result
        $d[$$m-3]                           // if more than 3 medications, use $$m-3
            ??$d[$$m]-20                    // else use last medication - 20 hours
    ;
sort($r);                           // sort results by time
foreach($r as$m=>$t)$o[]=" $m: "    // prepare for output: drug name and formatted time:
    .date("i:s",$t%24*60)           // use hrs as mins and mins as secs to avoid TZ problems
;
echo join(",",$o);                  // print
Titus
sumber
0

JavaScript (ES6), 246 byte

s=>s.split`, `.map(s=>(m[s[0]].unshift(t=s.replace(/\d+/,h=>(h=(1+h)%24)>9?h:`0`+h),s),l=l||t.slice(1)),l=0,m={I:[],P:[]})&&`Next `+[].concat(m.I[7]||m.I[0]||[],m.P[7]||m.P[0]||[]).sort((i,p)=>((i=i.slice(1))<l)-((p=p.slice(1))<l)||i>p).join`, `

Penjelasan:

Melilit setiap dosis, Idan Pdosis dipisahkan menjadi dua array. 4 jam juga ditambahkan ke setiap dosis, dan waktu itu juga disimpan. Array diisi secara terbalik untuk mendeteksi 8 entri lebih mudah. Waktu 4 jam setelah dosis pertama juga disimpan untuk digunakan selama penyortiran. Pada titik ini setiap larik dapat berada dalam satu dari tiga status:

  • 8 entri, dalam hal ini entri terakhir adalah dosis pertama, dan dosis berikutnya harus 24 jam setelah dosis ini (yaitu waktu yang sama besok)
  • 2, 4 atau 6 entri, dalam hal ini entri pertama adalah 4 jam setelah dosis terakhir, dan karena itu waktu dosis berikutnya
  • 0 entri, dalam hal ini kami concatentate [], yang akan diratakan dan karenanya dikeluarkan dari hasilnya

Setelah diekstraksi kali dosis berikutnya dari dua array, itu tetap memilah mereka ke dalam urutan. Ini dilakukan dengan membandingkannya dengan waktu 4 jam setelah dosis pertama. Jika salah satu dari dua kali sebelum waktu ini, ini harus merujuk besok, dan dosis itu datang terakhir. Kalau tidak, waktunya hanya dibandingkan secara langsung. (Agak merepotkan, obatnya sebelum waktunya, jadi aku harus mengupasnya untuk membandingkan dengan benar.)

Neil
sumber