ความสมมาตรของเดือน


32

บทนำ

บางเดือนมีความสมมาตรอย่างสมบูรณ์ซึ่งหมายความว่าพวกเขามีความสมมาตรกลางเช่นเดียวกับการสะท้อนกลับสมมาตรเช่นFebruary of 2010:

     February 2010
┌──┬──┬──┬──┬──┬──┬──┐ 
│  │  │  │  │  │  │  │ 
├──┼──┼──┼──┼──┼──┼──┤ 
│  │  │  │  │  │  │  │ 
├──┼──┼──┼──┼──┼──┼──┤ 
│  │  │  │  │  │  │  │ 
├──┼──┼──┼──┼──┼──┼──┤ 
│  │  │  │  │  │  │  │ 
└──┴──┴──┴──┴──┴──┴──┘ 

บางเดือนมีเพียงสมมาตรส่วนกลางเช่นFebruary of 1996หรือเดือนปัจจุบันApril of 2018:

      February 1996
          ┌──┬──┬──┬──┐
          │  │  │  │  │
 ┌──┬──┬──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┴──┴──┘
 │  │  │  │  │
 └──┴──┴──┴──┘

       April 2018  ┌──┐
                   │  │
 ┌──┬──┬──┬──┬──┬──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┴──┴──┴──┴──┴──┘
 │  │
 └──┘

และบางอันไม่สมมาตรเช่นเดียวกับเดือนก่อนหน้าMarch of 2018:

      March 2018
         ┌──┬──┬──┬──┐
         │  │  │  │  │
┌──┬──┬──┼──┼──┼──┼──┤
│  │  │  │  │  │  │  │
├──┼──┼──┼──┼──┼──┼──┤
│  │  │  │  │  │  │  │
├──┼──┼──┼──┼──┼──┼──┤
│  │  │  │  │  │  │  │
├──┼──┼──┼──┼──┼──┼──┘
│  │  │  │  │  │  │
└──┴──┴──┴──┴──┴──┘

งาน

ป้อนข้อมูลในรูปแบบของวันที่เช่น:

  • 2018.04
  • 2018.03
  • 2010.02
  • 1996.02

ส่งออกสมมาตรที่สอดคล้องกันเช่น

  • 2018.04 -> centrally symmetric
  • 2018.03 -> asymmetric
  • 2010.02 -> symmetric
  • 1996.02 -> centrally symmetric

กฎระเบียบ

  • นี่คือรหัสกอล์ฟดังนั้นจำนวนไบต์ที่น้อยที่สุดจะเป็นผู้ชนะ
  • ไม่อนุญาตให้มีช่องโหว่มาตรฐาน
  • สมมติว่าสัปดาห์เริ่มต้นด้วยวันจันทร์ (ขอบคุณAngsและArnauldสำหรับคำแนะนำ)
  • พิจารณาเฉพาะปีระหว่าง 1900 ถึง 2100 ( รวม )
  • กฎการจัดรูปแบบอินพุตและเอาต์พุตอนุญาตให้ใช้ซึ่งหมายความว่าคุณสามารถใช้รูปแบบที่เทียบเท่ากับภาษาที่คุณเลือกได้
  • ฐานวิธีการแก้ปัญหาของคุณบนปฏิทินเกรกอเรียน

7
พิจารณาว่าวันที่แปลกคุณอาจต้องการระบุกฎหรือ จำกัด การป้อนข้อมูลที่เป็นไปได้ให้กับช่วงเล็ก ๆ (พูด, 1901-2099)
user202729

2
สิ่งที่ควรหลีกเลี่ยงเมื่อเขียนความท้าทาย / การเพิ่มสิ่งที่ไม่จำเป็นรวมถึง "การทำคำตอบf(x)สำหรับทุกxรายการในการคำนวณ" สิ่งที่เกี่ยวกับ "นำเข้าในรูปแบบของวันที่"?
user202729

