Який сьогодні день (або інші дати)?


12

Завдання

Напишіть програму або функцію, яка розраховує назву дня на тиждень дати, яку вводить користувач.

Введення-виведення

Введення є рядок, YYYYMMDD.

Приклад вхідних значень:

20110617: 17 червня 2011 року
19040229: 29 лютого 1904
06661225: 25 грудня 666 року
00000101: 1 січня 0
99991231: 31 грудня 9999

Ви можете припустити, що всі введення є дійсними. Зауважте, що нуль року дійсний.

Вихід - це ціле число між 0та 6. Кожне ціле число позначає назву дня на тиждень. Ви можете вільно визначити, яке ціле число позначає назву тижня, як це

0: понеділок
1: Вівторок
2: середа
...
6: неділя

(по порядку) або цей

0: понеділок
1: середа
2: неділя
...
6: субота

(не в порядку).

Випробування

У цьому прикладі використовується вихідний вихідний тиждень ([0..6 -> понеділок..субота].)

20110617 П’ятниця 4
19500101 неділя 6
22220202 Субота 5
19000228 середа, 2
19000301 Четвер, 3
19450815 середа, 2
19040229 понеділок 0
19040301 Вівторок 1
17760704 Четвер, 3
20000228 понеділок 0
20000229 Вівторок 1
20000301 середа, 2
20121223 неділя 6
00000401 субота 5
66660606 Середа 2
59161021 Субота 5

Обмеження

Ви не повинні використовувати будь- які функції / class / ..., які пов'язані з часовою позначкою або датою, як, наприклад, Dateклас в Java/ JavaScript/ ActionScriptабо getdateфункція в PHP.

Слід скористатися григоріанським календарем , яким зараз користуються багато людей.

Звичайно, виграє найкоротший код. Якщо два коди мають однакову довжину, виграє код з найвищими голосами.

(Термін дії: Якщо існує більше 5 кодів, які мають більше (або рівних) +1голосів.)


Сьогодні? Чому, Різдво!
Joey Adams

3
Оптимістичний рішення написано в Bash (6 символів): echo 4.
trutheality

1
@trutheality Ні, я не мав на увазі, що .. Я хотів - це код, який друкує / повертає день тижня дати, яку хтось набрав, а не друкує день тижня сьогодні.
JiminP

О, я знаю. Ось що робить цей.
trutheality

Це правильно, принаймні, 14% часу!
Draco18s більше не довіряє SE

Відповіді:


2

Рубі, 95 92 символи

Просте прямо реалізація рубіну з 0: понеділок, ...

p ((y=(d=gets.to_i)/(k=100)/k-((m=d/k%k)<3?1:0))+y/4-y/k+y/400+"squsptrotqro"[-m].ord+d%k)%7

4

PHP - 101 97 103 125 символів

  • Алгоритм сакамото
  • 0 = неділя

Код

<?php fscanf(STDIN,"%4d%2d%2d",$y,$m,$d);@$a=a032503514624;$y-=$m<3;$z=$y+1;echo($y+$y/4%$z-$y/100%$z+$y/400%$z+$a[$m]+$d)%7;

Примітка

На жаль, завдяки динамічній, слабкій типізації PHP, алгоритм Сакамото не працює належним чином без явного підлоги кожної операції поділу.


Чи можете ви протестуйте ще раз? Деякі роки це дає мені різні результати (наприклад, тестовий зразок 17760704 приносить вівторок замість середи).
Говард

@Howard, що дуже дивно; за 17760704, я отримую середу. Однак у мене виникають інші невідповідності, яких я не можу пояснити, наприклад, 19040229 повертається у вівторок. Не впевнений, що може спричинити це. Я отримую ті ж результати, коли знову розширюю алгоритм y+y/4-y/100+y/400.
rintaun

Я бачу, що це відбувається з 497 * у / 400: y=4у такому випадку повертається 4, а не правильне 5 з y+y/4+y/100+y/400(де грають лише перші два терміни). Це те, на що моє відповідь на JavaScript. Чи можливо, що замість ints створюються парні? (Мій PHP занадто слабкий, щоб знати.)
DocMax

