प्राइम टाइम यात्रा


23

किसी को मत बताना, लेकिन मैंने अपने चाचा के टाइम ट्रैवल मशीन को बंद कर दिया है! हालाँकि, मेरे चाचा प्राइम नंबरों के प्रति आसक्त हैं, और वह मशीन में शो करते हैं - उन्होंने इसे क्रमबद्ध किया है ताकि यह केवल उन नंबरों पर जा सके जो एक प्राइम नंबर तक हैं।

इसलिए यह 1947-08-151947 + 8 + 15 = 1970 पर नहीं जा सकता, जो कि एक प्रमुख संख्या नहीं है। यह जा सकता है 1947-07-25, क्योंकि 1947 + 7 + 25 = 1979, जो कि प्रमुख है। इसलिए अगर मैं भारत के स्वतंत्रता समारोह को देखने के लिए वापस जाना चाहता हूं, तो ऐसा लगता है कि मुझे कुछ हफ्ते पहले जाना होगा और उन 20 दिनों का इंतजार करना होगा।

मेरे पास कुछ अन्य तिथियां हैं, जिन्हें मैं जाना चाहता हूं, और मुझे इसी तरह अपनी तिथि से पहले (या यदि मैं भाग्यशाली हूं, तो) एक तारीख पर जाना होगा, जो एक प्रमुख संख्या तक होती है। हालांकि, मैं अधीर हूं, और बहुत ज्यादा इंतजार नहीं करना चाहता हूं - इसलिए मैं वह तिथि ढूंढना चाहता हूं जो मैं उपयोग कर सकता हूं जो मेरी लक्षित तिथि के सबसे करीब है।

क्या आप मुझे एक कार्यक्रम लिख सकते हैं जो मेरी लक्षित तिथि लेता है और मुझे वह तारीख देता है जो मुझे टाइम मशीन में इनपुट करनी चाहिए - दी गई तारीख से पहले या उसके बराबर निकटतम तारीख जिसके पुर्जे एक अभाज्य संख्या में जोड़ते हैं?

(इस चुनौती के लिए, हम प्रोलेप्टिक ग्रेगोरियन कैलेंडर का उपयोग कर रहे हैं - जिसका अर्थ है कि हम वर्तमान ग्रेगोरियन कैलेंडर का उपयोग उस अवधि के लिए भी करते हैं, जब लोग पुराने जूलियन कैलेंडर का उपयोग कर रहे थे।)

इनपुट

  • एक तिथि
    • आदर्श रूप से, वर्तमान युग (एडी) में कोई भी तारीख; व्यावहारिक रूप से, आपकी भाषा का जो भी उपसमुच्चय है वह स्वाभाविक रूप से संभाल सकता है
    • किसी भी एकल मानव-पठनीय स्वरूप में

उत्पादन

  • इनपुट तिथि के निकटतम तारीख, जो इनपुट से कम या बराबर है और जिसकी तिथि + माह + वर्ष एक प्रमुख संख्या तक है।
    • किसी भी एकल मानव-पठनीय स्वरूप में

⁺: "मानव पठनीय" दिन के रूप में, महीने और साल में सभी अलग-अलग वर्तनी, जो भी आदेश में

परीक्षण के मामलों

1947-08-15
=> 1947-07-25
1957-10-04
=> 1957-09-27
1776-07-04
=> 1776-07-04
999-12-12
=> 0999-12-10
2018-06-20
=> 2018-06-15
1999-01-02
=> 1998-12-29
1319-12-29
=> 1319-07-01

(सवाल के साथ मदद के लिए @ शागी, @ पेटरटायलर, और @ अरनौल का शुक्रिया।)


क्या आउटपुट में बकवास समय होना ठीक है? (उदाहरण Fri Jul 25 02:46:39 CEST 1947)
14

@wastl हाँ, जब तक कि तारीख की जानकारी आउटपुट का एक सन्निहित स्थिर लंबाई है (तो उस विशेष उदाहरण के लिए नहीं)।
सूंदर -

जवाबों:



4

जावास्क्रिप्ट (Node.js) , 94 बाइट्स

3 वाक्य के रूप में इनपुट को सिंटेक्स में करीने से लेता है (year)(month)(day)। एक अग्रणी हाइफ़न के साथ एक हाइफ़न-पृथक स्ट्रिंग लौटाता है।

