Mal di testa festivo


14

Avvertenza: NON consultare un medico da questo post. Se desideri una consulenza medica, vai da un professionista qualificato.

Ho mal di testa. Ho bisogno di pillole per il mal di testa.

Ti dirò le ultime dosi che ho avuto e tu mi dirai quando posso prendere la mia dose successiva, senza sovradosaggio.

Ti darò questa stringa: P: 00:00, I: 02:00, P: 04:00, I: 06:00

E mi darai questo: Next P: 08:00, I: 10:00

Ingresso:

Stringa che rappresenta i tempi di assunzione di ciascun farmaco, nel seguente formato:

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

Ciò significa che il paracetamolo è stato assunto alle 00:00 e alle 04:00 e l'ibuprofene è stato assunto alle 02:00 e alle 06:00

Output (aggiornato):

String con il tempo che può essere preso il prossimo di ogni farmaco, nel seguente formato:

Next P: 08:00, I: 10:00
  • L'ordine di uscita dovrebbe essere nell'ordine in cui il farmaco deve essere assunto. - Se l'ibuprofene deve essere assunto alle 09:35 e al paracetamolo e alle 10:22, l'output dovrebbe essereNext I: 09:35, P: 10:22
  • Se i tempi per la dose successiva di ciascun farmaco sono gli stessi, l'ordine di uscita non ha importanza: Next P: 08:00, I: 08:00ORNext I: 08:00, P: 08:00
  • Se viene assunto solo un farmaco (nella stringa di input), solo quel farmaco dovrebbe essere nella stringa di output: Next P: 02:00

Regole:

  • Ci saranno sempre e solo due tipi di farmaci, il paracetamolo 'P' e l'ibuprofene 'I'.
  • Il paracetamolo può essere assunto una volta ogni 4 ore, un massimo di 4 volte in un periodo di 24 ore.
  • L'ibuprofene può anche essere assunto una volta ogni 4 ore, un massimo di 4 volte in un periodo di 24 ore.
  • Il paracetamolo e l'ibuprofene possono essere assunti insieme o in momenti separati. Uno non conta per il dosaggio dell'altro.
  • I tempi nella stringa di input saranno sempre consecutivi, ma potrebbero scorrere oltre la mezzanotte (23:00 -> 03:00)
  • I tempi nella stringa di input non dureranno più di 24 ore
  • Massimo 4 volte per ciascun farmaco (8 max in totale)
  • L'input sarà sempre non vuoto e conterrà almeno un farmaco e una volta

Esempi:

Due dosi di ciascuna a intervalli di due ore:

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

Singola dose di paracetamolo

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

Dose massima di paracetamolo entro 24 ore, dose singola di ibuprofene

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

Casi test:

"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"

Questo è il golf del codice, quindi vince la risposta più breve int byte.

AGGIORNARE:

L'output può ora essere abbreviazioni di Paracetamol e Ibuprofen; PeI


Sarei bello avere un po 'di leva sul formato di input e output - meta post
Gurupad Mamadapur

L'output di @GurupadMamadapur forse, ma l'estrazione dei tempi e del tipo di farmaco dall'input è metà della sfida
Erresen,

Ti consiglierei di consentire alle persone di abbreviare il paracetamolo e l'ibuprofene in uscita poiché aggiungono una lunghezza non necessaria agli invii
Cyoce,

@Cyoce sì, sono d'accordo, sto provando una soluzione da solo ed è in realtà un po 'complicato - ho aggiornato le regole per consentire un output abbreviato
Erresen,

@Lynn ha accettato e aggiornato
Erresen il

Risposte:


4

JavaScript (ES6), 367 362 354 358 byte

Versione golfizzata:

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}

Ungolfed / ha commentato:

// 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;
}

Per usarlo, chiama F con la stringa come argomento in questo modo:

F("P: 04:00, I: 06:00")

Questo è fantastico, ma ho avuto un paio di problemi. Sembra fallire se c'è un solo tipo di pillola nell'input, ad es. F("P: 22:00")-> ReferenceError: q is not defined. Questo input verrà eseguito se in precedenza P&I è stato referenziato, ma con vecchi dettagli per I.
Chris M

Grazie! L'ho appena testato e hai ragione sull'errore di riferimento. Immagino che la variabile q non sia ripristinata e non ho prestato sufficiente attenzione durante il test. Grazie per avermelo fatto sapere, lo aggiusterò più tardi.
Luca,

Si è rivelato essere una soluzione semplice, ma mi è costato 4 byte.
Luca,

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

Spiegazione:

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 ","

1

PHP, 228 241 239 227 226 byte

richiede 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);

abbattersi

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

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`, `

Spiegazione:

Passando sopra ogni dose, il IeP dosi sono separate in due array. Ad ogni dose vengono anche aggiunte 4 ore e anche questi tempi vengono salvati. Le matrici sono popolate al contrario per facilitare il rilevamento di 8 voci. Il tempo 4 ore dopo la prima dose viene anche salvato per l'uso durante l'ordinamento. A questo punto ogni array può trovarsi in uno dei tre stati:

  • 8 voci, nel qual caso l'ultima voce è la prima dose e la dose successiva deve essere 24 ore dopo questa dose (cioè domani alla stessa ora)
  • 2, 4 o 6 voci, nel qual caso la prima voce è 4 ore dopo l'ultima dose, e quindi l'ora della dose successiva
  • 0 voci, nel qual caso concateniamo [], che viene appiattito e quindi escluso dal risultato

Dopo aver estratto i tempi di dose successivi dai due array, resta da ordinare in ordine. Questo viene fatto confrontandoli con il tempo 4 ore dopo la prima dose. Se una delle due volte è precedente a questa, ciò deve riferirsi a domani e quella dose arriva per ultima. Altrimenti, i tempi vengono semplicemente confrontati direttamente. (Abbastanza inopportuno, il medicinale è in anticipo, quindi devo toglierlo per confrontarlo correttamente.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.