Công cụ lập kế hoạch lịch ASCII


11

Đưa ra một danh sách các hoạt động và thời gian / ngày bắt đầu của chúng, xuất ra lịch nghệ thuật ASCII hiển thị các hoạt động vào những ngày thích hợp. Tất cả các hoạt động được đảm bảo trong cùng một tháng, không có hai hoạt động sẽ diễn ra trong cùng một ngày và tất cả các hoạt động được đảm bảo phù hợp với hộp lịch.

Lịch có ngày ở góc trên bên trái của mỗi hộp, các hộp có 9 không gian rộng bằng 5 không gian, bao quanh -|. Chữ viết tắt hai chữ cái cho ngày trong tuần được tập trung ở trên hàng đầu tiên và các tuần bắt đầu bằng Chủ nhật.

Ví dụ, đưa ra các hoạt động sau:

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

Xuất lịch tương ứng này:

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

Làm rõ

  • Các từ lịch biểu (khớp [A-Za-z] +) sẽ được phân cách bằng một khoảng trắng giữa chúng (như trong ví dụ).
  • Tách văn bản trên ranh giới từ là đủ. Không cần từ gạch nối.
  • Nếu tháng hai bắt đầu vào Chủ nhật trong một năm không nhuận, bạn sẽ chỉ có bốn hàng lịch.
  • Nếu một tháng 31 ngày (ví dụ: tháng 8) bắt đầu vào cuối tuần, bạn có thể phải xuất sáu hàng lịch.

I / O và Nội quy

  • Mã của bạn phải xử lý ngày ít nhất là giữa 0001-01-019999-12-31trong lịch Gregorian, bao gồm cả năm nhuận nếu thích hợp. Ví dụ: nếu được cung cấp đầu vào 2016-02-13 9:00am Test, lịch đầu ra sẽ có ngày 29 tháng 2.
  • Định dạng ngày đầu vào có thể ở bất kỳ định dạng mong muốn. ISO 8601, một datetimeđối tượng, một chuỗi có định dạng đặc biệt, v.v. Phân tích cú pháp đầu vào không phải là phần thú vị của thử thách này.
  • Đầu vào và đầu ra có thể bằng bất kỳ phương pháp thuận tiện .
  • Các dòng mới hàng đầu / dấu hoặc khoảng trắng khác là tùy chọn, miễn là các ký tự xếp hàng một cách thích hợp.
  • Hoặc là một chương trình đầy đủ hoặc một chức năng được chấp nhận. Nếu một chức năng, bạn có thể trả lại đầu ra thay vì in nó.
  • Đầu ra có thể là bàn điều khiển, được trả về dưới dạng danh sách các chuỗi, được trả về dưới dạng một chuỗi, v.v.
  • Sơ hở tiêu chuẩn bị cấm.
  • Đây là vì vậy tất cả các quy tắc chơi gôn thông thường đều được áp dụng và mã ngắn nhất (tính bằng byte) sẽ thắng.

1.) Bạn có phải chia tên hoạt động trên ranh giới từ không? 2.) Khi bạn có một tháng hai không nhảy vọt bắt đầu vào Chủ nhật, bạn chỉ có 4 hàng? 3.) Khi bạn cần 6 hàng để hiển thị tháng (ví dụ: Tháng 8 bắt đầu vào Thứ Bảy), điều gì xảy ra?
nedla2004

Liên quan (dễ dàng hơn).
Arnauld

@ nedla2004 1) Có, ranh giới từ sẽ hoạt động tốt. 2) Đúng vậy, 4 hàng. 3) Lịch của bạn sẽ cần hiển thị 6 hàng. Tôi sẽ chỉnh sửa làm rõ.
admBorkBork

@Arnauld Vâng, đó là một giả định hợp lý
admBorkBork

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

Câu trả lời:


10

JavaScript (ES8), 380 ... 321 320 byte

Đưa đầu vào vào (y,m,e)đâu:

  • y là năm
  • m là tháng, 0 chỉ mục
  • elà một đối tượng có khóa là ngày và giá trị của chúng là các sự kiện ở [hour, task]định dạng
