카페의 그룹화 된 영업 시간을 보여주는 표시


20

여러 상점의 문에서 이러한 표시를 보았을 것입니다.

개관 시간

월-금 0900-1800
sat-sun 1100-1530

여기서의 임무는 일주일 내내 영업 시간 목록에서 동일한 영업 시간으로 연속 날짜를 그룹화하여 이와 같은 부호를 생성하는 것입니다. 연속적인 것으로 간주되는주는 "주변"입니다.

입력:

  • 월요일부터 시작하여 일주일에 하루의 영업 시간을 나타내는 7 가지 요소
  • 각 요소는 XXXX-XXXX 형식의 문자열입니다.
  • 입력 예 :

    0900-1800 0900-1800 0930-1730 0930-1730 0900-1500 1100-1500 1100-1500
    
  • 입력을 배열로 보내는 것이 좋습니다 (예를 들어 stdin에서 읽지 않으면 함수에 대한 입력으로)

산출:

  • 영업 시간 목록으로, 영업 시간이 동일한 연속 요일이 범위로 표시됩니다. 일요일 (마지막 날)과 월요일 (첫날)도 연속 일입니다.
  • 하루 전과 후의 영업 시간이 비슷한 날이 인쇄됩니다.
  • 요일은 세 개의 소문자로 지정됩니다. mon tue wed thu fri sat sun
  • 입력의 첫 번째 요소는 mon, tue 옆에 해당합니다.
  • 영업 시간은 입력과 같이 표시됩니다
  • 두 가지 예

    mon-fri 0900-1800, sat-sun 1100-1500
    mon-wed 1030-1530, thu 100-1800, fri-sun 1200-1630
    
  • 출력은 정렬되어야하므로 요일의 요일 순서대로 범위가 나타납니다. 월요일이 첫 번째가 바람직하지만 주가 줄 바꿈하여 그룹에서 첫 번째가 아닐 수 있습니다. 따라서이 경우 tue가 첫 번째 범위입니다.

    tue-fri 0900-1800, sat-mon 1100-1500
    
  • 연속하지 않는 한 그룹화하지 마십시오. 여기서 수요일과 금요일은 동일한 영업 시간을 갖지만 목요일에 다른 영업 시간으로 구분되어 자체적으로 나열됩니다.

    mon-tue 1000-1200, wed 0900-1500, thu 1000-1800, fri 0900-1500, sat-sun 1000-1500
    
  • 출력은 여기 예와 같이 쉼표로 구분되거나 맨 위 예와 같이 줄 바꿈으로 구분 될 수 있습니다.

테스트 사례

첫 번째 줄이 입력되고 두 번째 줄이 출력됩니다

0900-1800 0900-1800 0900-1800 0900-1800 0900-1800 1100-1500 1100-1500
mon-fri 0900-1800, sat-sun 1100-1500

0900-1800 0900-1800 0900-1800 0930-1700 0900-1800 1100-1500 1100-1500
mon-wed 0900-1800, thu 0930-1700, fri 0900-1800, sat-sun 1100-1500

1100-1500 0900-1800 0900-1800 0900-1800 0900-1800 1100-1500 1100-1500
tue-fri 0900-1800, sat-mon 1100-1500

1100-1500 1100-1500 0900-1800 0900-1800 0900-1800 0900-1800 1100-1500
wed-sat 0900-1800, sun-tue 1100-1500

1200-1500 1100-1500 0900-1800 0900-1800 0900-1800 0900-1800 1100-1500
mon 1200-1500, tue 1100-1500, wed-sat 0900-1800, sun 1100-1500

규칙

이것은 코드 골프이므로 바이트 단위의 최단 답변이 이깁니다.