6
ยินดีต้อนรับสู่ PPCG และความท้าทายแรกที่ดี! แม้ว่าความท้าทายนี้จะดี แต่ในอนาคตหากคุณต้องการคำติชมเกี่ยวกับความท้าทายก่อนโพสต์คุณสามารถโพสต์ไว้ในกล่องทดลอง
user202729

2
เอาต์พุตควรเป็นสตริงที่กล่าวถึงอย่างเคร่งครัดหรือค่าที่ต่างกัน 3 ค่า?
Uriel

2
(เดี๋ยวก่อนปฏิทินเกรกอเรียนหรือปฏิทินจูเลียนฉันแนะนำ [1901-2099] แต่คุณตัดสินใจที่จะใช้ [1900-2100] ดังนั้นมันจึงแตกต่างกันไปสำหรับอินพุตบางส่วน)
user202729

คำตอบ:


20

JavaScript (ES6), 55 ไบต์

บันทึกแล้ว 6 ไบต์ขอบคุณ @Neil

(year)(month)จะเข้าในไวยากรณ์ currying ส่งคืนfalseสำหรับอสมมาตรtrueสำหรับสมมาตรส่วนกลางและ0สมมาตรสมบูรณ์

y=>m=>(n=(g=_=>new Date(y,m--,7).getDay())()+g())&&n==7

ลองออนไลน์!

อย่างไร?

เรากำหนดฟังก์ชันg ()ซึ่งส่งคืนวันทำงานของyyyy / mm / 01เป็นจำนวนเต็มระหว่าง0 = วันจันทร์และ6 = วันอาทิตย์

g = _ => new Date(y, m--, 7).getDay()

เนื่องจากgetDay ()ส่งกลับค่า0 = วันอาทิตย์เป็น6 = วันเสาร์เราจึงเปลี่ยนผลลัพธ์เป็นช่วงที่คาดหวังโดยค้นหาวันที่ 7 แทน

จากนั้นเราจะกำหนด:

n = g() + g()

เนื่องจากตัวสร้างของวันที่คาดว่าจะมีเดือนที่จัดทำดัชนี 0 และเนื่องจากg ()ลดลงm หลังจากผ่านไปยังวันที่เราจะทำการคำนวณวันทำงานแรกของวันแรกของเดือนถัดไปก่อนแล้วจึงเพิ่มลงในปัจจุบัน

เดือนสมมาตรอย่างสมบูรณ์

เดือนสมมาตรทั้งหมดเริ่มต้นด้วยวันจันทร์และตามด้วยเดือนซึ่งเริ่มต้นด้วยวันจันทร์ นี่เป็นไปได้สำหรับเดือนกุมภาพันธ์ของปีที่ไม่ก้าวกระโดด

- Feb --------------    - Mar --------------
Mo Tu We Th Fr Sa Su    Mo Tu We Th Fr Sa Su
--------------------    --------------------
01 02 03 04 05 06 07    01 02 03 04 05 06 07
08 09 10 11 12 13 14    08 09 10 11 12 13 14
15 16 17 18 19 20 21    15 16 17 18 19 20 21
22 23 24 25 26 27 28    22 23 24 25 26 27 28
                        29 30 31

นำไปสู่การนี้n = 0

ศูนย์กลางสมมาตรเดือน

ใจกลางสมมาตรเดือนเดือนที่ผลรวมของวันทำงานวันแรกของพวกเขาและที่ของเดือนถัดไปเป็น7

- M ----------------    - M+1 --------------
Mo Tu We Th Fr Sa Su    Mo Tu We Th Fr Sa Su
--------------------    --------------------
 0  1 [2] 3  4  5  6     0  1  2  3  4 [5] 6
--------------------    --------------------
      01 02 03 04 05                   01 02
06 07 08 09 10 11 12    03 04 05 06 07 07 09
13 14 15 16 17 18 19    ...
20 21 22 23 24 25 26
27 28 29 30 31

ดังนั้นการทดสอบที่สอง: n == 7


