ASCII Takvim Planlayıcısı


11

Etkinliklerin bir listesi ve başlangıç ​​saati / tarihi göz önüne alındığında, etkinlikleri uygun günlerde gösteren bir ASCII sanat takvimi çıktılayın. Tüm etkinliklerin aynı ayda olması garanti edilir, aynı gün iki etkinlik olmaz ve tüm etkinliklerin takvim kutusuna sığacağı garanti edilir.

Takvim her kutunun sol üst köşesindeki tarih var, kutular ile çevrili boyunda 5 boşluklarla geniş 9 boşluklar vardır -ve |. Haftanın günü için iki harfli kısaltma ilk satırın üzerinde ortalanır ve haftalar Pazar ile başlar.

Örneğin, aşağıdaki etkinlikler göz önüne alındığında:

10/5/2018 - 9:00am - Sandbox calendar challenge
10/9/2018 - 9:00am - Post challenge to main
10/10/2018 - 10:00am - Profit
10/31/2018 - 7:30pm - Halloween party

İlgili takvimin çıktısını alın:

    Su        Mo        Tu        We        Th        Fr        Sa     
-----------------------------------------------------------------------
|         |1        |2        |3        |4        |5        |6        |
|         |         |         |         |         |9:00am   |         |
|         |         |         |         |         |Sandbox  |         |
|         |         |         |         |         |calendar |         |
|         |         |         |         |         |challenge|         |
-----------------------------------------------------------------------
|7        |8        |9        |10       |11       |12       |13       |
|         |         |9:00am   |10:00am  |         |         |         |
|         |         |Post     |Profit   |         |         |         |
|         |         |challenge|         |         |         |         |
|         |         |to main  |         |         |         |         |
-----------------------------------------------------------------------
|14       |15       |16       |17       |18       |19       |20       |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
-----------------------------------------------------------------------
|21       |22       |23       |24       |25       |26       |27       |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
|         |         |         |         |         |         |         |
-----------------------------------------------------------------------
|28       |29       |30       |31       |         |         |         |
|         |         |         |7:30pm   |         |         |         |
|         |         |         |Halloween|         |         |         |
|         |         |         |party    |         |         |         |
|         |         |         |         |         |         |         |
-----------------------------------------------------------------------

Açıklamalar

  • Zamanlama sözcükleri ([A-Za-z] + ile eşleşen) aralarında tek bir boşlukla sınırlandırılacaktır (örnekte olduğu gibi).
  • Metni sözcük sınırları üzerinde bölmek yeterlidir. Kelimeleri tirelemeye gerek yok.
  • Şubat bir pazar günü artık olmayan bir yılda başlarsa, yalnızca dört takvim satırınız olur.
  • 31 günlük bir ay (örneğin, Ağustos) haftanın sonlarına doğru başlarsa altı takvim satırı çıkarmanız gerekebilir.

G / Ç ve Kurallar

  • Kodunuz , uygun şekilde artık yıllar dahil olmak üzere, en az Gregoryen takvimi arasındaki 0001-01-01ve 9999-12-31içindeki tarihleri işlemelidir. Örneğin, girdi verilirse 2016-02-13 9:00am Test, çıktı takviminde 29 Şubat olmalıdır.
  • Giriş tarihi formatı istenilen herhangi bir formatta olabilir. ISO 8601, bir datetimenesne, özellikle biçimlendirilmiş bir dize, vb. Giriş ayrıştırma bu zorluğun ilginç bir parçası değildir.
  • Giriş ve çıkış herhangi bir uygun yöntemle yapılabilir .
  • Karakterlerin uygun şekilde hizalanması şartıyla, öndeki / sondaki yeni satırlar veya diğer boşluklar isteğe bağlıdır.
  • Tam bir program veya bir işlev kabul edilebilir. Bir işlev varsa, çıktıyı yazdırmak yerine döndürebilirsiniz.
  • Çıktı konsola olabilir, bir dize listesi olarak döndürülebilir, tek bir dize olarak döndürülebilir, vb.
  • Standart boşluklar yasaktır.
  • Bu bu nedenle her zamanki golf kuralları geçerlidir ve en kısa kod (bayt cinsinden) kazanır.

1.) Etkinlik adlarını sözcük sınırları üzerinde bölmek zorunda mısınız? 2.) Pazar günü başlayan bir şubesiz şubeniz olduğunda, sadece 4 satırınız var mı? 3.) Ayı göstermek için 6 satıra ihtiyacınız olduğunda (ör. Ağustos Cumartesi başlıyor) ne olur?
nedla2004

