दो दिनों के अंतर की गणना करें।


11

एक और तारीख-हेरफेर समस्या: पी

कार्य

एक प्रोग्राम या एक फ़ंक्शन लिखें जो उपयोगकर्ता द्वारा दी गई दो तिथियों के बीच अंतर की गणना करता है।

इनपुट आउटपुट

पिछले एक के समान , इनपुट दो YYYYMMDDएस हैं, एक अंतरिक्ष , एक अल्पविराम ,, या एक शून्य चिह्न द्वारा अलग किए गए हैं -

इनपुट मानों का उदाहरण:

20100101-20010911
20110620-20121223
19000101 20101010
33330101,19960229
00010101 99991231

आउटपुट एक पूर्णांक है, जो दिनों में दो तिथियों के बीच अंतर है।

उदाहरण के लिए, इनपुट 20110101-20100101पैदावार 365, और 33320229 17000101पैदावार 596124

आप परिणामों का परीक्षण कर सकते हैं यहा पर यहाँ पर । (रिंटन की टिप्पणी नीचे देखें।) यदि दो तिथियां समान हैं, तो कार्यक्रम को वापस आ जाना चाहिए 0, यदि तिथि मान्य है ( स्कोर देखें )।

बंधन

बेशक, आपको किसी भी प्रकार के फ़ंक्शन / वर्ग / ... का उपयोग नहीं करना चाहिए , जो टाइमस्टैम्प या दिनांक से संबंधित हैं, और आपको ग्रेगोरियन कैलेंडर का उपयोग करना चाहिए ।

स्कोर

यदि आपका कोड प्रतिबंध नहीं रखता है, तो score = -∞

डिफ़ॉल्ट bonus1 है।

  • यदि आपका कोड इनपुट के क्रम की परवाह किए बिना काम करता है (उदाहरण के लिए, 20100101,20110101रिटर्न 365या -365) bonus+=1,।
  • यदि आपका कोड वर्ष 0 को संभाल सकता है , तो bonus+=0.5
  • यदि आपका कोड अमान्य माह (1 ~ 12 के बीच) / दिनांक (1 ~ 31 के बीच) को पहचानता है, जैसे 20109901या 34720132, और प्रिंट E(और प्रोग्राम को समाप्त करता है या ऐसा कुछ देता है 0) bonus+=1,।
  • उपर्युक्त नियम के बावजूद, अपने कोड अमान्य दिनांक, जैसे को मान्यता देता है 20100230, 20100229या 20111131, और प्रिंट E(और समाप्त हो जाता है की तरह कार्यक्रम या रिटर्न कुछ 0), bonus+=1
  • उपरोक्त दो नियमों के बावजूद, यदि आपका कोड अमान्य इनपुट स्ट्रिंग को पहचानता है, जैसे 20100101|20100202या 2010010120100202, और प्रिंट E(और प्रोग्राम को समाप्त करता है या ऐसा कुछ देता है 0) bonus+=1,।

score = floor(-4.2*code.length/bonus)। उच्चतम स्कोर जीत के साथ कोड। यदि दो शीर्ष कोड में समान स्कोर है, तो उच्चतम बोनस जीत के साथ कोड। यदि दो शीर्ष कोड में समान स्कोर और बोनस दोनों हैं, तो उच्चतम वोटों वाले कोड जीतते हैं।

(वहां: जब 5 से अधिक कोड हों, जिनमें +1वोट (या बराबर) से अधिक हों ।)


क्या 20030229 को तीसरे बोनस द्वारा अमान्य तिथि माना जाता है?
rintaun

@rintaun हां। इसके विपरीत यह अमान्य है 20040229। : P
JiminP

1
क्या वुल्फरामअल्फा वास्तव में सही परिणाम देता है? मैं से जवाब परस्पर विरोधी हो रही है यह और timeanddate.com । मेरा कार्यक्रम, जो मुझे लगता है कि सही ढंग से काम कर रहा है (कम से कम उस उदाहरण में: पी), बाद वाले से सहमत है।
जूनुन

@rintaun मुझे लगता है कि वुल्फराम | अल्फा गलत था, 365*4 + 2 + 2= 1464 के बाद से । जानकारी के लिए धन्यवाद!
जमिनपी

