Tính tổng thời lượng


18

Thử thách

Viết mã ngắn nhất có thể tổng hợp tất cả thời lượng xuất hiện trong stdin. Chương trình chỉ phải xem xét các chuỗi khớp với một trong các mẫu sau và bỏ qua phần còn lại.

    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)

ví dụ về các chuỗi khớp với các mẫu liệt kê:

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

Đầu ra phải có dạng

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

Thí dụ

STDIN

Xem video Chào mừng.
Video: 10:37 phút.
Xem video giới thiệu về khóa học.
Video: 3:30 phút. Xem video về cách sử dụng Tổng quan Bài học.
Video: 9:13 phút.
Xem tổng quan về video về cách sử dụng hệ thống Epsilen để chia sẻ công việc của bạn.
Video: 03:15 phút.
Xem video để tìm hiểu về Đánh giá Sẵn sàng Học tập của Tiểu bang Texas (STAAR).
Video: 1:05:26 phút.

TUYỆT VỜI

1h 32m 1s


Còn chuỗi như thế 10:4:56nào? Theo đặc điểm kỹ thuật hiện tại họ phải được coi là 4m 56s, một phần 10sẽ bị bỏ qua. Cùng một câu hỏi về 10:12:7nó có nghĩa là 10m 12sbỏ qua 7? Hoặc xử lý các chuỗi như vậy có thể được thực hiện xác định?
Qwertiy

Chương trình chỉ nên xem xét thời lượng với phần đệm bằng 0 trong các trường phút và giây. Trong ví dụ của bạn, chuỗi "10: 4: 56" sẽ được coi là 4m 56s. Ngoài ra, chuỗi "10: 12: 7" sẽ được hiểu là 10m 12s.
Alfredo Diaz

Lạ, nhưng ok :)
Qwertiy

Làm thế nào bạn có được 1h 19m 18strong đầu ra? 37+30+13+15+26==121, 10+3+9+3+5==30, 1==1, Vì vậy tôi mong đợi 1h 32m 01s. Có gì sai trong logic này? Ngoài ra, định dạng đầu ra như vậy là một trong những dự kiến, phải không?
Qwertiy

Bạn đúng rồi. Xin lỗi: S
Alfredo Diaz

Câu trả lời:


3

Bình 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

Hãy thử trực tuyến.

Điều này yêu cầu đầu vào từ STDIN giống như cách mà câu trả lời Javascript thực hiện, như văn bản được trích dẫn với dòng mới là \ns.

Mẫu vật:

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

Đầu ra

1h 32m 1s

Ví dụ làm việc với ngày kỳ lạ:

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

Đầu ra

0h 11m 20s

(Chỉ 10:10 và 1:10 là thời gian hợp pháp)

Lý do chính khiến việc này kéo dài là vì Pyth sẽ không cho phép bạn trích xuất các trận đấu tích cực. Điều này thay vào đó phù hợp với tất cả mọi thứ không phải là thời gian hợp lệ và thay thế nó bằng một ký tự không gian. Sau đó, phân tách trên khoảng trắng chỉ để lại thời gian và một số con số bướng bỉnh. Số lượng vượt quá được loại bỏ bằng cách kiểm tra các :ký tự, số này sẽ bị xóa khỏi thời gian không hợp lệ. Điều này gần như chắc chắn có thể được đánh gôn hơn nữa;)


Khốn may mắn là Pyth có regex quá !
Tối ưu hóa

@Optimizer: D Đó là một nỗi đau thực sự. Tôi đang nghĩ đến việc đề xuất thay đổi hành vi "khớp" để thay đổi dựa trên đối số bạn đưa ra (hiện tại nó chỉ kiểm tra xem đó có phải là chuỗi không)
FryAmTheEggman

6

Javascript ES6, 138 ký tự

Chức năng, 139

Lấy chuỗi làm đối số và ghi đầu ra vào bàn điều khiển:

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

Chương trình, 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)

Kiểm tra chức năng

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

Đầu ra

"1h 32m 1s"

Đồng ý. Hoạt động tốt trong Firefox Developer Edition 36.0a2, định dạng chỉ bị lỗi trong Firefox 34.0.
manatwork

