Bir kafenin gruplanmış çalışma saatlerini gösteren bir işaret


20

Muhtemelen çeşitli dükkanların kapılarında bu işaretleri gördünüz:

AÇILIŞ SAATLERİ

mon-fri 0900-1800
sat-güneş 1100-1530

Buradaki görev, tüm hafta boyunca açılış saatleri listesinden aynı açılış saatleriyle arka arkaya günleri gruplandırmak gibi bir işaret oluşturmaktır. Haftanın ardışık kabul edilenler için "etrafına sarıldığını" unutmayın.

Giriş:

  • Pazartesi'den başlayarak haftada her gün için açılış saatlerini temsil eden 7 eleman.
  • Her öğe XXXX-XXXX biçiminde bir dizedir
  • Örnek girdi:

    0900-1800 0900-1800 0930-1730 0930-1730 0900-1500 1100-1500 1100-1500
    
  • Girdiyi bir dizi olarak göndermeniz uygundur (örneğin, stdin'den okumuyorsanız bir işleve girdi olarak)

Çıktı:

  • Aynı açılış saatlerine sahip birbirini izleyen günlerin aralık olarak gösterildiği açılış saatlerinin listesi. Pazar (son gün) ve pazartesi (ilk gün) de birbirini izleyen günler olduğunu unutmayın.
  • Günün açılış saatlerinden önceki veya sonraki günlere benzer olmadığı bir gün kendi kendine yazdırılır
  • Günler üç küçük harf olarak belirtilir: pazartesiden önce güneş
  • Girişteki ilk öğenin, tonun yanındaki mon'e karşılık geldiğini unutmayın.
  • Çalışma saatleri girişteki gibi gösterilir
  • İki örnek

    mon-fri 0900-1800, sat-sun 1100-1500
    mon-wed 1030-1530, thu 100-1800, fri-sun 1200-1630
    
  • Çıktı sıralanmalıdır, böylece aralıklar günlerin haftadaki sıralarına göre görünür. Pazartesi ilk olmak için tercih edilir, ancak hafta sarıldığı için bir grupta ilk olmayabilir. Yani bu durumda, ton ilk aralıktır.

    tue-fri 0900-1800, sat-mon 1100-1500
    
  • Birbirini takip etmedikçe gruplandırmayın, burada çarşamba ve cuma günleri aynı çalışma saatlerine sahiptir, ancak kendileri tarafından listelenecek şekilde farklı çalışma saatleri ile bir Perşembe ile ayrılırlar.

    mon-tue 1000-1200, wed 0900-1500, thu 1000-1800, fri 0900-1500, sat-sun 1000-1500
    
  • Çıktı, buradaki örnekler olarak virgülle veya üstteki örnekte olduğu gibi bir yeni satırla ayrılabilir.

Test senaryoları

İlk satır girdi, ikinci satır beklenen çıktı

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

kurallar

Bu kod golf, bu yüzden bayttaki en kısa cevap kazanır.


7
Programlama Bulmacaları ve Kod Golf hoş geldiniz. Bu iyi bir mücadeledir; aferin! Gelecekte, bir meydan okuma göndermeden önce korumalı alanı kullanmanızı tavsiye ederim. (Bilirsin, ne olur ne olmaz ...)
wizzwizz4

1
Pazar ve Pazartesi günlerini birbiri ardına görmek bana tuhaf geliyor ...
Frédéric

1
Herhangi bir sunumun söz konusu temel davayı düzgün bir şekilde ele almaması durumunda "mon-sun" için bir test vakası olması gerektiğini hissediyorum.
Patrick Roberts

Yanıtlar:


7

JavaScript (ES6), 182 173 170 163 157 bayt

Edc65 yardımıyla 6 bayt kaydedildi

Girdiyi bir dizi dizesi olarak alır ve sonucu doğrudan konsola yazdırır:

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

Biçimlendirilmiş ve yorumlanmış

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)

Test senaryoları

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)kullanarak Dbazı byte kaydetmek gerekir bir işlevi yerine bir dizi olarak
edc65

@ edc65 - Maalesef ('Pazartesi'den önceki gün' aradığımızda) D()ile çağrılabilir -1, substr()ancak bu bir dizi ile çalışır ancak bir dizi ile çalışmaz.
Arnauld

@ edc65 - EDIT: yönteminizi başka bir düzeltme ile birleştirerek, bu kesinlikle bir kazanç. Teşekkürler!
Arnauld

3

Toplu, 334 bayt

@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

Girdiyi komut satırı parametreleri olarak alır, her grubu ayrı bir satıra çıkarır. Her günün saatini bir önceki günle karşılaştırarak, fgruptaki ilk gün holarak, o grubun saatiyle, gruptaki lson günle wve son grubun haftanın başına ne zaman kalacağını izleyerek çalışır . Uyumsuzluk bulunduğunda, hafta kaydırması geçerli olmadığı sürece önceki grup yazdırılır. Son olarak, tüm günler işlendiğinde, son grup herhangi bir hafta ambalajına ve tüm saatlerin çıktı alınmadan önce aynı olup olmadığına göre ayarlanır. 0yer dizisi olarak kullanılır, çünkü boş dizelerin Toplu Olarak karşılaştırması daha fazla bayttır.


2

Jöle , 87 84 80 75 bayt

  • @Dennis tür yardım ile 4bytes ( 'hızlı, "düz" ile kullanılan bir kesmek düzeltildi )

Eminim daha iyi bir yol var ama şimdilik:

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

TryiItOnline

Nasıl?

            “ḅạṄ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

JavaScript (ES6), 171 169 bayt

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)

Bir dizi olarak girişi alır ve konsola ayrı satırlarda çıkar. Bu neredeyse tam olarak Toplu cevabımın bir limanı; fAyrıca varsayılan olurken elbette boş bir dizeye artık varsayılan, lve whiç 'sun'(ben içine başlatmayı birleştirmek başardı çünkü gözcü değeri bana Toplu 3 bayt kaydedildi kullanarak set/a).


1

Bacon , 514 496 455 bayt

Aşağıdaki BASIC programı, girintisi ile gösterilmiştir. Ancak girinti olmadan 455 bayttan oluşur.

Fikir, zaman çizelgelerini ilişkilendirilebilir bir dizinin dizinleri olarak kullanmaktır. Sonra her gün bir biti temsil eder: Pazartesi = bit 0, Salı = bit 1, Çarşamba = bit 2 vb. İlişkilendirilebilir dizinin üyeleri için gerçek değerler, ikili OR kullanarak günlerin ilgili bitleriyle hesaplanır.

Bundan sonra, ilişkisel dizi üyelerinde bit 0 ile başlayan kaç ardışık bit bulunduğunu kontrol etmek önemlidir.

Bit 0 ve bit 6'nın ayarlanması durumunda, bir hafta kaydırma vardır. Bu durumda, bu başlangıç ​​konumunu ezberleyerek bir sonraki bit dizisinin başlangıcını aramaya başlayın. Diğer sekansları yazdırın ve bit 6'ya ulaşıldığında, gün aralığı önceden kaydedilmiş konumla sonlandırılmalıdır.

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'yi çağırmak için aşağıdaki çağrıları kullanma:

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

Çıktı :

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.