7
프로그래밍 퍼즐과 코드 골프에 오신 것을 환영합니다. 이것은 좋은 도전입니다. 잘 했어! 앞으로는 챌린지를 게시하기 전에 샌드 박스를 사용하는 것이 좋습니다. (알다시피,
만약을 위해서

1
일요일과 월요일을 연속으로 갖는 것은 나에게 이상해 보인다 ...
Frédéric

1
제출물이 특정 기본 사례를 제대로 처리하지 못하는 경우를 대비하여 "mon-sun"에 대한 테스트 사례가 있어야한다고 생각합니다.
Patrick Roberts

답변:


7

자바 스크립트 (ES6) 182 173 170 163 157 바이트

edc65의 도움으로 6 바이트 절약

입력을 문자열 배열로 가져 와서 결과를 콘솔에 직접 인쇄합니다.

h=>{for(D="montuewedthufrisatsun".match(/.../g),d=c=i=j=0;j<8;y=d)h[i]==h[6]?i++:(v=h[d=(i+j++)%7])!=c&&(j>1&&console.log(D[x]+(x-y?'-'+D[y]:''),c),x=d,c=v)}

형식화 및 의견

h => {                               // input = list h of opening hours
  for(                               //
    D = "montuewedthufrisatsun"      // D = list of abbreviated names of days
        .match(/.../g),              //
    d =                              // d = current day of week
    c =                              // c = current opening hours
    i =                              // i = first day of week to process
    j = 0;                           // j = day counter
    j < 8;                           // stop when 7 days have been processed
    y = d                            // update y = last day of current day range
  )                                  //
  h[i] == h[6] ?                     // while the opening hours of day #i equal the opening
    i++                              // hours of sunday: increment i
  : (v = h[d = (i + j++) % 7]) != c  // else, if the new opening hours (v) of the current
    && (                             // day (d) doesn't match the current opening hours (c):
      j > 1 &&                       //   if this is not the first iteration:
        console.log(                 //     print:
          D[x] +                     //     - the first day of the current day range (x)
          (x - y ?                   //     - followed by either an empty string
            '-' + D[y]               //       or a '-' and the last day of the range
          : ''),                     //       (if they differ)
          c                          //     - the corresponding opening hours
        ),                           //   (endif)
      x = d,                         //   update x = first day of current day range
      c = v                          //   update c = current opening hours
    )                                // (endif)
}                                    // (end)

테스트 사례

let f =

h=>{for(D="montuewedthufrisatsun".match(/.../g),d=c=i=j=0;j<8;y=d)h[i]==h[6]?i++:(v=h[d=(i+j++)%7])!=c&&(j>1&&console.log(D[x]+(x-y?'-'+D[y]:''),c),x=d,c=v)}

f(["0900-1800", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500", "1100-1500"]);
console.log('-');
f(["0900-1800", "0900-1800", "0900-1800", "0930-1700", "0900-1800", "1100-1500", "1100-1500"]);
console.log('-');
f(["1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500", "1100-1500"]);
console.log('-');
f(["1100-1500", "1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500"]);
console.log('-');
f(["1200-1500", "1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500"]);


D='montuewedthufrisatsun'.match(/.../g)사용 D몇몇 바이트를 저장해야하는 대신 함수의 배열로
edc65

@ edc65-불행히도 D()호출 할 수 있습니다 -1( '월요일 전날'을 찾을 때), 작동 substr()하지만 배열에서는 작동하지 않습니다.
Arnauld

@ edc65-편집 : 당신의 방법을 다른 수정과 결합함으로써 이것은 확실히 승리입니다. 감사!
Arnauld

3

배치, 334 바이트

@echo off
set/af=l=w=0
set h=%7
call:l mon %1
call:l tue %2
call:l wed %3
call:l thu %4
call:l fri %5
call:l sat %6
call:l sun %7
if not %w%==0 set l=%w%
if %f%==0 set f=mon
call:l 0 0
exit/b
:l
if not %h%==%2 (
if %f%==0 (set w=%l%)else if %f%==%l% (echo %f% %h%)else echo %f%-%l% %h%
set f=%1
set h=%2
)
set l=%1

입력을 명령 줄 매개 변수로 사용하고 각 그룹을 별도의 줄에 출력합니다. 매일의 시간을 전날과 비교 f하여 그룹의 첫날, 해당 그룹 h의 시간, 그룹 l의 마지막 날 w, 마지막 그룹이주의 시작으로 다시 돌아가는 시간을 추적 하여 작동합니다 . 불일치가 발견되면 주 래핑이 적용되지 않는 한 이전 그룹이 인쇄됩니다. 마지막으로 모든 요일이 처리되면 마지막 그룹이 매주 줄 바꿈과 출력되기 전에 모든 시간이 동일한 지 여부가 조정됩니다. 0빈 문자열은 배치에서 비교하는 데 더 많은 바이트가 필요하므로 자리 표시 자로 사용됩니다.


2

젤리 , 87 84 80 75 바이트

  • @Dennis의 친절한 도움으로 4 바이트 ( '빠른 "플랫"으로 사용한 핵을 수정했습니다 )

더 좋은 방법이 있지만 지금은 확실합니다.

Ṫ2ị$€;@µ+\µżṙ1’$Ṗị“ḅạṄMḤ9\E¥LḃɓṅÐĿ;$»s3¤Q€j€”-
ṙ7Ḷ¤Œr'€Ėµ2ịLµÐṂḢ
ÇṪḢ€ż@ÇÑ$G

TryiItOnline

방법?

            “ḅạṄMḤ9\E¥LḃɓṅÐĿ;$» - compressed string "montuewedthufrisatsun"
                  v  v
Ṫ2ị$€;@µ+\µżṙ1’$Ṗị -- s3¤Q€j€”- - Link 1, getDayStrings: [offset, groupedList]
Ṫ                               - Tail: get groupedList
 2ị$€                           - second index of each: get group sizes, e.g. mon-thu is 4
     ;@                         - concatenate (reversed arguments): prepend with offset
       µ                        - monadic chain separation
        +\                      - cumulative reduce with addition: start indexes
          µ                     - monadic chain separation
           ż                    - zip with
               $                - last two links as a monad
            ṙ1                  -     rotated left by one
              ’                 -     decrement:  end indexes
                Ṗ               - pop: remove last one, it's circular
                 ị              - index into
                        ¤       - last two links as a nilad
                    --          -     compressed string of weekdays (as shown at the top)
                      s3        -     split into 3s
                        Q€      - unique items for each: [tue,tue] -> [tue]
                          j€    - join each with
                            ”-  - literal string "-"

ṙ7Ḷ¤Œr'€Ėµ2ịLµÐṂḢ - Link 2: CalculateGroupingData: list of time strings
   ¤              - last two links as a nilad
ṙ                 -    rotate time strings list left by
 7Ḷ               -    range 7: [0,1,2,3,4,5,6]
       €          - for each
    Œr            -     run length encode
      '           -     flat - i.e. don't vectorise
        Ė         - enumerate [[1,[groupsFromMon]],[2,[groupsFromTue], ...]
         µ        - monadic chain separation
              ÐṂ  - filter for minimum of
             L    -     length of
          2ị      -     item at index 2: The number of groupings
                Ḣ - head: get the first occurring minimal (i.e Mon, or Tue, ...)

ÇṪḢ€ż@ÇÑ$G - Main link: list of time strings
Ç          - call last link (1) as a monad: get the offset and grouping
 Ṫ         - tail: get the grouping
  Ḣ€       - head each: get the time information
        $  - last two links as a monad
      Ç    -      call last link (1) as a monad: get the offset and grouping
       Ñ   -      call the next link as a monad: get the day strings
    ż@     - zip (with reversed arguments)
         G - arrange as a group (performs a tabulation to nicely align the result)

1

자바 스크립트 (ES6), (171) 169 바이트

a=>a.map((e,d)=>(d='montuewedthufrisatsun'.substr(d*3,3),e!=h&&(f?o(f):w=l,f=d,h=e),l=d),f='',l=w='sun',h=a[6],o=f=>console.log((f==l?l:f+'-'+l)+' '+h))&&o(f||'mon',l=w)

입력을 배열로 취하여 별도의 행으로 콘솔에 출력합니다. 이것은 거의 정확히 내 배치 답변의 포트입니다. f나는 또한 기본 수있는 동안 물론 빈 문자열를 기본으로, l그리고 w'sun'(내가으로 초기화를 병합 할 수 있었다 때문에 감시 값이 나에게 일괄 3 바이트를 저장 사용 set/a).


1

베이컨 , 514 496 455 바이트

아래의 기본 프로그램은 들여 쓰기와 함께 표시됩니다. 그러나 들여 쓰기가 없으면 455 바이트로 구성됩니다.

아이디어는 시간 스케줄을 연관 배열에 대한 인덱스로 사용하는 것입니다. 그런 다음 각 요일은 월요일 = 비트 0, 화요일 = 비트 1, 수요일 = 비트 2 등의 비트를 나타냅니다. 연관 배열의 멤버에 대한 실제 값은 이진 OR을 사용하여 일의 각 비트에 의해 계산됩니다.

그 후, 비트 0부터 시작하여 연관 배열 멤버에 몇 개의 연속 비트가 있는지 확인해야합니다.

비트 0과 비트 6도 설정된 경우 일주일 랩이 있습니다. 이 경우 다음 비트 시퀀스의 시작을 찾고 시작 위치를 기억하십시오. 나머지 시퀀스를 인쇄하고 비트 6에 도달하자마자 날짜 범위가 미리 암기 된 위치로 끝나야합니다.

LOCAL n$[]={"mon","tue","wed","thu","fri","sat","sun"}
GLOBAL p ASSOC int
SUB s(VAR t$ SIZE a)
    FOR i = 0 TO a-1
        p(t$[i])=p(t$[i])|BIT(i)
    NEXT
    LOOKUP p TO c$ SIZE o
    b=e=0
    REPEAT
        FOR i=0 TO o-1
            IF p(c$[i])&BIT(b) THEN
                IF b=0 AND p(c$[i])&65=65 THEN
                    WHILE p(c$[i])&BIT(b)
                        INCR b
                    WEND
                    e=b
                    BREAK
                FI
                ?n$[b];
                r=b
                REPEAT
                    INCR b
                UNTIL NOT(p(c$[i])&BIT(b))
                IF e AND b>6 THEN
                    ?"-",n$[e-1];
                ELIF b-r>1 THEN
                    ?"-",n$[b-1];
                FI
                ?" ",c$[i]
            FI
        NEXT
    UNTIL b>6
    FREE p
ENDSUB

다음 호출을 사용하여 SUB를 호출하십시오.

s("0900-1800", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500", "1100-1500")
PRINT "======"
s("0900-1800", "0900-1800", "0900-1800", "0930-1700", "0900-1800", "1100-1500", "1100-1500")
PRINT "======"
s("1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500", "1100-1500")
PRINT "======"
s("1100-1500", "1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500")
PRINT "======"
s("1200-1500", "1100-1500", "0900-1800", "0900-1800", "0900-1800", "0900-1800", "1100-1500")

출력 :

mon-fri 0900-1800
sat-sun 1100-1500
======
mon-wed 0900-1800
thu 0930-1700
fri 0900-1800
sat-sun 1100-1500
======
tue-fri 0900-1800
sat-mon 1100-1500
======
wed-sat 0900-1800
sun-tue 1100-1500
======
mon 1200-1500
tue 1100-1500
wed-sat 0900-1800
sun 1100-1500
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.