(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`)

Hãy thử trực tuyến!

Làm sao?

Dưới đây là một số phần quan trọng trong mã.

Tiêu đề

Dòng tiêu đề được tạo bằng:

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

Khi split()được sử dụng với một biểu thức chính quy có chứa một nhóm bắt giữ, nhóm này được bao gồm trong mảng đầu ra. Trong trường hợp này, nó cung cấp cho:

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

Chúng tôi tham gia mảng này với 4 khoảng trắng, dẫn đến:

'    Su        Mo        Tu        We        Th        Fr        Sa    \n'

đó chính xác là những gì chúng ta muốn

Cơ cấu tháng

Hàm trợ giúp xây dựng một ngày từ năm đầu vào và tháng đầu vào (không đổi) và ngày (là động). Tham số của nó là một tên phương thức, cho phép trích xuất ngày trong tuần hoặc tháng.Gymd

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

Nó được sử dụng đầu tiên để xác định ngày trong tuần của ngày đầu tiên của tháng, để chúng ta có thể quay trở lại vào Chủ nhật cuối cùng từ đó. Sau đó, nó được sử dụng để phát hiện khi chúng tôi nhập lại đúng tháng và khi chúng tôi rời khỏi đó (thông tin này được lưu trữ trong Boolean ).x

Định dạng sự kiện

Các mã sau đây được sử dụng để định dạng một sự kiện.

[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 byte

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

Hãy thử trực tuyến!

Đầu vào tương tự như câu trả lời JS của Arnauld :

Đưa đầu vào vào (y,m,e)đâu:

  • y là năm
  • m là tháng, 1 chỉ mục
  • elà một đối tượng có khóa là ngày và giá trị của chúng là các sự kiện ở (hour, task)định dạng

3

Than , 215 206 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Có ngày ở định dạng d / m / yyyy. Giải trình:

Sθ

Nhập sự kiện đầu tiên.

≔I⪪§⪪θ ⁰/η

Trích xuất ngày và chia trên /s.

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

Chuyển đổi sang tháng kể từ tháng 3, 1 trước Công nguyên. Tôi muốn tính ngày trong tuần của tháng đầu tiên của tháng tiếp theo và tháng hiện tại, và làm việc theo tháng dễ hơn là giữ các tháng và năm tách biệt và mang theo vào cuối năm, cộng với nó cũng cho phép tôi bắt đầu đếm tháng bắt đầu vào tháng ba thay vì tháng một, được yêu cầu bởi sự phù hợp của Zeller.

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

Sử dụng sự phù hợp của Zeller đã được sửa đổi để trích xuất ngày trong tuần của ngày đầu tiên của tháng tiếp theo và tháng này. Phần cơ bản dựa trên thực tế là số ngày từ ngày 30 tháng 10 năm trước đến ngày đầu tiên của tháng nhất định cho tháng m = 43 và m = 14tháng 1 năm sau được đưa ra theo công thức m * 153 / 5, tuy nhiên chúng tôi có thể trừ 140 vì chúng tôi chỉ có thể trừ quan tâm đến ngày trong tuần. Sau đó vẫn còn để điều chỉnh do năm; mỗi năm thêm một ngày, mỗi năm thứ 4 thêm một ngày, mỗi năm thứ 100 trừ đi một ngày và mỗi năm thứ 400 lại thêm một ngày nữa. (Khi tôi làm việc trong nhiều tháng, các giá trị này được nhân với 12.) Khá thuận tiện, điều này trực tiếp cho tôi câu trả lời theo tuần được lập chỉ mục vào Chủ nhật (thông thường bạn sẽ thêm ngày trong tháng và bắt đầu đếm vào Thứ Bảy).

≔±⊟ηζ

Phủ định ngày trong tuần và lưu nó là ngày hiện tại của tháng.

≔⁺²⁸﹪⁺⊟ηζ⁷ε

Tính số ngày trong tháng kể từ ngày trong tuần của hai tháng.

⭆⪪SuMoTuWeThFrSa²◨◧ι⁶χ

Đầu ra các tiêu đề ngày.

↓←⁷¹

In hàng trên cùng của -s.

W‹ζε«

Vòng lặp cho đến ngày cuối cùng của tháng đã được xuất.

Di chuyển con trỏ đến đầu hàng tiếp theo.

F⁷«

Quá trình 7 ngày một lần.

P↓⁵→

In cột của |s sang trái.

≦⊕ζ

Tăng ngày hiện tại của tháng.

F⁼Iζ§⪪θ/⁰«

Nếu ngày hiện tại của tháng là ngày của sự kiện hiện tại, ...

≔⪪θ - θ

... trích xuất các phần khác của sự kiện, ...

≔⟦ω◨§θ¹¦⁹⟧δ

... ghi thời gian vào 9 khoảng trắng và lưu nó và một chuỗi trống dưới dạng danh sách, ...

F⪪⊟θ 

... phân chia mô tả trên các khoảng trắng và lặp lại chúng, ...

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

... Thêm từng từ vào từ trước nếu nó phù hợp; ...

P⪫δ¶

... xuất thời gian và mô tả ( Pδkhông hoạt động, có thể là lỗi Than?), ...

Sθ»

... và nhập sự kiện tiếp theo.

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

Nếu ngày hiện tại của tháng nằm trong khoảng từ 1 đến ngày cuối cùng của tháng thì hãy xuất nó, nếu không thì chỉ cần xuất đủ không gian để chuyển sang ngày tiếp theo.

↓⁵←⁷¹

Vào cuối tuần, in cột bên phải của |s và hàng dưới cùng của -s.


Có thể tôi đã bỏ qua nó trong mã TIO dài dòng của bạn, nhưng bạn có chắc rằng việc triển khai đồng dư của Zeller đã hoàn tất? Nó có vẻ đúng cho các tháng từ tháng 3 đến tháng 12, nhưng trong các tháng 1 và tháng 2 year-1nên được sử dụng thay vì yearmonth+12nên được sử dụng thay vì month. Hay bạn đã đơn giản hóa bằng cách nào đó thuật toán mà tôi đã đề cập trong câu trả lời 05AB1E này của tôi tương đương với thuật toán từ Wikipedia ?
Kevin Cruijssen

@KevinCruijssen Về cơ bản, đây là lý do tại sao tôi tính số tháng kể từ tháng 3, 1BC, nhưng quá phức tạp để giải thích thêm trong một nhận xét.
Neil

1
@KevinCruijssen Tôi đã cập nhật lời giải thích của mình; Tôi hy vọng bạn tìm thấy nó hữu ích.
Neil

Cảm ơn! Đó thực sự là một công thức sửa đổi tốt đẹp, và bây giờ tôi hiểu lý do đằng sau nó. Cảm ơn rất nhiều vì đã thêm nó vào lời giải thích. +1 từ tôi.
Kevin Cruijssen

2

Java (JDK) , 538 439 428 425 byte

Khá có thể là giải pháp Code Golf dài nhất tôi từng đăng. Vẫn cố gắng đánh gôn từ đây nhưng đó là một cuộc đấu tranh.

Quản lý để loại bỏ 99 byte bằng cách thay đổi định dạng đầu vào và sử dụng một số phân tích cú pháp regex và 11 khác từ các bit linh tinh.

Giảm thêm 3 byte nhờ Kevin!

Lấy cảm hứng từ các câu trả lời khác, phải lấy đầu vào là năm, tháng và Bản đồ ngày cho Chuỗi biểu thị thời gian và sự kiện theo định dạng <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;}

Hãy thử trực tuyến!


Ung dung

(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:0có thể ?7*(i=1):0để lưu 3 byte.
Kevin Cruijssen

@KevinCruijssen Rất vui được cảm ơn!
Luke Stevens

Đề xuất b>x|i++<6?0:7*(i=1)thay vì b<=x&++i>6?7*(i=1):0c*i>1|b<1|b>x?c<2&e!=null?e.split("-")[i-2]:" ":b+""thay vìc*i<2&b>0&b<=x?b+"":c<2&e!=null?e.split("-")[i-2]:" "
trần mèo

1

Đỏ , 674 651 byte

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]]

Hãy thử trực tuyến!

Dễ đọc hơn:

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]có thể được gỡ bỏ, phải không? Bạn sử dụng e: 1 + c/weekday % 7, vì vậy esẽ luôn luôn trong phạm vi [1, 7].
Kevin Cruijssen

@KevinCruijssen: Có thể tôi đang thiếu thứ gì đó, nhưng tôi nghĩ rằng tôi cần nó. Lập chỉ mục màu đỏ là dựa trên 1. Hãy xem cái này: >> c: now / time / date == 12-Oct-2018 >> c: c + 1 == 13-Oct-2018 >> 1 + c / ngày trong tuần% 7 == 0; >> 1 + 2 * 3 là 9 màu đỏ, không phải 7
Galen Ivanov

1
EDIT: Ah, nvm .. Việc 1 + xảy ra đầu tiên .. Ok, tôi thấy lỗi của tôi. Tôi đã quen %/có quyền ưu tiên vận hành hơn +.
Kevin Cruijssen

1
@KevinCruijssen Vâng, chính xác. Không có quyền ưu tiên của nhà điều hành trong Red, thay vào đó, người ta cần sử dụng ()
Galen Ivanov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.