계산 시간표


14

타임 시트

직장에서 종종 시간표를 작성해야합니다. 이 작업은이를 돕기위한 코드 작성입니다.

입력

공백으로 구분 된 하루의 시작과 끝을 나타내는 약간 비표준 12 시간 시계에서 두 번. 세 번째 숫자는 점심 식사 시간을 나타냅니다. 예를 들어

9:14 5:12 30

즉, 오전 9시 14 분에 작업을 시작하고 오후 5시 12 분에 작업을 마치고 점심을 먹기 위해 30 분이 걸렸습니다.

당신은 가정 할 수 있습니다

  • 첫 번째 열의 시간은 00:00 (자정)부터 오후 1 시까 지이며 두 번째 열의 시간은 가장 이른 시간은 오후 1시 (오후 11시 59 분)입니다.
  • 점심 시간은 더 이상 근무일이 아닙니다!

입력 형식은 주어진 예와 같아야합니다.

직무

코드는이 트리플의 파일 (또는 표준 입력)을 읽어야하며, 각 출력에 대해 작업 한 시간을 나타냅니다. 이 출력은 시간 수를 나타냅니다. 위의 예는 다음과 같습니다.

7 시간 58 분-30 분-7 시간 28 분

산출

출력은 (전체) 시간과 분을 지정해야하며 59 분을 초과해서는 안됩니다. 즉, 2 시간 123 분을 출력 할 수 없습니다. 그 외에도, 코드는 편리한 인간 판독 형식으로 출력 할 수 있습니다.

10:00 1:00 30    --> 2hr 30min
12:59 1:00 0     --> 0hr 1min
00:00 11:59 0    --> 23hr 59min
10:00 2:03 123   --> 2hr 0min 

3
엄격한 입력 형식 ( :12 시간 제로 구분 된 시간)이 어떻게이 문제에 어떤 영향을 미치는지 알 수 없습니다 .
얽히고 설킨

3
@Shaggy 입력 형식을 파싱하는 것은 시간이 한두 문자 일 수 있기 때문에 문자 위치를 가정 할 수 없기 때문에 입력 형식을 구문 분석하는 것이 가장 어려운 과제였습니다.
Ryan

코드가 여러 줄을 읽어야합니까? 아니면 한 줄을 읽는다면 충분합니까?
Luis Mendo

1
예, 코드는 여러 줄을 허용해야합니다.
Anush

5
@ mbomb007 공감할 수는 있지만 입력 형식을 좋아하지 않는 것은 VTC의 이유가 아닙니다.
Okx

답변:



5

레티 나 0.8.2 , 83 바이트

\d+
$*
 (1+:)
 12$*1$1
+`1:
:60$*
(1*) :\1(1*)(1*) \2
$3
:(1{60})*(1*)
$#1hr $.2min

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 설명:

\d+
$*

입력을 단항으로 변환하십시오.

 (1+:)
 12$*1$1

중지 시간에 12 시간을 추가하십시오.

+`1:
:60$*

시간에 60을 곱하고 분을 더하십시오.

(1*) :\1(1*)(1*) \2
$3

정지 시간에서 시작 시간과 중단 시간을 뺍니다.

:(1{60})*(1*)
$#1hr $.2min

60으로 Divmod. (보다 지루한 출력 형식을 위해 5 바이트를 저장하십시오.)



4

파이썬 3, 161 바이트

나는 이것이 가장 작지 않다는 것을 알고 있지만 파일에서 읽습니다.

for l in open('t'):
    l=l[:-1].split(':')
    m=-int(l[0])*60+int(l[1][:2])+(int(l[1][3:])*60+720+int(l[2][:2])-int(l[2][2:]))
    print(f'{m//60}hr {m-(m//60*60)}min')

이 작업을 수행하기 위해 작업 표를 일시 중지하는 아이러니를 느끼고 있습니다 ...

파이썬 2.7, 133 바이트

의견에 대한 제안에 감사드립니다! 파이썬 2.7로 전환하면 기본적으로 정수 나누기이므로 몇 바이트가 더 절약됩니다.

for l in open('t'):i,h,l=int,60,l[:-1].split(':');m=-i(l[0])*h+i(l[1][:2])+(i(l[1][3:])*h+720+i(l[2][:2])-i(l[2][2:]));print m/h,m%60

python3과 동일한 접근 방식은 print 문으로 인해 기본적으로 135 바이트이며 부동 소수점 나누기입니다.