ไม่มีในตัว 93 ไบต์

ใช้ความสอดคล้องกันของเซลเลอร์ รูปแบบ I / O เหมือนกับเวอร์ชันอื่น

y=>m=>(n=(g=_=>(Y=y,((m+(m++>2||Y--&&13))*2.6|0)+Y+(Y>>2)-6*~(Y/=100)+(Y>>2))%7)()+g())&&n==7

ลองออนไลน์!


ฉันคิดว่ามันtrue, falseและfilenotfoundแทน0...
Angs

g=m=>new Date(y,m,7).getDay()บันทึก 6 ไบต์
Neil

7

T-SQL , 213 ไบต์ (กฎ I / O ที่เข้มงวด)

SET DATEFIRST 1SELECT CASE WHEN a+b<>8THEN'a'WHEN a=1THEN''ELSE'centrally 'END+'symetric'FROM(SELECT DATEPART(DW,f)a,DATEPART(DW,DATEADD(M,1,f)-1)b FROM (SELECT CONVERT(DATETIME,REPLACE(s,'.','')+'01')f FROM t)y)x

แบบสอบถามด้านบนพิจารณากฎการจัดรูปแบบอินพุต / เอาต์พุตที่เข้มงวด

อินพุตถูกนำมาจากคอลัมน์sของตารางชื่อt:

CREATE TABLE t (s CHAR(7))
INSERT INTO t VALUES ('2018.04'),('2018.03'),('2010.02'),('1996.02')

Ungolfed:

SET DATEFIRST 1
SELECT *, CASE WHEN a+b<>8 THEN 'a' WHEN a=1 AND b=7 THEN '' ELSE 'centrally ' END+'symetric'
FROM (
    SELECT *,DATEPART(WEEKDAY,f) a, 
        DATEPART(WEEKDAY,DATEADD(MONTH,1,f)-1) b 
    FROM (SELECT *,CONVERT(DATETIME,REPLACE(s,'.','')+'01')f FROM t)y
) x

SQLFiddle 1

T-SQL , 128 ไบต์ (กฎ I / O ที่อนุญาต)

SET DATEFIRST 1SELECT CASE WHEN a+b<>8THEN 1WHEN a=1THEN\END FROM(SELECT DATEPART(DW,d)a,DATEPART(DW,DATEADD(M,1,d)-1)b FROM t)x

หากรูปแบบของอินพุตและเอาต์พุตสามารถเปลี่ยนแปลงได้ฉันจะเลือกป้อนวันแรกของเดือนในdatetimeคอลัมน์ชื่อd:

CREATE TABLE t (d DATETIME)
INSERT INTO t VALUES ('20180401'),('20180301'),('20100201'),('19960201')

เอาต์พุตจะเป็น 1 สำหรับ asymetric, 0 สำหรับ symetric, NULL สำหรับ symetric จากส่วนกลาง

หากเราสามารถเรียกใช้บนเซิร์ฟเวอร์ (หรือด้วยการเข้าสู่ระบบ) ที่กำหนดค่าสำหรับภาษา BRITISH เราสามารถลบSET DATEFIRST 1การบันทึกอีก 15 ไบต์

SQLFiddle 2