y=>m=>g=d=>(P=k=>n%++k?P(k):~k)(n=eval(s='-'+new Date(y,m-1,d).toJSON().split`T`[0]))?g(d-1):s

इसे ऑनलाइन आज़माएं!

कैसे?

हम पहले तिथि को JSON प्रारूप yyyy-mm-ddT00:00:00.000Z( ISO 8601 ) में परिवर्तित करते हैं , इस पर विभाजित करते हैं 'T', केवल बाएं भाग को रखते हैं और एक अग्रणी हाइफ़न जोड़ते हैं, जो देता है -yyyy-mm-dd

s = '-' + new Date(y, m - 1, d).toJSON().split`T`[0]

यह अभिव्यक्ति रों अब किया जा सकता है eval()'विपरीत पाने के लिए uated n के योग का साल + माह + दिन

n = eval(s)

हम हेल्पर फंक्शन P () का उपयोग करके यह परखते हैं कि क्या -n प्राइम है (किस स्थिति में यह 0 है )। अगर ऐसा है, हम वापसी रों । अन्यथा, हम पिछले दिन के साथ फिर से प्रयास करते हैं।

(P = k => n % ++k ? P(k) : ~k)(n) ? g(d - 1) : s

1
मुझे ऐसा लगता है कि मुझे यह समझने से बस एक दिन की आवश्यकता है कि प्रधान जाँच कैसे कार्य करती है और समाप्त होती है। अच्छा गोल्फ!
सूंदर -

3

पायथन 2 , 130 127 बाइट्स

इनपुट है year, month, day

-3 बाइट्स केविन क्रूज़सेन की बदौलत

from datetime import*
def f(a):
  while(lambda n:any(n%m<1for m in range(2,n)))(a.year+a.month+a.day):a-=timedelta(1)
  print a

इसे ऑनलाइन आज़माएं!


आपको इनपुट के रूप में एक दिनांक-ऑब्जेक्ट लेने की अनुमति है, जिससे आप 3 बाइट्स बचा सकते हैं ।
केविन क्रूज़सेन

1
@KevinCruijssen धन्यवाद। क्या आपको लगता है कि यह एक वैध इनपुट प्रारूप है?
अंडा

मैं नहीं देखता कि यह क्यों नहीं होगा, इसलिए यह एक और -4 है। उस बारे में सोचा नहीं था।
केविन क्रूज़सेन

2

जावा 8, 144 128 बाइट्स

d->{for(;;d=d.minusDays(1)){int n=d.getYear()+d.getMonthValue()+d.getDayOfMonth(),i=2;for(;i<n;n=n%i++<1?0:n);if(n>1)return d;}}

इसे ऑनलाइन आज़माएं।

java.time.LocalDateवर्ग वर्ष की तुलना में एक सुधार किया गया है java.util.Date(, लेकिन क्यों किया था वे अब उन नामों करना था getMonthValueऔर getDayOfMonthबजाय getMonthऔर getDay) ..>।>

स्पष्टीकरण:

d->{                      //  Method with LocalDate as both parameter and return-type
  for(;;                  //  Loop indefinitely
      d=d.minusDays(1)){  //    Going one day back after every iteration
    int n=d.getYear()+d.getMonthValue()+d.getDayOfMonth(),
                          //   Set `n` to the sum of year+month+day
    i=2;for(;i<n;n=n%i++<1?0:n);if(n>1)
                          //   If `n` is a prime:
      return d;}}         //    Return the now modified input-LocalDate `d`

2

रूबी , 94 बाइट्स

इसे ऑनलाइन आज़माएं!

एकल दिनांक इनपुट लेता है, और ISO 8601 प्रारूप ( YYYY-MM-DD) में एक स्ट्रिंग लौटाता है ।

require'date'
require'prime'
->d{d.downto(0){|i|break i.to_s if (i.day+i.month+i.year).prime?}}

यह रूबी के प्राइम मॉड्यूल का उपयोग करता है। यदि यह अनुमति नहीं है, या पर फेंक दिया है, तो दो बाइट्स के लिए मैं यह घृणा प्रस्तुत करता हूं:


रूबी , 97 बाइट्स

इसे ऑनलाइन आज़माएं!

यह इस स्टैकओवरफ़्लो उत्तर से अभाज्य संख्या के लिए एक चेक का उपयोग करता है । मुझे नहीं पता कि यह कैसे काम करता है, यह जादू टोना जैसा दिखता है। ऊपर जैसा ही इनपुट, और वैसा ही आउटपुट।