İlgili (daha kolay).
Arnauld

@ nedla2004 1) Evet, kelime sınırları işe yarayacak. 2) Doğru, 4 sıra. 3) Takviminizin 6 satır göstermesi gerekir. Açıklamalarda düzenleme yapacağım.
AdmBorkBork

@Arnauld Evet, bu adil bir varsayım
AdmBorkBork

1
1752-09-02 - 09:00am - Wife's Birthday Tomorrow (14th!)
ngm

Yanıtlar:


10

JavaScript (ES8), 380321 320 bayt

Girişi şu şekilde alır (y,m,e):

  • y yıl
  • m 0 endeksli aydır
  • eanahtarları gün olan ve değerleri [hour, task]biçimdeki olaylar olan bir nesnedir
(y,m,e)=>`SuMoTuWeThFrSa
`.split(/(..)/).join`    `+(p='-'.repeat(d=71)+`
`)+(g=i=>++d<1|(x=G`getMonth`==m)|i%7?`|${[h,t]=e[d]||E,o=[x*d,h],q=E,t&&t.split` `.map(s=>q=(u=q?q+' '+s:s)[9]?o.push(q)&&s:u),[...o,q][r%5]||E}`.padEnd(10)+(++i%7?E:`|
`+(++r%5?(d-=7,E):p))+g(i):E)(E=r='',d=-(G=s=>new Date(y,m,d)[s]())`getDay`)

Çevrimiçi deneyin!

Nasıl?

Koddaki bazı önemli kısımlar aşağıdadır.

Başlık

Başlık satırı şunlarla oluşturulur:

'SuMoTuWeThFrSa\n'.split(/(..)/).join`    `

Bir split()yakalama grubu içeren normal bir ifadeyle kullanıldığında, bu grup çıktı dizisine dahil edilir. Bu durumda, verir:

[ '', 'Su', '', 'Mo', '', 'Tu', '', 'We', '', 'Th', '', 'Fr', '', 'Sa', '\n' ]

Bu diziye 4 boşlukla katılıyoruz:

'    Su        Mo        Tu        We        Th        Fr        Sa    \n'

tam da istediğimiz şey bu.

Ay yapısı

Gymd

G = s => new Date(y, m, d)[s]()

x

Olay biçimlendirme

Bir olayı biçimlendirmek için aşağıdaki kod kullanılır.

[h, t] = e[d] || E,           // split the content of the event into h and t
o = [x * d, h],               // set the first 2 entries of o[]: day and hour
q = E,                        // we start with q = empty string
t &&                          // skip this .map() loop entirely if t is not defined
t.split` `                    // split the string on spaces
.map(s =>                     // for each word s:
  q =                         //   update q:
    (u = q ? q + ' ' + s : s) //     u is the concatenation of the previous string with
                              //     the new word, separated by a space if needed
    [9] ?                     //     if u is more than 9 character long:
      o.push(q)               //       push the previous string in o[]
      && s                    //       and reset q to s
    :                         //     else:
      u                       //       update q to u
),                            // end of map()
[...o, q][r % 5]              // append the last pending part to o[] and extract the
|| E                          // relevant row; or use an empty string by default

3

Python 2 , 326 324 315 312 307 bayt

import calendar as c,textwrap as t
c.setfirstweekday(6)
y,m,e=input()
print' Su Mo Tu We Th Fr Sa\n'.replace(' ',' '*8)[4:]+'-'*71
for w in c.monthcalendar(y,m):
 for l in zip(*[[d or'',a]+(t.wrap(b,9)+['']*3)[:3]for d in w for a,b in[e.get(d,'  ')]]):print'|'+'|'.join('%-9s'%v for v in l)+'|'
 print'-'*71

Çevrimiçi deneyin!

Arnauld'un JS cevabı ile aynı giriş :

Girişi şu şekilde alır (y,m,e):

  • y yıl
  • m 1 endeksli aydır
  • eanahtarları gün olan ve değerleri (hour, task)biçimdeki olaylar olan bir nesnedir

3

Kömür , 215 206 bayt

