รวมระยะเวลา


18

ท้าทาย

เขียนรหัสที่สั้นที่สุดที่สามารถรวมระยะเวลาทั้งหมดที่ปรากฏใน stdin โปรแกรมต้องพิจารณาสตริงที่ตรงกับหนึ่งในรูปแบบต่อไปนี้และละเว้นส่วนที่เหลือ

    HH:MM:SS     (it will be interpreted as HH hours, MM minutes and SS seconds)        
    H:MM:SS      (it will be interpreted as H hours, MM minutes and SS seconds)
    MM:SS        (it will be interpreted as MM minutes, SS seconds)
    M:SS         (it will be interpreted as M minutes, SS seconds)

ตัวอย่างของสตริงที่ตรงกับรูปแบบที่แจกแจง:

    12:00:01  
    2:03:22  
    00:53  
    9:13

ผลลัพธ์ควรอยู่ในรูปแบบ

    HHh MMm SSs      (that means HH hours, MM minutes and SS seconds with non-zero-padding)

ตัวอย่าง

STDIN

ดูวิดีโอยินดีต้อนรับ
วิดีโอ: 10:37 นาที
ดูวิดีโอแนะนำหลักสูตร
วิดีโอ: 3:30 นาที ดูวิดีโอวิธีใช้ภาพรวมของบทเรียน
วิดีโอ: 9:13 นาที
ดูภาพรวมวิดีโอของวิธีใช้ระบบ Epsilen เพื่อแบ่งปันงานของคุณ
วิดีโอ: 03:15 นาที
ดูวิดีโอเพื่อเรียนรู้เกี่ยวกับการประเมินความพร้อมด้านวิชาการของรัฐเท็กซัส (STAAR)
วิดีโอ: 1:05:26 นาที

STDOUT

1 ชม. 32 ม. 1 วินาที


แล้วสตริง10:4:56ล่ะ? ตามข้อกำหนดปัจจุบันพวกเขาจะต้องถือว่าเป็น4m 56sส่วนหนึ่ง10จะถูกละเว้น คำถามเดียวกันเกี่ยวกับการเพิกเฉย10:12:7หมายความว่าอย่างไร หรือการจัดการของสตริงดังกล่าวสามารถกำหนดได้อย่างไร? 10m 12s7
Qwertiy

โปรแกรมควรพิจารณาระยะเวลาด้วยการเว้นระยะห่างในฟิลด์นาทีและวินาทีเท่านั้น ในตัวอย่างของคุณสตริง "10: 4: 56" จะถือว่าเป็น 4m 56s นอกจากนี้สตริง "10: 12: 7" จะถูกตีความว่าเป็น 10m 12s
Alfredo Diaz

แปลก แต่ก็โอเค :)
Qwertiy

คุณได้รับ1h 19m 18sผลลัพธ์อย่างไร 37+30+13+15+26==121, 10+3+9+3+5==30, ดังนั้นผมจึงคาดหวังว่า1==1 1h 32m 01sมีอะไรผิดปกติในตรรกะนี้? นอกจากนี้รูปแบบผลลัพธ์เช่นนั้นเป็นสิ่งที่คาดหวังใช่หรือไม่
Qwertiy

คุณพูดถูก ขออภัย: S
Alfredo Diaz

คำตอบ:


3

Pyth 105