require'date'
->d{d.downto(0){|i|break i.to_s if ?1*(i.day+i.month+i.year)!~ /^1?$|^(11+?)\1+$/}}

मॉड्यूल का उपयोग करना तब तक पूरी तरह से ठीक है जब तक कि बाइट काउंट (जो आपने यहां किया है) में आयात लाइनें शामिल हैं। ऐसा लगता है कि आपको प्रारंभिक dऔर अंतरिक्ष के आसपास के पेरेन्थेस की आवश्यकता नहीं है if, हालांकि उसके बाद , इसलिए आप अपने पहले उत्तर से 3 बाइट्स को हटा सकते हैं। TIO लिंक
सूंदर -

3
मैं witchcrafty घृणा हालांकि पसंद है। एक बार देखने के बाद यह बहुत साफ और सरल है: ?x*n !~ /^x?$|^(xx+?)\1+$/= यदि n अभाज्य है, की जाँच करने के लिए, n 'x's का एक स्ट्रिंग बनाएं, यह देखें कि यह 0 या 1 x का नहीं है (जो अभाज्य नहीं है), और यह कि यह किसी से मेल नहीं खाता है 2 या अधिक x का स्वयं को दोहराना (मिलान ^(xxxxx)\1+$का मतलब n 5 से विभाज्य है)। यह हमारे लिए लूपिंग करने के लिए रेगेक्स इंजन के पीछे हटने का दुरुपयोग करता है - यह शानदार है, यह राक्षसी है, और पशु बलि शायद इसकी खोज में शामिल था।
सूंदर -

कोष्ठक और अंतरिक्ष के बारे में अच्छी जगह! धन्यवाद।
IMP1

"जादू टोना" संस्करण 92 बाइट्स में किया जा सकता है, यहां देखें । क्योंकि जिस राशि को हम प्राणशक्ति के लिए जाँचना चाहते हैं वह कम से कम 3 है (न्यूनतम तिथि 0001-01-01 से लेकर 1 + 1 + 1 = 3 तक), हम विशेष रूप से इनपुट 0 को संभालने के लिए विशेष रूप से रेगेक्स के हिस्से को हटा सकते हैं। 1. इसे हटाने और सरलीकृत करने से 91 बाइट संस्करण मिलता है।
सूंदर -

एक दिलचस्प दृष्टिकोण। Tes महीने ’के बजाय 'सोम’ का उपयोग करके 2 बाइट्स बचाएं
जीबी

2

रूबी , 57 53 बाइट्स

->d{d-=9until/^(11+)\1+$/!~?1*(d.day+d.year+d.mon);d}

इसे ऑनलाइन आज़माएं!

मेरा विचार नहीं - IMP1 द्वारा "घृणा" से चोरी


मूल विचार:

रूबी , 59 बाइट्स

->d{d-=9until((2...w=d.day+d.year+d.mon).all?{|x|w%x>0});d}

इसे ऑनलाइन आज़माएं!


1
8e4काम के बजाय उपयोग करना चाहेंगे ?
कृति लिथोस

हां, निश्चित रूप से यह काम करता है। यह 9 या किसी अन्य छोटी संख्या का उपयोग करके भी काम करता है। इसे चलाने में केवल बहुत अधिक समय लगता है। धन्यवाद।
जीबी


2

एफ #, 134 133 बाइट्स

let rec s(d:System.DateTime)=
 let x=d.Year+d.Month+d.Day
 if(Seq.tryFind(fun i->x%i=0){2..x-1}).IsNone then d else d.AddDays(-1.)|>s

-1 बटर सूंदर से धन्यवाद ।

इसे ऑनलाइन आज़माएं!

कुल दिन, महीने और साल और देखें कि क्या यह प्रमुख है। यदि ऐसा है, तो उस तारीख को वापस करें। यदि नहीं, तो तारीख को 1 दिन घटाएं और फिर से प्रयास करें।


1
आप AddDays कॉल में, -1.0जैसा कि लिखकर एक बाइट बचा सकते हैं -1.
सूंदर -

तुम सही हो ... यह वास्तव में अजीब है। लेकिन उपयोगी है। धन्यवाद।
सियारन_मस्कारी

1

पॉवरशेल , 105 90 बाइट्स

