# Workweek completion

I work from Monday to Friday. I start my day at 8:12 and have lunch from 12:00 to 12:42. My workday ends at 16:30.

If you are wondering why 8:12 and 12:42:

• 8:00 is the goal, but I never actually make it
• 12:42 because I take 45 minute breaks, but this works better for the challenge spec

### Challenge

Write a function or full program that returns the smallest fraction of time I have worked and still need to work for the current week. The interval you must use is 6 min.

Each day has 76 six-minute intervals

### Examples

Monday 02:00 -> 0/1
Monday 08:24 -> 1/190
Monday 18:00 -> 1/5
Saturday xx:xx -> 1/1

Monday 08:17 -> 0/1
Monday 08:18 - Monday 08:23 -> 1/380


### Scoring

Shortest code win but golfing languages get a *3 multiplier.

• Pyth
• CJam
• GolfScript

Edit: I've lowered the modifier, but I will not remove it. Some languages have some overhead like variable declaration and other long keywords; function ,return, etc. I don't want to discourage someone from writing the skeleton of a method in their chosen language because it's longer than a complete CJam answer.

• perl,j,k,piet,APL etc. – Optimizer Jun 25 '15 at 11:02
• 4.5 is a very high multiplier. Python and Mathematica (and some other) languages can easily come withing 2-3 x of CJam for non-trivial challenges. – Optimizer Jun 25 '15 at 11:45
• -1 for arbitrary language bias. – Dennis Jun 25 '15 at 14:17
• The point here should only be code size on similar challenges as this is code-golf. – Optimizer Jun 25 '15 at 15:19
• I'm voting to close this question as off-topic because the incomplete description/list of what constitutes a golfing language makes it impossible to objectively score solutions. – Mego Jan 13 '16 at 17:57

# C++: 204 bytes

g++ 4.9.2

int f(char*a){int d=380,n=*a-'M'?*a-'W'?*a-'F'?*a-'S'?a[1]-'u'?3:1:5:4:2:0,m,h;sscanf(a,"%*s%d:%d",&h,&m);h=(m=h*10+m/6-82)<38?m:m>83?76:m-7;n=min(d,n*76+max(h,0));m=__gcd(n,d);printf("%d/%d\n",n/m,d/m);}


Live demo

Same as old answer, just replaced 5 ternary conditions of form a==b?c:d with a-b?d:c to save 1 byte each condition. Rest of the explanation remains same.

# C++: 210 bytes

int f(char*a){int d=380, n=*a=='M'?0:*a=='W'?2:*a=='F'?4:*a=='S'?5:a[1]=='u'?1:3,m,h;sscanf(a,"%*s%d:%d",&h,&m);h=(m=h*10+m/6-82)83?76:m-7;n=min(d,n*76+max(h,0));m=__gcd(n,d);printf("%d/%d\n",n/m,d/m);}

Live demo

# Explanations

int f(char* a) {  // Function name. Returning int instead of void to save one char
int d=380;  // denominator

int n= *a == 'M' ?  // Number of days
0 :  // Monday
*a == 'W' ?
2 :  // Wednesday
*a == 'F' ?
4 :  // Friday
*a == 'S' ?
5 :  // Saturday or Sunday
a[1] == 'u' ?
1 :  // Tuesday
3;   // Thurdays

int m, h;  // Minutes and hours

sscanf(a, "%*s%d:%d", &h, &m);  // %*s - Skip day, %d:%d - Read hour and min

h= (
m=h*10+m/6-82  // Calculate (h * 60 + m) / 6 - (8 * 60 + 12) / 6
) < 38 ? m       // Before lunch
: m>83 ? 76  // If it is past end of day 76) clamp to 76
:m-7; // After lunch, subtract lunch time

n = min(d,                  // numerator (n) can not be more than denominator
n * 76 + max(h,0) ); // Number of day * units (6 min) per day + units of current day (from time) clamped to 0 if negative

m=__gcd(n, d);  // Find gcd to get normalized form of rational number

printf("%d/%d\n", n/m, d/m);  // Print the result
}  // Function ends