1
यह ध्यान दिया जाना चाहिए कि यहां तक ​​कि timeanddate.com के साथ भी, कुछ समस्याएं हैं: यह केवल 1-3999 साल स्वीकार करता है, और यह जूलियन और ग्रेगोरियन कैलेंडर के बीच 11-दिन की विसंगति के लिए ऑटो को समायोजित करता है, जो 3 सितंबर, 1752 से पहले की तारीखों के लिए है। (इसलिए 17520914 के माध्यम से 17520903 वैध तिथियां नहीं हैं)। परिणाम का परीक्षण करते समय इसे ध्यान में रखें।
१६:

जवाबों:


3

पर्ल 5.14, स्कोर = -162

-163 -181 -196 -214 -167 -213 -234
  • code.length = 211: 208 स्रोत अक्षर + 3 -pविकल्प के साथ पर्ल चलाने के लिए
  • बोनस = 5.5: डिफ़ॉल्ट, आदेश, वर्ष 0, कभी-मान्य महीना / दिन, अमान्य दिनांक, पूर्ण-अमान्य इनपुट

कोड

$_=eval(join'-',map{($y,$m,$d)=/(....)(..)(..)/;die"E\n"if!($m*$d)||$m>12||$d>30+($m&1^$m>7)-($m==2)*(2-!($y=~s/00$//r%4));$y-=($m<3)-400;$d+int(($m+9)%12*30.6+.4)+int(365.2425*$y)}/^(\d{8})[ ,-](\d{8})$/)//E

प्रत्येक तिथि के लिए एक संशोधित जूलियन दिन संख्या की गणना करता है (कोड लंबाई को बचाने के लिए युग से संबंधित समायोजन की अनदेखी) और दोनों को घटाता है। (Ref। "जूलियन डे" विकिपीडिया पर )।

  • /rप्रतिस्थापन पर विकल्प के लिए perl 5.14+ की आवश्यकता होती है
  • अमान्य दिनांक बोनस प्राप्त करने के लिए महीने की लंबाई की गणना: 30+($m&1^$m>7)भाग किसी भी महीने की लंबाई देता है लेकिन फरवरी; बाकी एक साधारण या लीप वर्ष में फरवरी के लिए समायोजित करता है

मान्यताओं

  • "ग्रेगोरियन कैलेंडर का उपयोग करें" का अर्थ है जूलियन से ग्रेगोरियन संक्रमण से पहले के तारीखों के लिए प्रोलेप्टिक ग्रेगोरियन कैलेंडर। अर्थात्, अंतराल को पार करने के लिए 11 दिनों को घटाएं नहीं, उदाहरण के लिए, 3 सितंबर 1752 - 14 सितंबर 1752 ब्रिटिश संक्रमण।
  • "हैंडल वर्ष 0" का अर्थ है, उदाहरण के लिए, 00000101-00010101366 देना चाहिए, क्योंकि 0 400 का एक अभिन्न गुणक है, और इसलिए वर्ष 0 एक लीप वर्ष है।

आपके द्वारा किए गए परिवर्तनों के साथ, ऐसा लगता है कि आपका कार्यक्रम अब अमान्य महीनों और दिनों को 20111300-20119999रिटर्न की तरह स्वीकार करता है 2717
मिगिमारू

@ मिमिमारु: मैंने वास्तव में शुद्धता को अनुकूलित किया है। अरे। मैं संपादित करूँगा और हो सकता है कि यह वापस आ जाए।
DCharness

2

पीएचपी, स्कोर: -539.1

  • 706 वर्ण
  • सभी बोनस आइटम; बोनस = 5.5

कोड

<?php $a='(\d{4})(0[0-9]|1[0-2])([0-2][0-9]|3[01])';@$p=preg_match;if(!$p('/^(\d{8})[- ,](\d{8})$/',fgets(STDIN),$z))@die(E);unset($z[0]);sort($z);foreach($z AS$x){if(!$p('/(\d{4})(0[0-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])/',$x,$w))die(E);$n[]=$w;}$m=array(31,28,31,30,31,30,31,31,30,31,30,31);$r=0;$b=$n[0][1];$c=$n[0][2];$d=$n[0][3];$e=$n[1][1];$f=$n[1][2];$g=$n[1][3];@$t=str_pad;if((($b.$e==229)&&(!(!($b%4)+!($b%100)-!($b%400))))||($c>12))die(E);for($z=$b.$c.$d;;$s=$d,$r++){if($z==$e.$f.$g)break;if($z>$e.$f.$g)@die(E);if(@$s==$d)$d++;if((($c!=2)&&($d>$m[$c-1]))||(($c==2)&&($d>($m[$c-1]+!($b%4)-!($b%100)+!($b%400))))){$c++;$d=1;}if($c>12){$b++;$c=1;}$z=$b.$t($c,2,0,0).$t($d,2,0,0);}echo($r>0)?--$r:0;

Ungolfed

<?php
$a='(\d{4})(0[0-9]|1[0-2])([0-2][0-9]|3[01])';
@$p=preg_match;
if(!$p('/^(\d{8})[- ,](\d{8})$/',fgets(STDIN),$z)) @die(E);
unset($z[0]);
sort($z);
foreach($z AS $x)
{
        if (!$p('/(\d{4})(0[0-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])/',$x,$w)) die(E);
        $n[]=$w;
}
$m=array(31,28,31,30,31,30,31,31,30,31,30,31);
$r=0;
$b=$n[0][1];
$c=$n[0][2];
$d=$n[0][3];
$e=$n[1][1];
$f=$n[1][2];
$g=$n[1][3];
@$t=str_pad;
if ((($b.$e==229)&&(!(!($b%4)+!($b%100)-!($b%400))))||($c>12)) die(E);
for ($z=$b.$c.$d;;$s=$d,$r++)
{
        if ($z==$e.$f.$g)break;
        if ($z>$e.$f.$g)@die(E);
        if (@$s==$d)$d++;
        if ((($c!=2)&&($d>$m[$c-1]))||(($c==2)&&($d>($m[$c-1]+!($b%4)-!($b%100)+!($b%400)))))
        {
                $c++;
                $d=1;
        }
        if ($c>12)
        {
                $b++;
                $c=1;
        }
        $z=$b.$t($c,2,0,0).$t($d,2,0,0);
}
echo($r>0)?--$r:0;

ध्यान दें

प्रदान की गई दोनों के बीच प्रत्येक वैध तारीख के माध्यम से पुनरावृत्ति करके दिनों की संख्या की गणना करता है। यह बड़ी रेंज पर बहुत धीमा है। मुझे यकीन है कि यह इसे हल करने का सबसे अच्छा तरीका नहीं है, लेकिन मैं अधीर हो गया, और यही मैं के साथ समाप्त हुआ। :)

इसके अलावा, मुझे पता है कि "ungolfed" कोड अभी भी बहुत पठनीय नहीं है, लेकिन इसे फिर से लिखना पूरी तरह से बहुत प्रयास की आवश्यकता होगी।


2

रूबी 1.9, स्कोर: -175 -186 -191 -199

  • कोड की लंबाई: 229 243 250 260 वर्ण
  • बोनस: 5.5 (डिफ़ॉल्ट, आदेश, वर्ष 0, अमान्य महीना / दिन, अमान्य दिनांक, अमान्य इनपुट)

कोड स्टड के माध्यम से इनपुट स्वीकार करता है।

h=->n{n/4-n/100+n/400+1}
u,v=gets.split(/[ ,-]/).map{|s|s=~/^\d{8}$/?(d,e,f=[s[0,4],s[4,2],s[6,2]].map &:to_i;x=[0,y=31,28+h[d]-z=h[d-1]]+[y,30,y,30,y]*2
(!x[e]||e*f<1||f>x[e])?0:d*365+z+eval(x[0,e]*?+)+f):0}
puts (v*u>0)?u-v :?E

टिप्पणियाँ:

  • h उस वर्ष तक लीप वर्ष की संख्या देता है (बोनस के लिए वर्ष 0 सहित)।
  • रेगेक्स अमान्य इनपुट बोनस को संभालता है।
  • (!x[e]||e*f<1||f>x[e])हालत अवैध महीना / दिन / तारीख बोनस संभालती है।
  • परिणाम को पहली तारीख के रूप में दूसरी तिथि के रूप में प्रदर्शित किया जाता है, इसलिए यदि दूसरी तारीख बाद में यह एक नकारात्मक संख्या के रूप में आउटपुट होगी।
  • जूलियन और ग्रेगोरियन कैलेंडर के बीच परिवर्तन के लिए समायोजित नहीं करता है, इसलिए 33320229 17000101परिणाम होता है 596134

मेरे समाधान की त्रुटि की जाँच करने और सुधार जारी रखने के लिए मुझे धकेलने के लिए धन्यवाद। मुझे विशेष रूप से आपकी फरवरी-लंबाई की गणना पसंद है।
DCharness

@DCharness मुझे भी धकेलने के लिए धन्यवाद। मुझे एहसास हुआ कि मेरे मूल सबमिशन में सुधार के लिए बहुत जगह थी।
मिगिमारू

1

पायथन, स्कोर: -478

  • वर्ण: 455
  • बोनस: रिवर्स डेट, अमान्य दिन / माह, अमान्य दिनांक

समाधान:

import re
a=re.split('[-, ]',raw_input())
def c(x):return x[0]
def f(x,y=3):return(1if x%400==0 or x%100!=0and x%4==0 else 0)if y>2 else 0
t=[31,28,31,30,31,30,31,31,30,31,30,31]
[q,w,e],[i,o,p]=sorted([map(int,[a[x][:4],a[x][4:6],a[x][6:]])for x in[0,1]],key=c)
print sum(map(f,range(q,i)))+(i-q)*365+p+sum(t[:o-1])-e-sum(t[:w-1])+f(i,o)-f(q,w)if 0<w<13and 0<e<32and 0<o<13and 0<p<32and(e<=t[w-1]or(f(q)and e==29))and(p<=t[o-1]or(f(i)and p==29))else 'E'

मेरे पास "ungolfed" संस्करण नहीं है क्योंकि मैंने इसे कैसे लिखा है। अगर आप बग ढूंढते हैं तो मैंने इसका ठीक से परीक्षण नहीं किया है - कृपया टिप्पणी करें।

संपादित करें: उम्मीद है कि एक बग निश्चित रूप से एक टिप्पणी में बताया गया है और [, बी], [सी, डी] = [[१,२], [३,४] के रूप में अनपैकिंग में जोड़ा गया है।


क्षमा करें, लेकिन जब मैंने पायथन 2.7 शेल के साथ परीक्षण किया, तो '20000001,20010101' जैसे अमान्य इनपुट प्रिंट नहीं होते हैं E। (FYI करें, 0>-1>12, 0>6>12, 0>13>12रिटर्न False।)
JiminP

धन्यवाद। मैं अजगर के लिए काफी नया हूं। इस स्क्रिप्ट को लिखने से मुझे पता चला कि अजगर इस x<y<zतुलना को करता है या ए x if y else z। इसे ठीक करने की कोशिश की।
rplnt

@rpInt: गोल्फ के लिए, वहाँ भी है [x,z][y]जो की तुलना में कम है x if y else z, हालांकि यह हमेशा काम नहीं करता है, अगर इसके विपरीत-अभिव्यक्ति यह आलसी नहीं है।
रेयान

1

पीएचपी, स्कोर: -516

chars: 685 676

बोनस: 5.5

<? $z='/((\d{1,4})(\d\d)(\d\d))[- ,]((\d{1,4})(\d\d)(\d\d))/';if(!preg_match($z,$argv[1],$m))die('E');$s=1;if($m[1]>$m[5]){if(!preg_match($z,"$m[5] $m[1]",$m))die('E');$s=-1;}$b=array(31,28,31,30,31,30,31,31,30,31,30,31);list($x,$v,$c,$d,$e,$w,$f,$g,$h)=$m;if($d>12||1>$d||$g>12||1>$g||1>$e||1>$h||($e>$b[$d-1]&&!($d==2&&$e<30&&$c%4==0))||($h>$b[$g-1]&&!($g==2&&$h<30&&$f%4==0)))die('E');$z='array_slice';$y='array_sum';$x=$d!=$g||$e>$h;$r=$x?$b[$d-1]+$h-$e:$h-$e;$d+=$x;if($d>12){$c++;$d=1;}$r+=$d>$g?$y($z($b,$d-1,13-$d))+$y($z($b,0,$g-1)):($d!=$g?$y($z($b,$d-1,$g-$d)):0);$r+=($f-$c-($d>$g))*365;for($i=$c;$i<=$f;$i++)if($i%4==0&&$i.'0229'>$v&&$i.'0229'<$w)$r++;echo $s*$r;

PHP कोड <?को चलाने के लिए शुरुआत में चाहिए, अन्यथा यह कोड को प्रिंट करता है।
गारेथ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.