for l in open('t'):i,h,l=int,60,l[:-1].split(':');m=-i(l[0])*h+i(l[1][:2])+(i(l[1][3:])*h+720+i(l[2][:2])-i(l[2][2:]));print(m//h,m%60)

1
i=int시작 부분 에 넣고 세 번째 줄을 다음과 같이 변경 하면 4 바이트를 절약 할 수 있습니다.m=-i(l[0])*60+i(l[1][:2])+(i(l[1][3:])*60+720+i(l[2][:2])-i(l[2][2:]))
James

@DJMcMayhem 감사합니다! 나는 그것들을 단순화하는 방법을 생각하려고 노력했다.
Ryan

2
아주 좋은 첫 번째 대답, 프로그래밍 퍼즐 및 코드 골프에 오신 것을 환영합니다! 약간의 골프를 타기 위해 STDIN에서 입력을 받고 map(int,l[:-1].split(':'))여러 변환을 사용하여 int로 드롭하고 들여 쓰기 ;등을 교체하여 하나의 라이너로 모든 것을 축소 하여 몇 바이트를 절약 할 수 있습니다. 또한 다른 사용자가 골퍼 생활 중에 발견 한 깔끔한 트릭을 보려면 Python의 골프 팁을 방문하십시오 :).
Mr. Xcoder

1
또한 OP는 출력 형식에 대해 덜 제한적인 것처럼print(m,m%60) 보이 므로 충분 하다고 생각 합니다. (또한 사용주의 m%60대신에를 m-(m//60*60))
씨 Xcoder

@ Mr.Xcoder 감사합니다!
Ryan

4

C, 105 바이트

a,b,c,d,e;f(){for(;scanf("%d:%d%d:%d%d",&a,&b,&c,&d,&e);)a=(12+c-a)*60+d-b-e,printf("%d:%d ",a/60,a%60);}

완전히 간단합니다. 여기에서 온라인으로 사용해보십시오 .

언 골프 드 :

a, b, c, d, e; // start hours, minutes; end hours, minutes; break - all implicitly int
f() { // function - return type is implicitly int (unused)
    for(; scanf("%d:%d%d:%d%d", &a, &b, &c, &d, &e) ;) // until EOF is hit, read line by line
        a = (12 + c - a) * 60 + d - b - e, printf("%d:%d,", a / 60, a % 60); // calculate the minutes and store, then output separated: "h m"
}

제안 a,b,c,d;f(e)대신 a,b,c,d,e;f()하고 ;printf("%d:%d ",a/60,a%60))a=(12+c-a)*60+d-b-e;}대신;)a=(12+c-a)*60+d-b-e,printf("%d:%d ",a/60,a%60);
ceilingcat

4

볼프람 언어 125 119 111 바이트

