휴일 두통


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

이것은 Paracetamol이 00:00과 04:00에, Ibuprofen이 02:00과 06:00에 찍은 것을 의미합니다.

출력 (업데이트 됨) :

다음과 같은 형식으로 각 약물의 다음 복용 시간을 나타내는 문자열 :

Next P: 08:00, I: 10:00
  • 출력 순서는 약물 복용 순서대로해야합니다. -Ibuprofen을 09:35와 Paracetamol 및 10:22에 가져 오려면 출력은Next I: 09:35, P: 10:22
  • 각 약물의 다음 복용량을위한 시간이 같은 경우 출력 순서는 중요하지 않습니다 : Next P: 08:00, I: 08:00ORNext I: 08:00, P: 08:00
  • 입력 문자열에서 하나의 약물 만 복용하는 경우 해당 약물 만 출력 문자열에 있어야합니다. Next P: 02:00

규칙 :

  • Paracetamol 'P'와 Ibuprofen 'I'의 두 가지 유형의 약물 만있을 것입니다.
  • 파라세타몰은 4 시간마다 1 회, 24 시간 이내에 최대 4 회 복용 할 수 있습니다.
  • 이부프로펜은 또한 4 시간마다 한 번씩, 24 시간 내에 최대 4 번 복용 할 수 있습니다.
  • 파라세타몰과 이부프로펜은 함께 또는 별도의 시간에 섭취 할 수 있습니다. 하나는 다른 하나의 복용량에 포함되지 않습니다.
  • 입력 문자열의 시간은 항상 연속적이지만 자정에 롤오버 될 수 있습니다 (23:00-> 03:00)
  • 입력 문자열의 시간이 24 시간을 초과하지 않습니다
  • 각 약물 당 최대 4 회 (총 8 회)
  • 입력은 항상 비어 있지 않으며 최소 하나의 약물과 한 번만 포함합니다

예 :

2 시간 간격으로 각각 2 회 용량 :

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

파라세타몰의 단일 용량

"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 바이트가 이깁니다.

최신 정보:

결과는 이제 Paracetamol과 Ibuprofen의 약어가 될 수 있습니다. PI


- I는 입력 및 출력 형식에 대한 몇 가지 활용이 좋을 것 메타 포스트
Gurupad Mamadapur

입력 시간에서 약물 유형 추출 @GurupadMamadapur 아마 출력하지만, 반 도전
Erresen

사람들이 제출물에 불필요한 길이를 추가하여 사람들이 파라세타몰과 이부프로펜을 약자로 만들 것을 권장합니다.
Cyoce

@Cyoce 네, 동의합니다. 솔루션을 직접 시도해 보았습니다. 실제로 약간 까다 롭습니다. 약식 출력을 허용하도록 규칙을 업데이트했습니다.
Erresen

@Lynn 동의 및 업데이트
Erresen

답변:


4

자바 스크립트 (ES6) 367 362 354 358 바이트

골프 버전 :

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}

언 골프 / 코멘트

// 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 변수가 재설정되지 않았고 테스트 중에주의를 기울이지 않았습니다. 알려 주셔서 감사합니다. 나중에 수정하겠습니다.
Luke

쉬운 수정으로 판명되었지만 4 바이트가 들었습니다.
Luke

1

파이썬 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

자바 스크립트 (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.