Sθ≔I⪪§⪪θ ⁰/η≔⁻⁺×¹²⊟η⊟η²η≔EE²⁻ηι﹪Σ⟦÷ι⁴⁸⁰⁰±÷ι¹²⁰⁰÷ι⁴⁸÷ι¹²÷×¹³⁺⁴﹪ι¹²¦⁵⟧⁷η≔±⊟ηζ≔⁺²⁸﹪⁺⊟ηζ⁷ε⭆⪪SuMoTuWeThFrSa²◨◧ι⁶χ↓←⁷¹W‹ζε«↘F⁷«P↓⁵→≦⊕ζF⁼Iζ§⪪θ/⁰«≔⪪θ - θ≔⟦ω◨§θ¹¦⁹⟧δF⪪⊟θ ⊞δ⎇‹⁺L§δ±¹Lμ⁹⁺⁺⊟δ μμP⪫δ¶Sθ»◨×››ζ⁰›ζεIζ⁹»↓⁵←⁷¹

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Tarihleri ​​g / a / yyyy biçiminde alır. Açıklama:

Sθ

İlk olayı girin.

≔I⪪§⪪θ ⁰/η

Tarihi ayıklayın ve /s'de bölün .

≔⁻⁺×¹²⊟η⊟η²η

MÖ 1 Mart'tan bu yana aylara dönüştürün. Hem önümüzdeki ayın hem de şu anki ayın ilk gününü hesaplamak istiyorum ve aylar içinde çalışmak ayları ve yılları ayrı tutmak ve yıl sonunda taşımaktan daha kolaydır, ayrıca saymaya başlamama da izin verir Ocak ayı yerine Mart ayında başlayan ve Zeller'in uyumu için gerekli olan aylar.

≔EE²⁻ηι﹪Σ⟦÷ι⁴⁸⁰⁰±÷ι¹²⁰⁰÷ι⁴⁸÷ι¹²÷×¹³⁺⁴﹪ι¹²¦⁵⟧⁷η

Gelecek ayın ilk günü ve bu ayın haftasının gününü ayıklamak için değiştirilmiş bir Zeller uyumu kullanın. Temel kısım, bir önceki yılın 30 Ekim'den belirli bir ayın 1'ine kadar olan gün sayısının, m = 4Mart ve bir m = 14sonraki yılın Ocak ayı için formülle verildiği gerçeğine dayanmaktadır m * 153 / 5, ancak 140'ı çıkarabiliriz, çünkü yalnızca haftanın gününü önemsiyorum. Sonra yıl nedeniyle ayarlama yapmak kalır; her yıl bir gün ekler, her 4 yılda bir ek gün ekler, her 100. yılda bir gün çıkarılır ve her 400. yılda bir gün tekrar eklenir. (Aylar içinde çalıştığım için bu değerlerin hepsi 12 ile çarpılır.) Daha doğrusu bu bana doğrudan Pazar endeksli bir hafta açısından cevap verir (normalde ayın gününü ekler ve Cumartesi günleri saymaya başlarsınız).

≔±⊟ηζ

Haftanın gününü alın ve ayın geçerli günü olarak kaydedin.

≔⁺²⁸﹪⁺⊟ηζ⁷ε

İki ayın haftasından itibaren aydaki gün sayısını hesaplayın.

⭆⪪SuMoTuWeThFrSa²◨◧ι⁶χ

Gün başlıklarını çıktılar.

↓←⁷¹

Üst satırını yazdırın -.

W‹ζε«

Ayın son gününe kadar döngü çıktı.

İmleci bir sonraki satırın başına götür.

F⁷«

Bir seferde 7 gün işleyin.

P↓⁵→

|Soldaki s sütununu yazdırın .

≦⊕ζ

Ayın geçerli gününü artırın.

F⁼Iζ§⪪θ/⁰«

Ayın geçerli günü geçerli etkinliğin günü ise, ...

≔⪪θ - θ

... etkinliğin diğer bölümlerini çıkarın ...

≔⟦ω◨§θ¹¦⁹⟧δ

... zamanı 9 boşluğa doldurun ve boş bir dizeyi liste olarak kaydedin, ...

F⪪⊟θ 

... boşluklardaki açıklamayı ayır ve üzerlerine geç, ...

⊞δ⎇‹⁺L§δ±¹Lμ⁹⁺⁺⊟δ μμ

... eğer uygunsa, her kelimeyi bir önceki kelimeye eklemek; ...

P⪫δ¶

... zaman ve açıklama çıktı ( Pδçalışmıyor, bir Kömür hatası olabilir?), ...

Sθ»

... ve sonraki etkinliği girin.

◨×››ζ⁰›ζεIζ⁹»

Ayın geçerli günü 1 ile ayın son günü arasındaysa, çıktı alın, aksi takdirde ertesi güne geçmek için yeterli alan çıkın.

