ปวดหัววันหยุด


14

คำเตือน: อย่ารับคำแนะนำทางการแพทย์จากโพสต์นี้ หากคุณต้องการคำแนะนำทางการแพทย์ไปที่มืออาชีพที่มีคุณสมบัติเหมาะสม

ฉันปวดหัว. ฉันต้องการยาแก้ปวดหัว

ฉันจะบอกคุณในปริมาณที่น้อยที่สุดที่ฉันมีและคุณบอกฉันเมื่อฉันสามารถได้รับปริมาณต่อไปของฉันโดยไม่ต้องใช้ยาเกินขนาด

ฉันจะให้สายนี้กับคุณ: P: 00:00, I: 02:00, P: 04:00, I: 06:00

และคุณจะให้ฉันนี้: Next P: 08:00, I: 10:00

การป้อนข้อมูล:

สตริงแสดงเวลาที่ใช้ยาแต่ละชนิดในรูปแบบต่อไปนี้:

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

นี่หมายความว่ายาพาราเซตามอลถูกถ่ายเมื่อเวลา 00:00 น. และ 04:00 น. และยาไอเป้โพรเพนจะถูกนำมาใช้เวลา 02:00 น. และ 06:00 น

เอาท์พุท (ปรับปรุง):

สายที่มีเวลาที่ยาตัวต่อไปสามารถใช้ในรูปแบบต่อไปนี้:

Next P: 08:00, I: 10:00
  • คำสั่งส่งออกควรอยู่ในลำดับที่จะใช้ยา - หากใช้ไอบูโพรเฟนในเวลา 09:35 น. และพาราเซตามอลและ 10:22 แสดงว่าควรจะออกNext I: 09:35, P: 10:22
  • หากเวลาในการใช้ยาแต่ละครั้งเท่ากันลำดับการส่งออกไม่สำคัญ: Next P: 08:00, I: 08:00หรือNext I: 08:00, P: 08:00
  • หากมีการใช้ยาเพียงตัวเดียว (ในสายป้อนข้อมูล) ดังนั้นควรใช้ยานั้นในสายออกเท่านั้น: Next P: 02:00

กฎ:

  • จะมีเพียงสองชนิดของยา Paracetamol 'P' และ Ibuprofen 'I'
  • พาราเซตามอลสามารถรับประทานครั้งเดียวทุก 4 ชั่วโมงสูงสุด 4 ครั้งภายในระยะเวลา 24 ชั่วโมง
  • สามารถใช้ไอบูโพรเฟนทุก ๆ 4 ชั่วโมงสูงสุด 4 ครั้งภายในระยะเวลา 24 ชั่วโมง
  • พาราเซตามอลและไอบูโพรเฟนสามารถนำมารวมกันหรือแยกกันก็ได้ หนึ่งไม่นับต่อปริมาณของอีก
  • เวลาในสตริงอินพุตจะต่อเนื่องกันเสมอ แต่อาจเกลือกกลั้วเที่ยงคืน (23:00 -> 03:00)
  • เวลาในสายป้อนจะไม่เกิน 24 ชั่วโมง
  • สูงสุด 4 ครั้งสำหรับแต่ละยา (รวมสูงสุด 8)
  • การป้อนข้อมูลจะไม่ว่างเปล่าเสมอและมียาอย่างน้อยหนึ่งรายการและหนึ่งครั้ง

ตัวอย่าง:

สองปริมาณของแต่ละช่วงเวลาสองชั่วโมง:

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

Paracetamol ครั้งเดียว

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

ขนาดยาพาราเซตามอลสูงสุดภายใน 24 ชั่วโมงยาเดี่ยวไอบูโปรเฟน

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

กรณีทดสอบ:

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

นี่คือรหัสกอล์ฟดังนั้นคำตอบที่สั้นที่สุดจะชนะ int

UPDATE:

ผลลัพธ์สามารถเป็นตัวย่อของ Paracetamol และ Ibuprofen; PและI


ฉันยินดีที่จะใช้ประโยชน์จากรูปแบบการป้อนข้อมูลและผลลัพธ์ - เมตาโพสต์
Gurupad Mamadapur

@GurupadMamadapur เอาท์พุทบางที แต่การแยกเวลาและประเภทยาจากการป้อนข้อมูลเป็นครึ่งหนึ่งของความท้าทาย
Erresen