K"smh"J"\D\D+|\d+:(?=\d:)|:\d\D"W:QJ1=Q:QJd;FN_msdCfn2lTm+*]0</k\:2msbck\:cQ)~k+d+hK_`%+NZ60=Z/N60=KtK;_k

ลองออนไลน์

เรื่องนี้ต้องมีการป้อนข้อมูลจาก STDIN ในทางเดียวกันว่าคำตอบ Javascript ไม่เป็นข้อความที่ยกมามีการขึ้นบรรทัดใหม่เป็น\ns

ตัวอย่าง:

"View the Welcome video.\nVideo: 10:37 min.\nView the video introduction to the course.\nVideo: 3:30 min. View the video of how to use the Lesson Overview.\nVideo: 9:13 min.\nView the video overview of how to use the Epsilen system to share your work.\nVideo: 03:15 min.\nView the video to learn about the State of Texas Assessment of Academic Readiness (STAAR).\nVideo: 1:05:26 min."

เอาท์พุต

1h 32m 1s

ตัวอย่างการทำงานกับวันที่ weirder:

"10:10:5 and 5:1:10 and 27 or 16: or 1:1:1 or 11:1\n"

เอาท์พุต

0h 11m 20s

(เฉพาะ 10:10 และ 1:10 เป็นเวลาที่ถูกต้อง)

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


ไอ้ผู้โชคดีที่ Pyth ก็มี regex เช่นกัน !
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer: D มันเป็นความเจ็บปวดที่แท้จริง ฉันคิดว่าการแนะนำให้เปลี่ยนพฤติกรรม "จับคู่" เป็นการเปลี่ยนแปลงตามอาร์กิวเมนต์ที่คุณให้ไว้ (ขณะนี้ตรวจสอบเฉพาะว่าไม่ใช่สตริง)
FryAmTheEggman

6

Javascript ES6, 138 ตัวอักษร

ฟังก์ชั่น 139

รับค่าสตริงเป็นอาร์กิวเมนต์และเขียนเอาต์พุตไปยังคอนโซล:

f=s=>(r=0,s.replace(/(\d\d?):(\d\d)(:(\d\d))?/g,(m,a,b,x,c)=>r+=x?+c+b*60+a*3600:+b+a*60),console.log("%dh %dm %ds",r/3600,r%3600/60,r%60))

โปรแกรม 138

prompt(r=0).replace(/(\d\d?):(\d\d)(:(\d\d))?/g,(m,a,b,x,c)=>r+=x?+c+b*60+a*3600:+b+a*60),console.log("%dh %dm %ds",r/3600,r%3600/60,r%60)

ทดสอบฟังก์ชั่น

f("View the Welcome video.\n\
Video: 10:37 min.\n\
View the video introduction to the course.\n\
Video: 3:30 min. View the video of how to use the Lesson Overview.\n\
Video: 9:13 min.\n\
View the video overview of how to use the Epsilen system to share your work.\n\
Video: 03:15 min.\n\
View the video to learn about the State of Texas Assessment of Academic Readiness (STAAR).\n\
Video: 1:05:26 min.")

เอาท์พุต

"1h 32m 1s"

ตกลง. ทำงานได้ดีใน Firefox Developer Edition 36.0a2 การจัดรูปแบบล้มเหลวเฉพาะใน Firefox 34.0
จัดการ

Promt ไม่อนุญาตให้มีหลายสตริง แต่ฉันสามารถเพิ่มเวอร์ชันด้วยการโทรพร้อมท์ () ในจำนวนตัวอักษรเดียวกัน :) ฉันยังย่อให้ 1 สัญลักษณ์)))
Qwertiy

@Optimizer วิธีการป้อนพวกเขา?
Qwertiy

@Optimizer การแทรกบรรทัดใหม่ไม่ทำงานใน FF 35.0 ของฉัน
Qwertiy

ฉันไม่สามารถทำงานได้ ฉันลองใน ideone.com ideone.com/56EHgV
Alfredo Diaz

4

JavaScript, ES6, 208 200 197 ไบต์

ฉันรู้ว่ามันยาวมาก แต่ฉันต้องการที่จะสำรวจคุณสมบัติล่าสุดของ ES6, ย้อนกลับ, ลดแผนที่, ฟังก์ชั่นลูกศรและความเข้าใจของอาร์เรย์ (ตัวดำเนินการแพร่กระจาย)

alert(prompt().match(/\d\d?:\d\d(:\d\d)?/g).map(x=>[...x.split(":").reverse(),z=0].slice(0,3)).reduce((a,b)=>b.map((y,i)=>+y+ +a[i])).map((x,i)=>(z=(t=x+z|0)/60,t%60+"smh"[i])).reverse().join(" "))

เพียงแค่เรียกใช้ตัวอย่างใน Firefox ล่าสุด

มันทำงานอย่างไร (ungolfed เล็กน้อย)

alert(                              // Alert the final result
  prompt()                          // Take the input via prompt
  .match(/\d\d?:\d\d(:\d\d)?/g)     // Match only correct time formats
  .map(                             // Map all matches using this method
    x=>[                            // Take each element as argument x
      ...x.split(":").reverse(),    // split x on ":" and reverse the array, then spread it
      z=0                           // put 0 as last element of return array
    ].slice(0,3)                    // Take only first 3 elements of the array
  ).reduce(                         // Reduce the result using this method
    (a,b)=>                         // Pairwise elements of the array
    b.map(                          // Map array b
      (y,i)=>~~y+~~a[i]             // Convert b[i] to b[i]+a[i]
    )                               // Now we have array like [SS, MM, HH]
  ).map(                            // Map these three values for carry over calculation
    (x,i)=>(
      t=x+z,                        // z contains carryover amount, add it to this value
      z=(t/60)|0,                   // Carryover is now floor(t/60)
      t%60+"smh"[i]                 // Remove overflow from t and add "s", "m" or "h"
    )                               // Now we have array like ["SSs", "MMm", "HHh"]
  ).reverse().join(" ")             // Reverse it and join by space
)

4

Bash (ด้วย grep, sed, awk และ date): 124 ไบต์, 120 ไบต์

เพียงไพพ์ข้อความลงในนี้:

grep -o '[:0-9]*'|sed 's/^[^:]*:[^:]*$/:\0/'|awk -F: '{T+=3600*$1+60*$2+$3}END{print"@"T}'|xargs date +"%Hh %Mm %Ss" -ud

มันทำงานอย่างไร

  • grep: เอาต์พุตสตริงจากอินพุตที่มีเท่านั้น 0123456789:
  • sed: เปลี่ยน MM: SS และ M: SS เป็น: M: SS
  • awk: คำนวณวินาทีสตริงว่างคือ 0
  • xargs: ส่งผ่านอินพุตเป็นอาร์กิวเมนต์จนถึงวันที่
  • date: แปลงวินาทีตั้งแต่ epoch (นำหน้าด้วย @) เป็นรูปแบบที่ต้องการ

ชั่วโมงนี้ไม่เกี่ยวข้องกับเขตเวลาของคุณใช่ไหม
Qwertiy

คุณพูดถูกดีจับ :) เพิ่มธง -u
pgy

3

Perl - 228 201

use integer;$h=0,$m=0,$s=0;while(<>){if(/(\d+:){1,2}\d+/){@a=reverse(split(/:/,$&));push @a,(0)x(3-@a);$s+=@a[0];$m+=@a[1];$h+=@a[2];}}$m+=$s/60;$s=$s%60;$h+=$m/60;$m=$m%60;print $h."h ".$m."m ".$s."s"

มันเป็นอัลกอริทึมเดียวกับของเครื่องมือเพิ่มประสิทธิภาพ (grep, split, reverse, add)

ฉันไม่ใช่ผู้เชี่ยวชาญ Perl ดังนั้นอาจลดจำนวนไบต์ได้

Ungolfed

use integer;                              # will do integer division
$h=0,$m=0,$s=0;
while(<>){
    if(/(\d+:){1,2}\d+/) {                # extract date formats
        @a = reverse(split(/:/,$&));      # split by ":" and reverse
        push @a,(0)x(3-@a);               # pad with zeros (minutes and hours)
        $s+=@a[0];                        # sum seconds
        $m+=@a[1];                        # sum minutes
        $h+=@a[2];                        # sum hours
    }
}

# convert seconds as minutes    
$m += $s / 60;
$s = $s % 60;

# convert minutes as hours
$h += $m / 60;
$m = $m % 60;

print $h."h ".$m."m ".$s."s";

สำหรับฉันมันแปลกที่จะเห็นวิธีการแก้ปัญหา perl นานกว่าจาวาสคริปต์หนึ่ง :)
Qwertiy

ถ้านับ Shebang ก็เป็นเรื่องปกติอีกต่อไป
จัดการ

@Qwertiy ฉันเห็นด้วย ความหวังของฉันคือกูรู Perl บางคนจะช่วยฉันแก้ไข
coredump

@ การทำงานทำไมมันถึงนับ
Qwertiy

@Qwertiy เพราะ coredump ลืมที่จะแยกออกจากการนับ : S อาจถูกลบออก (พร้อมกับmyคำหลักเหล่านั้นทั้งหมด)
จัดการ

3

Rebol - 174

n: charset"1234567890"a:[1 2 n]b:[":"2 n]c: 0 parse input[any[copy x[a b b](c: c + do x)| copy x[a b](c: c + do join"0:"x)| skip]]print reword"$1h $2m $3s"[1 c/1 2 c/2 3 c/3]

Ungolfed + หมายเหตุประกอบ:

n: charset "1234567890"                      ; setup \d regex equiv
a: [1 2 n]                                   ; parse rule for \d{1,2} 
b: [":" 2 n]                                 ; parse rule for :\d\d
c: 0                                         ; time counter

parse input [                                ; parse the input (STDIN)
                                             ; (no regex in Rebol)

  any [                                      ; match zero or more... 
                                             ;
      copy x [a b b] (c: c + do x)           ;  HH:MM:SS or H:MM:SS
                                             ;    - copy match to x
                                             ;    - increment time (c) by x
                                             ; OR
    | copy x [a b] (c: c + do join "0:" x)   ;  MM:SS or M:SS
                                             ;    - copy match to x
                                             ;    - "MM:SS" into "0:MM:SS" (join)
                                             ;    - then increment time (c)
                                             ; OR
    | skip                                   ;   no match so move through input
  ]
]

print reword "$1h $2m $3s" [1 c/1 2 c/2 3 c/3]

Rebol มาพร้อมกับtime!ประเภทข้อมูลของตัวเอง คุณสามารถดูว่าโค้ดข้างต้นใช้ประโยชน์จากสิ่งนี้ได้อย่างไรจากตัวอย่างด้านล่าง (จากภายในคอนโซล Rebol):

>> 0:10:37 + 0:3:30 + 0:9:13 + 0:3:15 + 1:05:26
== 1:32:01

;; Rebol would treat 10:37 as 10 hours & 37 minutes (and not MM:SS)
;; So we have to prefix the "0:"

>> join "0:" 10:37
== "0:10:37"

;; This is a string so we use Rebol DO evaluator to convert to time!

>> do join "0:" 10:37 
== 0:10:37

>> type? do join "0:" 10:37
== time!

>> hms: do join "0:" 10:37
== 0:10:37

>> hms/hour
== 0

>> hms/second
== 37

>> hms/minute
== 10

2

Groovy - 195

M=60
r=(System.in.text=~/((\d?\d):)?(\d\d):(\d\d)/).collect{it[2..4]*.toInteger().inject{s,i->(s?:0)*M+i}}.inject{s,i->s+=i}
f=[];(2..0).each{j=M**it;s=r%j;f<<(r-s)/j;r=s}
printf("%sh %sm %ss",f)

ฉันไม่สามารถหาวิธีบีบอัดได้มากขึ้น

Ungolfed

M=60
r=(System.in.text=~/((\d?\d):)?(\d\d):(\d\d)/).collect{  // extract dates
    it[2..4]*.toInteger().inject{ s,i ->                 // convert to seconds
        (s?:0)*M+i
    }
}.inject{s,i ->
    s+=i                                                 // sum seconds
}

f=[];
(2..0).each{                                             // convert to h,m,s
    j=M**it;
    s=r%j;
    f<<(r-s)/j;
    r=s
}

printf("%sh %sm %ss",f)

1

Mathematica 300 ตัวอักษร

แบบฝึกหัดเล็ก ๆ นี้ใช้รหัสเป็นจำนวนมากแม้แต่สำหรับ Mathematica แน่นอนมีวิธีที่มีประสิทธิภาพมากขึ้นในการทำเช่นนี้

แข็งแรงเล่นกอล์ฟ

สมมติว่าการป้อนข้อมูลที่ถูกเก็บไว้ในtxt,

n=NumberString;
t=ToExpression;
o=TimeObject;

QuotientRemainder[QuantityMagnitude[Plus@@((o[#]-o[{0,0,0}])&/@
(StringSplit[StringCases[w,{(n~~":"~~n~~":"~~n),(n~~":"~~n)}],":"]
/.{{a_,b_}:> {0,t@a,t@b},{a_,b_,c_}:> {t@a,t@b,t@c}}))],60]/.{h_,m_}:> 
Row[{h,"h ",IntegerPart@m,"m ",Round[60 FractionalPart[m]],"s "}]

มันทำงานอย่างไร (ใช้รหัส unGolfed):

1- ค้นหาเวลา

StringCases[txt,{(NumberString~~":"~~NumberString~~":"~~NumberString),
(NumberString~~":"~~NumberString)}];

{"10:37", "3:30", "9:13", "03:15", "1:05:26"}


2- แบ่งเป็นชั่วโมงนาทีวินาที

StringSplit[%,":"]/.{{a_,b_}:> {0,ToExpression@a,ToExpression@b},{a_,b_,c_}:> 
{ToExpression@a,ToExpression@b,ToExpression@c}}

{{0, 10, 37}, {0, 3, 30}, {0, 9, 13}, {0, 3, 15}, {1, 5, 26}}


3-Sum ครั้ง วัตถุเวลาเป็นเวลาของนาฬิกา การลบวัตถุหนึ่งครั้งจากวัตถุอื่นจะคืนค่าระยะเวลาในกรณีนี้ 92.0167 นาที QuantityMagnitudeลดหน่วยของการวัด

q=QuantityMagnitude[Plus@@((TimeObject[#]-TimeObject[{0,0,0}])&/@%)]

92.0167


4 แปลง 92.0167 นาทีเป็นชั่วโมงนาทีวินาที

QuotientRemainder[q,60]/.{h_,m_}:> Row[{h,"h ",IntegerPart@m,"m ",
Round[60 FractionalPart[m]],"s "}]

1 ชม. 32 ม. 1 วินาที


1

Perl, 146

รายการของฉันพิมพ์ผลลัพธ์ด้วยพื้นที่ต่อท้าย - ฉันหวังว่าไม่เป็นไร

while(<>){for(/(\d?\d(?::\d\d){1,2})/g){$m=1;for(reverse split/:/,$_){$t+=$m*$_;$m*=60}}}for('s','m'){$o=($t%60)."$_ $o";$t/=60}print int$t,"h $o"

หากเราสามารถสมมติได้ว่าจะมีเพียงครั้งเดียวต่อหนึ่งบรรทัดของอินพุตเราสามารถสับอักขระได้ 4 ตัว:

while(<>){if(/(\d?\d(:\d\d){1,2})/){$m=1;for(reverse split/:/,$&){$t+=$m*$_;$m*=60}}}for('s','m'){$o=($t%60)."$_ $o";$t/=60}print int$t,"h $o"

สิ่งเหล่านี้ทำงานโดยการสะสมวินาทีทั้งหมดที่ผ่านไปและจัดรูปแบบค่านั้นในภายหลัง

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