for($a=$args[0];'1'*((Date $a -f yyyy+MM+dd)|iex)-match'^(..+)\1+$';$a=$a.AddDays(-1)){}$a

इसे ऑनलाइन आज़माएं!

-13 बाइट्स के लिए सूंदर का धन्यवाद।

एक के रूप में इनपुट लेता है DateTime 2018-06-20और इसे बचाता है $a। फिर हम एक forपाश में हैं। प्रत्येक पुनरावृत्ति, हम $a -formatted ले रहे हैं yyyy+MM+dd(जैसे, वर्तमान दिनांक हम +संकेतों द्वारा अलग किए गए हैं) |iex(समान eval) के साथ एक साथ जोड़ा गया है , स्ट्रिंग-गुणा करना है जिसमें 1s के साथ एक संयुक्त संख्या है, और एक प्राइम-चेकिंग regex का उपयोग कर यह निर्धारित करने के लिए कि वर्तमान तिथि प्रधान है या नहीं। यदि यह प्रमुख नहीं है, तो हम .AddDays(-1)एक दिन पीछे की ओर जाते हैं और लूप जारी रखते हैं। यदि यह प्रधान है, तो हम लूप से बाहर निकलते हैं और $aअंतर्निहित आउटपुट के साथ पाइप लाइन पर जगह बनाते हैं।

परिणामी उत्पादन संस्कृति-निर्भर है। TIO पर, जो उपयोग करता है en-us, आउटपुट लॉन्ग-डेट फॉर्मेट है, जो दिखता है Saturday, July 1, 1319 12:00:00 AM


आप तर्क को डेटाटाइम ऑब्जेक्ट के रूप में भेजकर कुछ बाइट्स बचा सकते हैं। इसके अलावा, रेगेक्स को 2 से ऊपर कंपोजिट से मिलान करने के लिए सरल बनाया जा सकता है (चूंकि न्यूनतम तिथि 0001-01-01जिसका योग 3 है)। मैंने यहाँ इन परिवर्तनों पर एक दरार ले ली ।
सूंदर -

(ध्यान दें कि मैं एक शक्तियुक्त नौसिखिया हूँ और यह जुड़ा हुआ कोड केवल न्यूनतम परीक्षण किया गया है, यहाँ से भी सभी परीक्षण मामलों की कोशिश नहीं की है।)
sundar -

@sundar मैंने उस इनपुट के बारे में सोचा, लेकिन यह मुझे थोड़ा "धोखा" लग रहा था, इसलिए मैं इसके बजाय स्ट्रिंग इनपुट के साथ गया। रेगेक्स पर टिप के लिए धन्यवाद - मुझे पूरी तरह से समझ में नहीं आता है कि यह कैसे काम करता है, इसलिए मैं सिर्फ मुस्कुराता हूं और ऊपर आने पर सिर हिलाता हूं। हेहे।
AdmBorkBork

1

बैश , 114 108 बाइट्स

a=`date +%s -d$1`
while [ "`date +%d+%m+%Y -d@$a|bc|factor|awk NF!=2`" ]
do a=$[a-86400]
done
date +%F -d@$a

इसे ऑनलाइन आज़माएं!

मेरा पहला बैश गोल्फ। ईमानदारी से कहूं तो मेरा पहला असली बैश प्रोग्राम है ... यहां से लिया गया प्राइमलिटी टेस्ट ।

समय-सीमा में बदलाव होने पर यह कभी-कभी विफल हो सकता है, लेकिन TIO UTC का उपयोग करता है, इसलिए वहां इसे काम करना चाहिए।


क्या पहली पंक्ति में "9" एक टाइपो है? उस और उसके आसपास के उद्धरणों को हटाना (क्योंकि हमें आवश्यकता हो सकती है कि इनपुट में रिक्त स्थान नहीं होना चाहिए), और इसके बाद के अंत में एक जोड़ना @$, 110 बाइट्स पर काम करने वाला कोड देता है ।
सूंदर -

@ सूंदर मुझे लगा कि दिन के उजाले के समय की समस्या हो सकती है, लेकिन मैं कल फिर से जाँच
करूँगा

1

सी (जीसीसी) , 167 बाइट्स