↓⁵←⁷¹

Hafta sonunda |s'nin sağ sütununu ve s'nin alt satırını yazdırın -.


Belki de ayrıntılı TIO kodunuzda atladım, ancak Zeller'in uyum uygulamalarınızın tamamlandığından emin misiniz? Mart-Aralık ayları için doğru gibi görünüyor, ancak Ocak ve Şubat ayları year-1yerine yerine kullanılmalı yearve month+12yerine kullanılmalıdır month. Yoksa bu 05AB1E cevabımda bahsettiğim ve Wikipedia'nınkine eşit olan algoritmayı basitleştirdiniz mi?
Kevin Cruijssen

@KevinCruijssen Temelde bu yüzden 1BM'den bu yana geçen ay sayısını hesaplıyorum, ancak bir yorumda daha fazla açıklamak çok karmaşık.
Neil

1
@KevinCruijssen Açıklamamı güncelledim; Umarım faydalı bulursun.
Neil

Teşekkürler! Bu gerçekten hoş bir değiştirilmiş formül ve şimdi bunun ardındaki mantığı anlıyorum. Açıklamaya eklediğiniz için çok teşekkürler. Benden +1.
Kevin Cruijssen

2

Java (JDK) , 538 439 428 425 bayt

Muhtemelen şimdiye kadar yayınladığım en uzun Code Golf çözümü. Hala buradan golf oynamaya çalışıyor ama bu bir mücadele.

Giriş biçimini değiştirerek ve bazı regex ayrıştırmalarını ve çeşitli bitlerden başka bir 11 kullanarak 99 bayt vurmayı başardı.

Kevin sayesinde 3 ekstra bayt kapalı!

Diğer cevaplardan ilham alarak, formattaki zamanı ve olayı temsil eden bir Dize'ye yıl, ay ve günler haritası olarak girdi alır <time>-<event>.

(y,m,M)->{var C=java.util.Calendar.getInstance();C.set(y,m-1,1);String r=",Su,,Mo,,Tu,,We,,Th,,Fr,,Sa\n".replace(",","    "),e;for(int x=C.getActualMaximum(5),l=0,b=0,j,c,i=0;i<7;r+="\n",l+=b<=x&++i>6?7*(i=1):0)for(j=0;j<71;b=l+j/10+2-C.get(7),e=(e=M.get(b))!=null?e.replaceAll("([^-]{1,9})(-| |$)","$1-")+" - ":null,r+=e=i%6<1?"-":c<1?"|":c*i<2&b>0&b<=x?b+"":c<2&e!=null?e.split("-")[i-2]:" ",j+=e.length())c=j%10;return r;}

Çevrimiçi deneyin!


Ungolfed

(y,m,M)->{                                              // Lambda taking input as a year, month and map
  var C=java.util.Calendar.getInstance();               // Creates a new Calendar instance
  C.set(y,m-1,1);                                       // Sets the calendar to the first of the month in the given year    
  String r=",Su,,Mo,,Tu,,We,,Th,,Fr,,Sa\n"              // Creates the header row by replacing
    .replace(",","    "),e;                             // commas with 4 sets of spaces

  for(                                                  // Creates 7 rows for a calendar row
      int x=C.getActualMaximum(5)                       // Stores last day of the month
      ,l=0,b=0,j,c,i=0;i<7;                             // Initialises other integers
      r+="\n",                                          // Add new line each row
      l+=b<=x&++i>6                                     // If end of a calendar row is reached, and current day is less than max
        ?7*(i=1)                                        // Set i to 1 and add 7 to line count to create another calendar row
        :0)                                             // Otherwise do nothing

    for(j=0;j<71;                                       // Loop 71 times, appending characters to create a row
        b=l+j/10+2-C.get(7),                            // Determine the day of the box we're in
        e=(e=M.get(b))!=null?                           // Get the event for this day from the map and if not null
            e.replaceAll("([^-]{1,9})(-| |$)","$1-")      // Do some regex to separate the line entries by hyphens
            +" - "                                      // Append extra hyphen to prevent array out of bounds
            :null,                                      // Otherwise do nothing
        r+=e=i%6<1?"-":                                 // If it's the first line of a calendar row, append -
           c<1?"|":                                     // If it's the first column of a box, append |
           c*i<2&b>0&b<=x?b+"":                         // If it's the second column of a box, the second row, 
                                                        // and less than the max day, append the day
           c<2&e!=null?e.split("-")[i-2]:               // If it's any other row and there is an event then split and append correct line
           " ",                                         // Else just append a space
        j+=e.length())                                  // Increase the row character count by the length to append
          c=j%10;                                       // Set the column of box (this is the only thing in the loop so happens first)

  return r;                                             // return the calendar string!
}

