Additionnez les durées


18

Défi

Écrivez le code le plus court qui peut additionner toutes les durées de temps qui apparaissent dans le stdin. Le programme ne doit considérer que les chaînes qui correspondent à l'un des modèles suivants et ignorer le reste.

    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)

exemples de chaînes qui correspondent aux modèles énumérés:

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

La sortie doit être de la forme

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

Exemple

STDIN

Visionnez la vidéo de bienvenue.
Vidéo: 10:37 min.
Visionnez la vidéo d'introduction au cours.
Vidéo: 3h30 min. Visionnez la vidéo expliquant comment utiliser l'aperçu de la leçon.
Vidéo: 9:13 min.
Visionnez la présentation vidéo de l'utilisation du système Epsilen pour partager votre travail.
Vidéo: 03:15 min.
Visionnez la vidéo pour en savoir plus sur l'évaluation de l'état de préparation scolaire de l'État du Texas (STAAR).
Vidéo: 1:05:26 min.

STDOUT

1h 32m 1s


Et les cordes comme 10:4:56? Selon les spécifications actuelles, elles doivent être traitées comme 4m 56s, une partie 10sera ignorée. Même question à propos de 10:12:7ce que cela signifie 10m 12savec l'ignorance de 7? Ou la gestion de telles chaînes peut-elle être définie par l'implémentation?
Qwertiy

Le programme ne doit considérer que les durées de temps avec un remplissage nul dans les champs des minutes et des secondes. Dans votre exemple, la chaîne "10: 4: 56" sera traitée comme 4m 56s. La chaîne "10: 12: 7" sera également interprétée comme 10m 12s.
Alfredo Diaz

Étrange, mais ok :)
Qwertiy

Comment avez-vous obtenu 1h 19m 18sla sortie? 37+30+13+15+26==121, 10+3+9+3+5==30, 1==1, Donc je pense 1h 32m 01s. Quel est le problème dans cette logique? De plus, un tel format de sortie est celui qui est attendu, n'est-ce pas?
Qwertiy

Tu as raison. Désolé: S
Alfredo Diaz

Réponses:


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

Essayez-le en ligne.

Cela nécessite une entrée de STDIN de la même manière que la réponse Javascript, comme un texte cité avec des retours à la ligne comme \ns.

Échantillon:

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

Production

1h 32m 1s

Exemple de travail avec des dates plus étranges:

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

Production

0h 11m 20s

(Seuls le 10:10 et le 1:10 sont des temps légitimes)

La raison principale pour laquelle cela est si long est que Pyth ne vous permettra pas d'extraire des correspondances positives. Cela correspond à la place à tout ce qui n'est pas une heure valide et le remplace par un caractère espace. Ensuite, le fractionnement sur des espaces ne laisse que des temps et des nombres capricieux. Les nombres excédentaires sont supprimés en vérifiant les :caractères, qui auront été supprimés des périodes non valides. Cela pourrait certainement être approfondi;)


Heureux bâtard que Pyth a aussi des regex !
Optimizer

@Optimizer: D C'était une vraie douleur cependant. Je pense à suggérer de changer le comportement "is match" pour changer en fonction de l'argument que vous lui donnez (actuellement, il vérifie uniquement qu'il ne s'agit pas d'une chaîne)
FryAmTheEggman

6

Javascript ES6, 138 caractères

Fonction, 139

Prend la chaîne comme argument et écrit la sortie sur la console:

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

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

Test de fonction

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

Production

"1h 32m 1s"

D'accord. Fonctionne bien dans Firefox Developer Edition 36.0a2, le formatage échoue uniquement dans Firefox 34.0.
manatwork

Promt n'autorise pas les chaînes multilignes. Mais je peux ajouter une version avec prompt () appeler dans le même nombre de caractères :) Je le raccourcis même 1 symbole)))
Qwertiy

@Optimizer Comment les saisir?
Qwertiy

@Optimizer L'insertion d'une nouvelle ligne ne fonctionne pas dans mon FF 35.0.
Qwertiy

Je ne peux pas le faire fonctionner. Je l'ai essayé sur ideone.com ideone.com/56EHgV
Alfredo Diaz

4

JavaScript, ES6, 208 200 197 octets

Je sais que c'est super long, mais je voulais explorer les dernières fonctionnalités d'ES6, inverser, réduire la carte, les fonctions fléchées et la compréhension du tableau (opérateur d'étalement).

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

Exécutez simplement l'extrait dans un dernier Firefox.

Comment ça marche (un peu golfé)

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 (avec grep, sed, awk et date): 124 octets, 120 octets

Il suffit de diriger le texte dans ceci:

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

Comment ça fonctionne

  • grep: sort les chaînes de l'entrée ne contenant que 0123456789:
  • sed: transforme MM: SS et M: SS en: M: SS
  • awk: calcule les secondes, la chaîne vide est 0
  • xargs: passe l'entrée comme argument à ce jour
  • date: convertit les secondes depuis l'époque (préfixée par @) au format requis

Cette heure n'est-elle pas liée à votre fuseau horaire?
Qwertiy

Vous avez raison, belle prise :) Ajout du drapeau -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"

Il se trouve que c'est le même algorithme que l'Optimizer (grep, split, reverse, add).

Je ne suis pas un expert Perl, donc le nombre d'octets peut être réduit.

Non golfé

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

Quant à moi, c'est étrange de voir une solution perl plus longue que celle de javascript :)
Qwertiy

Eh bien, même si le shebang est compté, il est normal qu'il soit plus long.
manatwork

@Qwertiy, je suis d'accord. J'espère que certains gourous de Perl m'aideront à résoudre ce problème.
coredump

@manatwork Pourquoi ça compte?
Qwertiy

@Qwertiy, car coredump a oublié de l'exclure du décompte. : S Peut être supprimé (avec tous ces mymots clés).
manatwork

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]

Non golfé + annoté:

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 est livré avec son propre time!type de données. Vous pouvez voir comment le code ci-dessus utilise cela à partir de l'exemple ci-dessous (à partir de la console 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)

Je ne peux pas comprendre comment le compresser davantage.

Non golfé

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 caractères

Ce petit exercice a pris beaucoup de code, même pour Mathematica. Il existe certainement des moyens plus efficaces de le faire.

Golfé

En supposant que l'entrée est stockée dans 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 "}]

Comment cela fonctionne (en utilisant du code non golfé):

1-Trouvez les temps.

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

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


2-Découpez en heures, minutes, secondes

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-Additionnez les temps. Les objets temps sont des heures d'horloge. La soustraction d'un objet temporel d'un autre renvoie une durée, dans ce cas 92,0167 minutes. QuantityMagnitudesupprime l'unité de mesure.

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

92.0167


4-Convertir 92,0167 minutes en heures, minutes, secondes.

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

1h 32m 1s


1

Perl, 146

Mon entrée imprime la sortie avec un espace de fin - j'espère que c'est ok

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"

Si nous pouvons supposer qu'il n'y aura qu'une seule fois par ligne d'entrée, nous pouvons couper 4 caractères:

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"

Ceux-ci fonctionnent en accumulant le nombre total de secondes écoulées et en formatant cette valeur par la suite.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.