@DocMax: Якщо залишити розширений вираз, такий же результат (497y / 400 має бути еквівалентним: y / 100 віднімається, а y / 400 додається знову незалежно). Я здогадуюсь, що PHP просто рубає все після десяткових, а не округляє. Я перевірив це шляхом округлення перед модулем. Це виправляє дві аномалії, але 19040229 все одно повертає той самий результат. Будь-які інші ідеї?
rintaun

@rintaun я не думаю, що це округлення. Вони принципово різні. Візьмемо приклад зверху (y = 4): 497 * 4/400 = 1988/400 = 4, але з іншого боку 4 + 4 / 4-4 / 100 + 4/400 = 4 + 1-0 + 0 = 5 . Терміни / 100 і / 400 отримують занадто велику вагу у вашому розрахунку, щоб 2000 року досягти неможливо.
Говард

2

С - 129

main(y,m,d,s)
{
    scanf("%04d%02d%02d",&y,&m,&d);
    y-=s=86400;
    d+=y+"-addgbegcfadf"[m];
    m>2?y++:0;
    putchar(48+(d+y/4-y/100+y/400+s+s)%7);
}

Це зловживає способом округлення поділу до нуля, принаймні в моїй системі (Linux x86).

Чарівна константа 86400, служить двом цілям:

  • Віднімайте рік, щоб зробити його негативним, не впливаючи на день тижня. Це робить його таким чином, підрозділи будуть округлюватися, а не знижуватися.
  • Змініть номер дня, тому понеділок буде 0.

Також трапляється кількість секунд за день.


Використовуйте y+=m>2;замість цього m>2?y++:0;і поголіть кілька байт.
Ясніше

2

Javascript, 126 123 символів

Використання алгоритму Сакамото з 0 = неділя:

prompt().replace(/(....)(..)(..)/,function(_,y,m,d){y-=m<3;alert((+d+y-~(y/4)+~(y/100)-~(y/400)+ +".621462403513"[+m])%7)})

Я підозрюю, що підрозділи можуть бути згорнуті, але зараз я цього не бачу.

Редагування: Покращено підрозділи (не потрібно, ~~коли можна просто ~).


2

Python 2 , 83 116 113 109 байт

Реалізує алгоритм Сакамото . Пропозиції з гольфу вітаються. Спробуйте в Інтернеті!

Редагувати: я повинен був це виправити століттями. -6 байт з пропозицій Джонатана Аллана +2 байти для фактичного виправлення коду.

def w(s):m=int(s[4:6]);y,d=int(s[:4])-(m<3),int(s[6:]);return(y+y/4-y/100+y/400+int('032503514624'[m-1])+d)%7

Вхід повинен бути одним рядком.
msh210

int('032503514624'[m-1])економить 6
Джонатан Аллан

0

Perl - 110 байт

Ось рішення, яке потрібно запустити з perl -p source.pl АБО perl -pe 'here-is-code'.

s/((..)(..))(..)(..)/(1+3*$1+$2-2*($1%4+$2%4)-(2<$4?$4+(1&$4&&4-(8&$4)):(2^$4)+(!($3%4)-!-$3+!($2%4)))+$5)%7/e

Просто скопіюйте вставку тестових випадків у stdin.

Це здається єдиним кодом без змінних, рядкових констант і поділів.


0

JavaScript (ES6), 73 байти (неконкурентоспроможний)

d=>(w=new Date(d[s="slice"](0,4),d[s](4,6)-1,d[s](-2)).getDay())-(w?1:-6)

Спробуй це

f=
d=>(w=new Date(d[s="slice"](0,4),d[s](4,6)-1,d[s](-2)).getDay())-(w?1:-6)
o.innerText=f(i.value="59161021")
oninput=_=>i.value.length==8&&(o.innerText=f(i.value))
<input id=i type=number><pre id=o>


Чому не змагаються?
програміст5000

@ programmer5000, ознайомтеся з датою опублікування виклику;)
Шагі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.