&&(i=1)<2?7:0olabilir ?7*(i=1):03 bayt kaydedin.
Kevin Cruijssen

@KevinCruijssen İyi teşekkürler!
Luke Stevens

Öner b>x|i++<6?0:7*(i=1)yerine b<=x&++i>6?7*(i=1):0ve c*i>1|b<1|b>x?c<2&e!=null?e.split("-")[i-2]:" ":b+""yerinec*i<2&b>0&b<=x?b+"":c<2&e!=null?e.split("-")[i-2]:" "
ceilingcat

1

Kırmızı , 674651 bayt

func[a][z: func[a b c][to-tuple reduce[a b c]]c: a/1 c/4: 1 d: c + 31
d/4: 1 d: d - 1 e: 1 + c/weekday % 7 if e = 0[e: 7]foreach
t[:Su:Mo:Tu:We:Th:Fr:Sa][prin pad pad/left t 6 10]h:
pad/with"-"71 #"-"print["^/"h]m: copy[]foreach[i b]a[put m z r:(t: e - 1)+
i/4 / 7 + 1 n: i/4 % 7 + t 2 b/1 t: split b/2" "l: 0
until[if t/2[if 10 >((length? t/1)+ length? t/2)[t/1:
rejoin reduce[t/1" "take next t]]]put m z r n 2 + l: l + 1 take t
tail? t]i: 0]n: k: 0 repeat v(g: e - 1 + d/4)/ 7 + sign? g % 7[repeat
r 5[repeat i 7[t: copy"|"if i = e[k: 1]if all[k = 1 r = 1 n < d/4][append t
n: n + 1]if s: select m z v i r[append t s]prin pad t 10]print"|"]print h]]

Çevrimiçi deneyin!

Daha okunabilir:

func [ a ] [
    c: d: a/1
    c/4: d/4: 1
    d: d + 31
    d/4: 1
    d: d - 1
    e: 1 + c/weekday % 7
    if e = 0[e: 7]
    g: e - 1 + d/4
    w: g / 7 + sign? g % 7
    foreach t [ :Su :Mo :Tu :We :Th :Fr :Sa ] [
        prin pad pad/left t 6 10
    ]
    h: pad/with "-" 71 #"-"
    print[ "^/" h ]
    m: copy #()
    foreach[ i b ] a [
        n: i/4 % 7 + t: e - 1
        r: t + i/4 / 7 + 1
        put m to-tuple reduce[ r n 2 ] b/1
        t: split b/2" "
        i: 0
        until [
            if t/2 [ if 9 >= ((length? t/1) + (length? t/2)) [
                t/1: rejoin reduce[t/1" "take next t]
                ]
            ]
            put m to-tuple reduce [ r n 2 + i: i + 1 ] take t
            tail? t
        ]

    ]
    n: 0
    g: off
    repeat v w [
        repeat r 5 [
           repeat i 7 [
                t: copy "|"
                if i = e[ g: on ]
                if all [ g r = 1 n < d/4 ] [ append t n: n + 1 ]
                if s: select m to-tuple reduce [ v i r ]
                    [ append t s ]
                prin pad t 10
            ]
            print "|"
        ]
        print h
    ]
]

if e = 0[e: 7]kaldırılabilir, değil mi? Siz kullanın e: 1 + c/weekday % 7, bu yüzden eher zaman aralıkta olacak [1, 7].
Kevin Cruijssen

@KevinCruijssen: Belki bir şey eksik ama sanırım buna ihtiyacım var. Kırmızı indeksleme 1 tabanlıdır. Lütfen şuna bir bakın: >> c: şimdi / saat / tarih == 12-Ekim-2018 >> c: c + 1 == 13-Ekim-2018 >> 1 + c / hafta içi% 7 == 0; >> 1 + 2 * 3 Kırmızı değil 9, 7 değil
Galen Ivanov

1
EDIT: Ah, nvm .. Önce 1 + olur .. Tamam , hatamı görüyorum. Ben alışkınım %ve /operatörün önceliği var +.
Kevin Cruijssen

1
@KevinCruijssen Evet, kesinlikle. Kırmızı'da operatör önceliği yoktur, bunun yerine () kullanılması gerekir
Galen Ivanov
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.