r;P(n,i){for(r=0;++i<n;)r|=n%i<1;}f(y,m,d){for(;P(y+m+d,1),r;)!--d?d=" >8><><>><><>"[!--m?y--,m=12:m]/2+(m==2&!(y%4)&y%100|!(y%400)):0;printf("%04d-%02d-%02d",y,m,d);}

इसे ऑनलाइन आज़माएं!

मंद होना

r;P(n,i){for(r=0;++i<n;)r|=n%i<1;}

एंटी-प्राइम-चेकिंग फ़ंक्शन। चूंकि जल्द से जल्द वैध वर्ष के लिए हमें 0001-01-01 से निपटने की आवश्यकता है, इसलिए हमें सबसे कम संख्या की चिंता करने की आवश्यकता है 3, इसलिए n == 2 या n <2 के लिए विशेष-मामले की जांच छीन ली गई है। r एक सत्य मान पर सेट है अगर n एक अभाज्य नहीं है। r को वैश्विक रखा गया है, क्योंकि इसे वापस नहीं करने पर दो बाइट्स ( वैश्विक जांचने के लिए i=n;बनाम लौटने के ,rलिए) की बचत होती है । मैं फ़ंक्शन कॉलर द्वारा 1 पर सेट किया गया है, एक और 2 बाइट्स को बचाने के लिए।

f(y,m,d){for(;P(y+m+d,1),r;)

हम तारीख को तीन अलग-अलग पूर्णांकों के रूप में लेते हैं और मुख्य लूप शुरू करते हैं, जो कि y + m + d तक प्रधान है। फिर हम फ़ंक्शन के मांस पर आते हैं:

!--d?                           Decrement day and check if zero, which means we go back to last day of previous month.
d=" >8><><>><><>"               The string contains the number of days of each month times 2, to bring them into printable ASCII range.
                                We begin the string with a space, to avoid having to substract from index later.
[!--m?y--,m=12:m]/2+            Decrement month and check if zero. If so, go back a year and set m to 12. Use m as index in string.
(m==2&!(y%4)&y%100|!(y%400))    If the new month is February, add 1 to day if it's a leap year.
:0;                             Do nothing if day did not become zero.

मूल्यांकन के आदेश के अनिर्दिष्ट होने पर यह लीप वर्ष की जाँच में और स्ट्रिंग के सूचकांक के रूप में m और y दोनों का उपयोग करने के लिए iffy लग सकता है। सौभाग्य से, हम केवल m == 2 के लिए लीप वर्ष की जांच करते हैं, जो कि उसी समय में नहीं हो सकता है जब हम m और y को बदलते हैं, क्योंकि यह केवल जनवरी से दिसंबर तक होता है, इसलिए लीप वर्ष की जांच कभी भी परेशान नहीं होती है मूल्यांकन का क्रम।

अंत में, परिणाम STDOUT में मुद्रित किया जाता है:

printf("%04d-%02d-%02d",y,m,d);}

0

सी # - 281 239 232 चार

using System;class P{static void Main(){var d=DateTime.Parse(Console.ReadLine());do{int c=d.Year+d.Month+d.Day;if(c%2!=0){int i=3;for(;i<=c;i+=2)if(c%i==0)break;if(i>=c)break;}d=d.AddDays(-1);}while(d>DateTime.MinValue);Console.WriteLine(d);}}

ungolfed:

using System;
class P
{
    static void Main()
    {
        var d = DateTime.Parse(Console.ReadLine());
        do
        {
            int c = d.Year + d.Month + d.Day;
            // minimum datetime in c# is 0001-01-01
            // therefore do not need to check for the first two primes 
            int i = 3;
            for (; i < c; i += 2) if (c % i == 0) break;
            // check to break the date decrement loop if counter passed the input value
            // ie, no factor could be found
            if (i >= c) break;

            d = d.AddDays(-1);
        } while (d > DateTime.MinValue);
        Console.WriteLine(d);
    }
}

कोड को कम कुशल लेकिन छोटा बनाया। प्राइम लूप अब वर्गमूल के बजाय पूर्णांक तक जाएगा। यह सभी सम संख्याओं को भी प्रोसेस करेगा।


आप शायद निकाल सकते हैं public। इसके अलावा, चूंकि कॉलिंग पैरामीटर के रूप में दिनांक इनपुट प्राप्त करने के लिए इसे अस्वीकृत नहीं किया जा सकता है, इसलिए आपके पास हो सकता है Main(string[]a)और फिरDateTime.Parse(a[0])
Corak

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