ฉันขอแนะนำให้คุณอนุญาตให้ผู้ใช้ย่อพาราเซตามอลและไอบูโพรเฟนเป็นเอาท์พุตเนื่องจากพวกเขาเพิ่มความยาวที่ไม่จำเป็นในการส่ง
Cyoce

@Cyoce ใช่ฉันเห็นด้วยลองแก้ปัญหาด้วยตัวเองและจริง ๆ แล้วมันค่อนข้างยุ่งยาก - อัปเดตกฎเพื่อให้มีตัวย่อ
Erresen

@Lynn ตกลงและอัปเดต
Erresen

คำตอบ:


4

JavaScript (ES6), 367 362 354 358 ไบต์

รุ่น Golfed:

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 / แสดงความคิดเห็น:

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

หากต้องการใช้งานให้เรียก F ด้วยสตริงเป็นอาร์กิวเมนต์ดังนี้

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

มันเยี่ยมมาก แต่ฉันมีปัญหาสองสามข้อ มันดูเหมือนว่าจะล้มเหลวถ้ามีเพียงหนึ่งชนิดของยาในการป้อนข้อมูลเช่น->F("P: 22:00") ReferenceError: q is not definedข้อมูลนี้จะทำงานหากมีการอ้างอิง P&I ก่อนหน้านี้ แต่มีรายละเอียดเก่าสำหรับ I.
Chris M

ขอบคุณ! ฉันเพิ่งทดสอบและคุณถูกต้องเกี่ยวกับข้อผิดพลาดของการอ้างอิง ฉันเดาว่าตัวแปร q ไม่ได้ถูกรีเซ็ตและฉันไม่ได้ให้ความสนใจเพียงพอในระหว่างการทดสอบ ขอบคุณที่แจ้งให้เราทราบฉันจะแก้ไขในภายหลัง
ลุค

กลายเป็นวิธีแก้ไขที่ง่าย แต่มีค่าใช้จ่าย 4 ไบต์
ลุค

1

Python 3 - 437 ไบต์

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

คำอธิบาย:

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 ไบต์

ต้องการ 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);

ชำรุด

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 ไบต์

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

คำอธิบาย:

วนรอบแต่ละโดสIและPปริมาณจะถูกแยกออกเป็นสองอาร์เรย์ 4 ชั่วโมงจะถูกเพิ่มเข้าไปในแต่ละยาและเวลาเหล่านั้นจะถูกบันทึกไว้ด้วย อาร์เรย์มีข้อมูลย้อนกลับเพื่อให้การตรวจจับ 8 รายการง่ายขึ้น เวลา 4 ชั่วโมงหลังจากเข็มแรกจะถูกบันทึกไว้สำหรับการใช้งานในระหว่างการเรียงลำดับ ณ จุดนี้แต่ละอาร์เรย์สามารถอยู่ในหนึ่งในสามสถานะ:

  • 8 รายการซึ่งในกรณีนี้รายการสุดท้ายคือเข็มแรกและเข็มถัดไปจะต้อง 24 ชั่วโมงหลังจากยานี้ (เช่นในเวลาเดียวกันในวันพรุ่งนี้)
  • 2, 4 หรือ 6 รายการซึ่งในกรณีนี้รายการแรกคือ 4 ชั่วโมงหลังจากเข็มสุดท้ายและดังนั้นเวลาของปริมาณถัดไป
  • 0 รายการซึ่งในกรณีนี้เราเชื่อมโยงกัน[]ซึ่งทำให้แบนและแยกออกจากผลลัพธ์

เมื่อทำการสกัดปริมาณครั้งถัดไปจากสองอาร์เรย์มันจะยังคงเรียงลำดับตามลำดับ ทำได้โดยการเปรียบเทียบกับเวลา 4 ชั่วโมงหลังจากเข็มแรก หากหนึ่งในสองครั้งคือก่อนเวลานี้สิ่งนี้จะต้องอ้างถึงในวันพรุ่งนี้และปริมาณนั้นจะคงอยู่ มิฉะนั้นเวลาจะถูกเปรียบเทียบโดยตรง (ค่อนข้างไม่สะดวกยาอยู่ก่อนเวลาดังนั้นฉันต้องเปลื้องมันเพื่อเปรียบเทียบอย่างถูกต้อง)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.