1
ทำได้ดีมาก ถ้าไม่แน่ใจว่ามันจะทำงานในทุกรุ่น แต่ใน SQL 2012 ผมสามารถที่จะบันทึก 15 ไบต์โดยใช้แทนCONVERT(DATETIME,s+'.01') REPLACEนอกจากนี้คุณยังสามารถปล่อยพื้นที่ในFROM (SELECT
BradC

1
มันใช้งานได้ แต่ขึ้นอยู่กับการDATEFORMATตั้งค่า ตัวอย่างเช่นถ้าเราใช้SET LANGUAGE BRITISHแล้วCONVERT(DATETIME,'2018.02.01')จะเป็นวันที่ 2 มกราคมแทนที่จะเป็นวันที่ 1 กุมภาพันธ์
Razvan Socol

5

Haskell, 170 ไบต์

import Data.Time.Calendar
import Data.Time.Calendar.WeekDate
a%b=((\(_,_,a)->a).toWeekDate.fromGregorian a b$1)!gregorianMonthLength a b
1!28=2
4!29=1
7!30=1
3!31=1
_!_=0

ส่งคืน 2 สำหรับสมมาตรส่วนกลาง, 1 สำหรับสมมาตรและ 0 สำหรับสมมาตร


@ TuukkaX ขออภัยด้วยความสับสน - นี่เป็นความท้าทายครั้งแรกของฉันฉันได้เปลี่ยนกฎเพื่อให้อนุญาตรูปแบบเอาต์พุตที่อนุญาตดังนั้นจึงสามารถมี "จิตวิญญาณ" ของรหัสกอล์ฟได้มากขึ้น
mkierc

5

Python 2, 118 104 ไบต์

ขอบคุณ Jonathan Allan และ Dead Possum สำหรับการปรับปรุง!

from calendar import*
def f(*d):_=monthcalendar(*d);print all(sum(_,[]))+(_[0].count(0)==_[-1].count(0))

Python 3, 122 105 ไบต์

from calendar import*
def f(*d):_=monthcalendar(*d);print(all(sum(_,[]))+(_[0].count(0)==_[-1].count(0)))

อินพุต

  • ครั้งแรกคือปี
  • ประการที่สองคือเดือน


เอาท์พุต

  • 0 = ไม่มีความสมมาตร
  • 1 = สมมาตรส่วนกลาง
  • 2 = สมมาตรที่สมบูรณ์

3
ยินดีต้อนรับสู่เว็บไซต์! คุณอาจไม่คิดว่าอินพุตถูกเก็บไว้ในตัวแปร (เช่นYหรือM) ดังนั้นขณะนี้ข้อมูลโค้ดและไม่ถูกต้อง อย่างไรก็ตามหากคุณเปลี่ยนตัวแปรเป็นการเรียกไปยังinput()สิ่งนี้จะเป็นการปรับได้อย่างสมบูรณ์แบบ
caird coinheringaahing

1
@cairdcoinheringaahing ขอบคุณสำหรับการต้อนรับ! ป้อนข้อมูลผู้ใช้คงที่ :)
แจ็คของโพดำทั้งหมด

ยินดีต้อนรับ! ปรับแต่งสำหรับ -9 bytes ที่นี่ - นำเข้าทั้งหมด, ไม่ได้ใส่กล่อง_[0]+_[-1]->sum(..)
Possum ที่ตายแล้ว

1
เทคนิคบางอย่างเพื่อทำให้มันลดลง 13 ไบต์ที่นี่
Jonathan Allan

1
... และอีกหนึ่งไบต์โดยใช้กลโกงผลรวมของ Dead Possum - ที่นี่
Jonathan Allan

4

แดง , 199, 168 161 ไบต์

func[d][t: split d"."y: do t/1 m: do t/2 a: to-date[1 m y]b: a + 31
b/day: 1 b: b - 1 if(1 = s: a/weekday)and(7 = e: b/weekday)[return 1]if 8 - e = s[return 2]0]

ลองออนไลน์!

0 - ไม่สมมาตร

1 - สมมาตร

2 - สมมาตรส่วนกลาง

อ่านเพิ่มเติมได้:

f: func[d][                  ; Takes the input as a string
    t: split d "."           ; splits the string at '.'
    y: do t/1                ; stores the year in y 
    m: do t/2                ; stores the month in m
    a: to-date[1 m y]        ; set date a to the first day of the month
    b: a + 31                ; set date b in the next month  
    b/day: 1                 ; and set the day to 1st
    b: b - 1                 ; find the end day of the month starting on a
    s: a/weekday             ; find the day of the week of a 
    e: b/weekday             ; find the day of the week of b
    if(s = 1) and (e = 7)    ; if the month starts at Monday and ends on Sunday
        [return 1]           ; return 1 fo symmetric
    if 8 - e = s             ; if the month starts and ends on the same day of the week
        [return 2]           ; return 2 for centrally symmetric  
    0                        ; else return 0 for assymetric
]