• Welcome to PPCG! Correct answers are great - but you'll garner more votes if you explain what's clever about your solution. There are various ways to do that; one that's popular is a formatted, annotated version of the same code. Any chance of obliging? Thanks. It's good to see you here; happy golfing! – Toby Speight Jun 25 '15 at 15:08
• @TobySpeight Thanks for the welcome words and the suggestion. I looked at a few posts to understand what you mean. I will add similar description in my code also. – Mohit Jain Jun 25 '15 at 16:47
• @TobySpeight Done – Mohit Jain Jun 25 '15 at 17:04
• Where does __gcd come from? – rink.attendant.6 Jun 25 '15 at 19:01
• @rink.attendant.6 std::__gcd is exposed in C++ library in gcc compilers. – Mohit Jain Jun 26 '15 at 5:05

# Python - 195 bytes

Very simple, uses fractions library for simplest terms. Had a Pyth solution, but the *4.5 was too much.

from fractions import*
z=raw_input()
Q=input()
n=("SMTWTF".index(z[0])-1if z[0]!='T'else"uh".index(z[1])*2+1)*76
Q=max(Q[0]*10+Q[1]/6-82,0)
print Fraction(n+(min(Q, 38)if Q<45 else min(Q-7,76)),380)


Takes input in two lines, the time as a tuple, since no input format was specified.

## PHP, 254 bytes

This is just a port of my JavaScript answer. Due to PHP's odd behaviour with ternary operators, parentheses are necessary.

function z($a,$b){return$b?z($b,$a%$b):$a;}function f($q){preg_match('/(\w+) (\d+):(\d+)/',$q,$i);$t=$i[3]/6+$i[2]*10-82;$t=$i[0][0]=='S'?380:strpos('neduit',$i[1][2])*76+($t<0?0:($t>82?76:($t>45?$t-7:($t>38?38:$t))));$g=z($t,380);return$t/$g.'/'.(380/\$g);}


## JavaScript (ES6), 201 191 bytes

f=i=>{z=(a,b)=>b?z(b,a%b):a,i=/(\w+) (\d+):(\d+)/.exec(i),t=+i[3]/6+i[2]*10-82;t=i[0][0]=='S'?380:'neduit'.indexOf(i[1][2])*76+(t<0?0:t>82?76:t>45?t-7:t>38?38:t);g=z(t,380);return+t/g+'/'+380/g}


### ECMAScript 5: 223 214 bytes

function f(i){z=function(a,b){return!b?a:z(b,a%b)},i=/(\w+) (\d+):(\d+)/.exec(i),t=+i[3]/6+i[2]*10-82;t=i[0][0]=='S'?380:'neduit'.indexOf(i[1][2])*76+(t<0?0:t>82?76:t>45?t-7:t>38?38:t);g=z(t,380);return+t/g+'/'+380/g}

Ungolfed
function f(input) {
var greatestCommonDivisor = function (a, b) {
// From https://stackoverflow.com/a/17445304/404623
return !b ? a : greatestCommonDivisor(b, a % b);
};

// Get input from string
var input = /(\w+) (\d+):(\d+)/.exec(input);

// Parse time relative to day
var t = Number(input[3]) / 6 + Number(input[2]) * 10 - 82;

var m, g, divisor;

if (input[0][0] == 'S') {
// Weekend - week is over
m = 380;
} else {
if (t < 0) {
// Before start of work day
m = 0;
} else if (t > 82) {
// After end of work day
m = 76;
} else if (t > 45) {
// After lunch
m = t - 7;
} else if (t > 38) {
// During lunch
m = 38;
} else {
m = t;
}

// Indices correspond to third letter of day of week
m += 'neduit'.indexOf(input[1][2]) * 76;
}

// Find common divisor
divisor = greatestCommonDivisor(m, 380);

// Return value
return m / divisor + '/' + 380 / divisor;
}


function f(i) {
z = function(a, b) {
return !b ? a : z(b, a % b)
}, i = /(\w+) (\d+):(\d+)/.exec(i), t = +i[3] / 6 + i[2] * 10 - 82;
t = i[0][0] == 'S' ? 380 : 'neduit'.indexOf(i[1][2]) * 76 + (t < 0 ? 0 : t > 82 ? 76 : t > 45 ? t - 7 : t > 38 ? 38 : t);
g = z(t, 380);
return t / g + '/' + 380 / g
}

['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'].forEach(function(d) {
var str;
for (var h = 8; h < 17; h++) {
for (var m = 0; m < 60; m += 6) {
str = d + ' ' + (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m);
document.body.innerHTML += str + ' -> ' + f(str) + '<br>';
}
}
});

Assumes that Sunday is the last day of the week.