i=Interpreter;j=IntegerPart;Row@{j[t=(i["Time"][#2<>"pm"]-i["Time"][#])[[1]]-#3/60],"hr ",j[60Mod[t,1]],"min"}&

사용자 202729 덕분에 8 바이트 절약

논리를 쉽게 따르기 위해 약어는 사용되지 않습니다.

Row[{IntegerPart[
 t = (Interpreter["Time"][#2 <> "pm"] - 
      Interpreter["Time"][#])[[1]] - #3/60], "hr ",
IntegerPart[60 Mod[t,1]], "min"}] &["9:00", "4:12", 20]

6 시간 51 분

Interpreter["Time"][#2 <> "pm"] 두 번째 매개 변수 뒤에 "pm"(이 경우 "4:12 pm")이 오는 시간으로 해석하여 TimeObject 해당 값을 .

-Interpreter["Time"][# <> "am"])[[1]] - #3/60]. #3세 번째 매개 변수는 20 분입니다. 빼기 부호는 교대 시간 끝에서 점심 시간 간격을 뺍니다. 조정 된 교대 시간 종료, 즉 사람이 점심 시간을 갖지 않은 경우 적용되는 교대 종료를 리턴합니다.

Interpreter["Time"][#] 첫 번째 매개 변수를 시간으로 해석합니다 (이 경우 "9:00"). TimeObject 하여 오전 9시에 해당 값을 .

조정 된 시프트 시간 끝에서 시프트 시작을 빼면 t시간 간격이 시간 단위로 표시됩니다. IntegerPart[t]작업 완료 시간 수를 반환합니다. IntegerPart[60 Mod[t,1]], "min"}]작업 한 추가 시간을 반환합니다.


예. 감사. 처음 Mod[x, 1]사용 된 것을 볼 수 있습니다.
DavidC

이 (삭제 된) 팁 에서 가져 왔습니다 . / 실제로 mod 1은 음수의 분수 부분과 다르게 동작합니다. / 수 Floor에 사용 IntegerPart?
user202729

Floor는 -6hr 52min내가 사용한 샘플 값 에 대해 설명 할 수없는 결과를 나에게 반환합니다 . 몇 시간 (그리고 분명히 몇 분) 동안 음의 값이 생성 된 이유를 이해하려면 이것을 조사해야합니다.
DavidC

3

자바 스크립트, 83 바이트 76 바이트

s=>(r=s.match(/\d+/g),r=(r[2]-r[0]+12)*60-r[4]-r[1]+ +r[3],(r/60|0)+':'+r%60)

아래 솔루션에서 내부 기능을 제거했습니다 (무엇을 생각 했습니까?). 출력 형식도 변경되었습니다.

온라인으로 사용해보십시오!


OLD : JavaScript, 112 바이트 111 바이트 110 바이트

s=>(t=(h,m,a)=>(a?12+h:h)*60+m,r=s.match(/\d+/g),r=t(+r[2],r[3]-r[4],1)-t(r[0],+r[1]),`${r/60|0}hr ${r%60}min`)

설명:

메인 함수 내에서, 우리는 세 번째 매개 변수가 진실이라면 12 시간을 시간 매개 변수에 추가하여주는 시간을 계산하는 데 도움이되는 다른 것을 정의하는 것으로 시작합니다.

(hours, minutes, addTwelve) =>
    (addTwelve? hours + 12: hours) * 60 + minutes

다음으로 문자열을 ' '또는':' 문자열의 모든 숫자의 배열의 결과 문자열 내부의 번호와 일치.

그런 다음 이전에 정의 된 함수를 사용하여 종료 시간과 시작 시간의 차이와 점심 시간을 빼는 (필요할 때 문자열을 숫자로 변환) 계산합니다.

마지막으로 결과 문자열을 생성합니다. hours는 정수 부분 r/60이고 minutes는 r%60입니다.

온라인으로 사용해보십시오!


@Jakob 저는 새로운 codegolf 사용자입니다. 나는 아직도 TIO를 포함하여 어떻게 작동하는지 모르겠습니다. 또한 이 의견에서 자바 스크립트를 사용하여 어떻게 접근 할 것인지 물었지만 아무도 응답하지 않았습니다.
ibrahim mahrir

@Jakob TIO 수정. 그리고 NodeJS를 사용하지 않고 브라우저 콘솔을 사용하고 있습니다. NodeJS는 TIO에 의해 추가되었습니다.
ibrahim mahrir

입력 방법이 합법적인지 확실하지 않지만 (이 질문은 불행히도 제한적입니다.) 좀 더 숙련 된 JS 골퍼가 필요할 수도 있습니다. 그러나 프로그램은 며칠 동안 입력 데이터를 지원해야합니다. 설명에서 매우 명확합니다.
Jakob

@Jakob 입력으로 더 많은 일을 사용해야한다면 함수가 배열을 받아들이고 map다음을 사용할 수 있습니다 a=>a.map(...). 내 대답에 5 바이트가 추가됩니다. 그러나 나는 여전히 내 의견에 대한 OP (또는 다른 사람) 응답을 기다리고 있습니다.
ibrahim mahrir

순수 JavaScript는 표준 입력 또는 파일에 액세스 할 수 없으므로 GUI 프롬프트를 사용하는 기본 방법을 사용하는 것이 좋습니다. codegolf.meta.stackexchange.com/a/2459/79343
OOBalance

3

파이썬 2 , 100 바이트

for I in open('x'):x,y,z,w,l=map(int,I.replace(':',' ').split());d=60*(12+z-x)+w-y-l;print d/60,d%60

온라인으로 사용해보십시오!

OP의 지시에 따라 텍스트 파일에서 여러 줄을 읽는 전체 프로그램. 한 줄만 구문 분석하는 함수는 10 바이트를 더 절약 할 수 있습니다.


1
이것은 또한 내 시도보다 더 읽기 쉽습니다!
Ryan

3

Java 10, 194191 바이트

u->{var s=new java.util.Scanner(System.in).useDelimiter("\\D");for(int i,a[]=new int[5];;i=(12+a[2]-a[0])*60+a[3]-a[1]-a[4],System.out.println(i/60+":"+i%60))for(i=0;i<5;)a[i++]=s.nextInt();}

Java에서 I / O는 고통 스럽다. 읽을 다음 입력 줄이 없으면 비정상적으로 종료됩니다. 여기에서 온라인으로 사용해보십시오 .

언 골프 드 :

u -> { // lambda taking a dummy input – we're not using it, but it saves a byte
var s = new java.util.Scanner(System.in).useDelimiter("\\D"); // we use this to read integers from standard input; the delimiter is any character that is not part of an integer
for(int i, a[] = new int[5]; ; // infinite loop; i will be used to loop through each line and to store the result in minutes between lines; a will hold the inputs
    i = (12 + a[2] - a[0]) * 60 + a[3] - a[1] - a[4], // after each line, calculate the result in minutes ...
    System.out.println(i / 60 + ":" + i % 60)) // ... and output the result in hours:minutes, followed by a newline
    for(i = 0; i < 5; ) // read the five integers on the current line ...
        a[i++] = s.nextInt(); // ... into the array
}


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.