Promt không cho phép chuỗi đa dòng. Nhưng tôi có thể thêm phiên bản với lời gọi () trong cùng số ký tự :) Tôi thậm chí còn rút ngắn nó 1 ký hiệu)))
Qwertiy

@Optimizer Làm thế nào để nhập chúng?
Qwertiy

@Optimizer Chèn một dòng mới không hoạt động trong FF 35.0 của tôi.
Qwertiy

Tôi không thể làm cho nó hoạt động. Tôi đã thử nó trên ideone.com ideone.com/56EHgV
Alfredo Diaz

4

JavaScript, ES6, 208 200 197 byte

Tôi biết điều này là siêu dài, nhưng tôi muốn khám phá các tính năng mới nhất của ES6, đảo ngược, thu nhỏ bản đồ, các hàm mũi tên và hiểu mảng (toán tử trải rộng).

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

Chỉ cần chạy đoạn trích trong Firefox mới nhất.

Làm thế nào nó hoạt động (vô dụng một chút)

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 (với grep, sed, awk và ngày): 124 byte, 120 byte

Chỉ cần đặt văn bản vào đây:

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

Làm thế nào nó hoạt động

  • grep: đầu ra chuỗi từ đầu vào chỉ chứa 0123456789:
  • sed: biến MM: SS và M: SS thành: M: SS
  • awk: tính toán giây, chuỗi rỗng là 0
  • xargs: chuyển đầu vào làm đối số cho đến ngày
  • ngày: chuyển đổi giây kể từ epoch (tiền tố @) thành định dạng bắt buộc

Không phải giờ này có liên quan đến múi giờ của bạn sao?
Qwertiy

Bạn nói đúng, bắt tốt :) Đã thêm cờ -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"

Nó xảy ra giống như thuật toán của Trình tối ưu hóa (grep, split, Reverse, add).

Tôi không phải là chuyên gia về Perl, vì vậy có lẽ số lượng byte có thể giảm.

Ung dung

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

Đối với tôi, thật lạ khi thấy giải pháp perl dài hơn javascript :)
Qwertiy

Chà, nếu ngay cả shebang cũng được tính, thì bình thường sẽ dài hơn.
manatwork

@Qwertiy Tôi đồng ý. Hy vọng của tôi là một số guru Perl sẽ giúp tôi khắc phục điều đó.
coredump

@manatwork Tại sao lại tính?
Qwertiy

@Qwertiy, vì coredump đã quên loại trừ nó khỏi số đếm. : S có thể bị xóa (cùng với tất cả các mytừ khóa đó).
manatwork

3

Nổi loạn - 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 + chú thích:

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 đi kèm với time!kiểu dữ liệu riêng của nó . Bạn có thể xem cách mã trên sử dụng mã này từ ví dụ bên dưới (từ trong bảng điều khiển 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)

Tôi không thể tìm ra cách nén nó nhiều hơn.

Ung dung

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

Toán học 300 ký tự

Bài tập nhỏ này chiếm rất nhiều mã, ngay cả đối với Mathicala. Chắc chắn có nhiều cách hiệu quả hơn để làm điều này.

Chơi gôn

Giả sử rằng đầu vào được lưu trữ trong 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 "}]

Cách thức hoạt động (sử dụng mã unGolfed):

1-Tìm thời gian.

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

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


2-Chia thành giờ, phút, giây

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-Tổng số lần. Đối tượng thời gian là thời gian đồng hồ. Trừ một đối tượng một lần từ một đối tượng khác trả về một khoảng thời gian, trong trường hợp này là 92,0167 phút. QuantityMagnitudegiảm đơn vị đo.

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

92,0167


4-Chuyển đổi 92,0167 phút thành giờ, phút, giây.

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

1h 32m 1s


1

Perl, 146

Mục nhập của tôi in đầu ra với một khoảng trắng ở cuối - Tôi hy vọng điều đó ổn

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"

Nếu chúng ta có thể giả sử sẽ chỉ có một lần cho mỗi dòng đầu vào, chúng ta có thể cắt 4 ký tự:

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"

Chúng hoạt động bằng cách tích lũy tổng số giây trôi qua và định dạng giá trị đó sau đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.