2

Mathematica, 137 ไบต์

a=#~DateValue~"DayName"&;b=a/@{2}~DateRange~{3};Which[{##}=={0,6},1,+##>5,0,1>0,-1]&@@(Position[b,a@#][[1,1]]~Mod~7&)/@{{##},{#,#2+1,0}}&

ฟังก์ชั่นบริสุทธิ์ ใช้ปีและเดือนเป็นข้อมูลป้อนเข้าและส่งคืน-1สำหรับเดือนแบบอสมมาตร0สำหรับเดือนสมมาตรส่วนกลางและ1สำหรับเดือนสมมาตรทั้งหมด ไม่แน่ใจว่าทำไมภาษานี้ไม่สามารถแปลงจากวันธรรมดาเป็นตัวเลขโดยค่าเริ่มต้น ...


2

ยูทิลิตีBash + GNU, 70

date -f- +%u<<<"$1/1+1month-1day
$1/1"|dc -e??sad8*la-55-rla+8-d*64*+p

YYYY/MMการป้อนข้อมูลมีรูปแบบเป็น

เอาต์พุตเป็นตัวเลขดังนี้:

  • น้อยกว่า 0: สมมาตรส่วนกลาง
  • 0: สมมาตร
  • มากกว่า 0: ไม่สมมาตร

ฉันคิดว่ารูปแบบผลลัพธ์นี้เป็นที่ยอมรับได้สำหรับคำถามนี้

ลองออนไลน์!


1

C, 111 ไบต์

a;g(y,m){y-=a=m<3;return(y/100*21/4+y%100*5/4+(13*m+16*a+8)/5)%7;}f(y,m){a=g(y,m)+g(y,m+1);return(a>0)+(a==7);}

เรียกใช้f(year, month), 0 สำหรับสมมาตรทั้งหมด, 1 สำหรับสมมาตร, 2 สำหรับสมมาตรส่วนกลาง


IIRC คุณสามารถละเมิด UB บน GCC โดยแทนที่returnด้วยy=(พารามิเตอร์แรก) และหลุดออกจากฟังก์ชัน
เควนติน

1

Perl 6 , 74 ไบต์

{{{$_==30??2!!$_%7==2}(2*.day-of-week+.days-in-month)}(Date.new("$_-01"))}

เปลือยบล็อกโดยปริยายฟังก์ชั่น 1 "2012-02"อาร์กิวเมนต์สตริงเหมือน ผลตอบแทน:

2     # Fully symmetric
True  # Centrally symmetric
False # Asymmetric

เมื่อรูปแบบมีความสมมาตรเนื่องจาก. วันในสัปดาห์เพิ่มขึ้น 1,. วันในเดือนจะต้องย้าย 2 เพื่อให้ยังคงการแข่งขัน (เดือนจะเริ่มในอีกหนึ่งวันต่อมา แต่ต้องสิ้นสุดวันก่อนหน้านี้ ) ดังนั้น2 * .day-of-week + .days-in-monthให้เราวัดช่องว่างนั้น Modulo 7 ควรเป็น 1 เพื่อให้ได้สัดส่วน แต่ก่อนอื่นเราสามารถตรวจสอบ non-leap กุมภาพันธ์โดยตรวจสอบยอดรวมก่อน modulo (วันจันทร์และ 28 วันต่อเดือนเป็นการรวมกันขั้นต่ำสุด)

ฉันประหลาดใจที่ต้องใช้จำนวนมาก แต่จำเป็นต้องใช้ 36 ไบต์อย่างเต็มรูปแบบสำหรับการกำหนดวันและรับวันในสัปดาห์และวันในเดือนนั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.