दिनांक घटकों के लिए मानव पठनीय समय अंतराल परिवर्तित करें


16

चुनौती

सबसे छोटा कार्यक्रम लिखें जो प्रपत्र के दिनांक घटकों के लिए मानव पठनीय समय अंतराल को परिवर्तित करता है:

{±YEARS|±MONTHS|±DAYS|±HOURS|±MINUTES|±SECONDS}

नमूना मामलों

प्रत्येक परीक्षण के मामले में दो लाइनें हैं, इनपुट आउटपुट के बाद:

1 year 2 months 3 seconds
{1|2|0|0|0|3}

-2 day 5 year 8months
{5|8|-2|0|0|0}

3day 9     years 4 seconds -5 minute 4 years 4 years -3seconds
{17|0|3|0|-5|1}

नियम

  • आप उपयोग strtotimeया किसी भी अंतर्निहित फ़ंक्शन का उपयोग नहीं कर सकते हैं जो पूरी नौकरी करता है।
  • सबसे छोटा कोड जीत (बाइट्स)
  • आप अपने आउटपुट को stdoutएक फ़ाइल में प्रिंट कर सकते हैं , परिणाम भी एक फ़ंक्शन द्वारा वापस किया जा सकता है, यह आपके ऊपर है
  • टोकन एकवचन या बहुवचन रूप में हो सकता है।
  • घटक एक यादृच्छिक क्रम में हो सकते हैं
  • संख्या और टोकन के बीच कोई सफेद स्थान नहीं हो सकता है
  • समय अंतराल सकारात्मक होने पर साइन वैकल्पिक है (इनपुट और आउटपुट)
  • यदि एक घटक एक बार से अधिक बार दिखाई देता है, तो मूल्यों को जोड़ा जाना चाहिए
  • प्रत्येक घटक का अपना संकेत होता है
  • घटकों को अलग से संभाला जाना चाहिए (जैसे 80 minutesआउटपुट में 80 के रूप में रहता है)
  • इनपुट कम मामले की गारंटी है

हैप्पी गोल्फिंग!


2
मुझे यह चुनौती पसंद है, लेकिन मुझे एक कठिन समय आ रहा है जो कुछ भी नहीं है जो उन भाषाओं में लंबे और गन्दा नहीं है जो कोड गोल्फ के लिए बीमार हैं। : /
एलेक्स ए।

क्या आउटपुट स्वरूप मायने रखता है?
टाइटस

Sign is optional when the time interval is positiveक्या इसका मतलब यह है कि इनपुट में +संकेत हो सकते हैं ?
टाइटस

जवाबों:


3

सीजेएम, 60 बाइट्स

60 के लंबे समय तक अटके रहने के बाद, मैं आखिरकार इसे 60 बाइट तक निचोड़ने में कामयाब रहा। काफी है! इसे भेज दो!

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

squished:

'{0a6*q[{_A,s'-+#)!{"ytdhic"#:I){]'0+iA/I_3$=@+t[}*}*}/'|*'}

विस्तृत और टिप्पणी:

'{              "Add '{' to output";
0a6*            "Initialize time to a list of 6 zeros";
q               "Read the input";
[               "Open an empty numeric character buffer";
{               "For each character in the input:";
  _               "Append the character to the numeric character buffer";
  A,s'-+#)!       "Check if the character is not part of a number";
  {               "If so:";
    "ytdhic"#:I     "Remove the character from the numeric character buffer and
                     convert it to the corresponding time unit index, or -1 if
                     not recognized
                     (Time units are recognized by a character in their name
                     that does not appear before the recognition character
                     in any other name)";
    ){              "Repeat (time unit index + 1) times:";
      ]'0+iA/         "Close the numeric character buffer and parse it as an
                       integer (empty buffer is parsed as 0)";
      I_3$=@+t        "Add the integer to the value of the indexed time unit";
      [               "Open an empty numeric character buffer";
    }*              "End repeat
                     (This is used like an if statement, taking advantage of
                     the fact that iterations after the first have no effect)";
  }*              "End if";
}/              "End for";
'|*             "Insert a '|' between each time unit value (implicitly added to
                 output)";
'}              "Add '}' to output";

मैंने शुरू में एक टोकन-आधारित दृष्टिकोण का उपयोग करना शुरू किया था, लेकिन यह बहुत मजबूती से अटक गया ... 61 बाइट्स। आह। इसलिए मैंने पूरी तरह से गियर बदल दिए और इस चरित्र-आधारित दृष्टिकोण पर स्विच कर दिया, जो कि कहीं भी अधिक दिलचस्प है।

(मेरे पार्स विधि किसी वैध संख्यात्मक वर्ण पर पहुंच गया जोड़कर काम करता है 0- 9और -) एक बफर करने के लिए जब समय इकाई नामों में से एक से एक निश्चित चरित्र पहुँच जाता है एक पूर्णांक के रूप में बफर और पार्स करने। उन चरित्र y, t, d, h, i, औरc, जो सभी शर्तों को संतुष्ट करते हैं कि वे एक समय इकाई नाम में दिखाई देते हैं और किसी अन्य समय इकाई नाम में मान्यता चरित्र से पहले प्रकट नहीं होते हैं। दूसरे शब्दों में, जब इनमें से एक समय इकाई मान्यता वर्णों तक पहुँच जाता है, तो संख्यात्मक बफर अंतिम संख्या से भरा हुआ दिखाई देगा यदि यह वास्तव में एक समय इकाई को इंगित करता है, या संख्यात्मक बफर खाली हो जाएगा यदि यह सिर्फ दिखाई देता है, लेकिन ' टी सिग्नल, कुछ अन्य समय इकाई। या तो मामले में, संख्यात्मक बफर को पूर्णांक के रूप में पार्स किया जाता है, या 0 यदि यह खाली था, और इसे संबंधित इकाई मूल्य में जोड़ा जाता है। इस प्रकार उनके पहचान चरित्र के बाद अन्य समय इकाइयों में दिखने वाले मान्यता पात्रों का कोई प्रभाव नहीं होता है।

अन्य पागल हैक में शामिल हैं:

  • गाली देने वाले लूप्स तो संख्यात्मक वर्णों को स्टैक पर छोड़ दिया जाता है (जो संख्यात्मक वर्ण बफर के रूप में कार्य करता है) "मुफ्त में।"
  • सशर्त के बजाय एक ब्लॉक शून्य या कई बार दोहराते हैं क्योंकि लूप एक बयान की तुलना में अधिक कॉम्पैक्ट है, और पहले प्रभाव के बाद पुनरावृत्तियों का कोई प्रभाव नहीं है।

मेरे टोकन-आधारित समाधान के बारे में उत्सुक किसी के लिए, जो 61 बाइट्स पर अटक गया, मैं इसे यहाँ भी पोस्ट करूँगा। मैं इसे विस्तार या टिप्पणी करने के लिए कभी नहीं मिला, हालांकि।

सीजेएम, 61 बाइट्स

'{0a6*q'm-'{,64/~m*{:X/XS**}/S%2/{~0="yodhis"#_3$=@i+t}/'|*'}

+1 यह निश्चित रूप से अधिक उर्ध्वगामी बनाता है।
oopbase

2
@ Forlan07 समर्थन के लिए धन्यवाद। :) लेकिन मुझे जवाब देने में थोड़ा देर हो गई, इसलिए यह अप्रत्याशित नहीं है। इस उत्तर के निर्माण की प्रक्रिया में वैसे भी पर्याप्त संतुष्टि थी।
रनर ११२

10

पर्ल: 61 अक्षर

धन्यवाद @ नटकी को।

s/-?\d+ *m?(.)/$$1+=$&/ge;$_="{y|o|d|h|i|s}";s/\w/${$&}+0/ge

नमूना रन:

bash-4.3$ perl -pe 's/-?\d+ *m?(.)/$$1+=$&/ge;$_="{y|o|d|h|i|s}";s/\w/${$&}+0/ge' <<< '1 year 2 months 3 seconds'
{1|2|0|0|0|3}

bash-4.3$ perl -pe 's/-?\d+ *m?(.)/$$1+=$&/ge;$_="{y|o|d|h|i|s}";s/\w/${$&}+0/ge' <<< '-2 day 5 year 8months'
{5|8|-2|0|0|0}

bash-4.3$ perl -pe 's/-?\d+ *m?(.)/$$1+=$&/ge;$_="{y|o|d|h|i|s}";s/\w/${$&}+0/ge' <<< '3day 9     years 4 seconds -5 minute 4 years 4 years -3seconds'
{17|0|3|0|-5|1}

मेरा खराब प्रयास: 78 77 वर्ण

s/([+-]?\d+) *(..)/$a{$2}+=$1/ge;$_="{ye|mo|da|ho|mi|se}";s/\w./$a{$&}||0/ge

1
कुछ सुधार मुझे मिल सकते हैं:s/(-?\d+) *(..)/$$2+=$1/ge;$_="{ye|mo|da|ho|mi|se}";s/\w./${$&}+0/ge
नटकी

1
एक और 4 वर्ण:s/-?\d+ *(m.|.)/$$1+=$&/ge;$_="{y|mo|d|h|mi|s}";s/\w+/${$&}+0/ge
नटकी

वाह। शानदार ट्रिक्स, @ कुटकी।
13

1
अन्य समाधानों में भी पाया गया, (m.|.)-> m?(.)अतिरिक्त 4. बचाता है
नटकी

रवींद्र। यह अब बाहर की कोशिश करने वाला था। तो यह काम करता है। :)
मैनेटवर्क

5

रूबी, 119 106 86 85 84 बाइट्स

एक बाइट Sp3000 के लिए धन्यवाद बचाया।

->i{?{+"yodhis".chars.map{|w|s=0;i.scan(/-?\d+(?= *m?#{w})/){|n|s+=n.to_i};s}*?|+?}}

यह एक अनाम फ़ंक्शन है, जो इनपुट को एक स्ट्रिंग के रूप में लेता है, और परिणाम (एक स्ट्रिंग के रूप में) भी लौटाता है। आप इसे इसे fकहने, कहने और इसे कॉल करने के लिए असाइन करके परीक्षण कर सकते हैं

f["3day 9     years 4 seconds -5 minute 4 years 4 years -3seconds"]

5

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

import re
f=lambda I:"{%s}"%"|".join(`sum(map(int,re.findall("(-?\d+) *m?"+t,I)))`for t in"yodhis")

यह एक लैम्ब्डा फ़ंक्शन है जो एक स्ट्रिंग में लेता है और बस आवश्यक संख्याओं को निकालने के लिए एक regex का उपयोग करता है।

मार्टिन की ओर इशारा करते हुए धन्यवाद कि \s*बस हो सकता है <space>*। यह भूलना आसान है कि रेग्जेस रिक्त स्थान से मेल खाते हैं ...


4

जावास्क्रिप्ट 100 105 112

संपादित जोड़ना टेम्पलेट तार (पहले dec 2014, इसलिए इस चुनौती के लिए मान्य कार्यान्वित) - समय में मैं नहीं उनमें से जानकारी थी

यूरेका को संपादित करें , आखिर में मुझे m?अन्य सभी उत्तरों का अर्थ मिला !

s=>s.replace(/(-?\d+) *m?(.)/g,(a,b,c)=>o['yodhis'.search(c)]-=-b,o=[0,0,0,0,0,0])&&`{${o.join`|`}}`

परीक्षा

F=
s=>s.replace(/(-?\d+) *m?(.)/g,(a,b,c)=>o['yodhis'.search(c)]-=-b,o=[0,0,0,0,0,0])&&`{${o.join`|`}}`

;['1 year 2 months 3 seconds','-2 day 5 year 8months'
,'3day 9     years 4 seconds -5 minute 4 years 4 years -3seconds']
.forEach(i=>console.log(i,F(i)))


3

आर, 197 बाइट्स

मुझे लगता है कि यह बिल्कुल भी एक प्रतिस्पर्धी प्रविष्टि नहीं है, मैं ज्यादातर आर में एक समाधान के साथ आना चाहता था। किसी भी मदद को छोटा करना निश्चित रूप से स्वागत योग्य है।

function(x){s="{";for(c in strsplit("yodhis","")[[1]])s=paste0(s,ifelse(c=="y","","|"),sum(as.numeric(gsub("[^0-9-]","",str_extract_all(x,perl(paste0("(-?\\d+) *m?",c)))[[1]]))));s=paste0(s,"}");s}

मार्टिन के जवाब की तरह, यह एक अनाम फ़ंक्शन है। इसे कॉल करने के लिए, इसे असाइन करें fऔर एक स्ट्रिंग पास करें।

यह बहुत ही छिपा हुआ है, तो आइए एक बिना गोल्फ वाले संस्करण पर एक नज़र डालते हैं।

function(x) {
    s <- "{"
    for (c in strsplit("yodhis", "")[[1]]) {
        matches <- str_extract_all(x, perl(paste0("(-?\\d+) *m?", c)))[[1]]
        nums <- gsub("[^0-9-]", "", matches)
        y <- sum(as.numeric(nums))
        s <- paste0(s, ifelse(c == "y", "", "|"), y)
    }
    s <- paste0(s, "}")
    return(s)
}

अकेले संरचना के आधार पर यह देखना आसान है कि क्या चल रहा है, भले ही आप आर से परिचित नहीं हैं। मैं कुछ अजनबी पहलुओं के बारे में विस्तार से बताऊंगा।

paste0() है कि कैसे आर बिना किसी विभाजक के साथ तार को जोड़ती है।

str_extract_all()समारोह हैडली है Wickham से आता है stringrपैकेज। बेस पैकेज में नियमित अभिव्यक्तियों की हैंडलिंग से वांछित होने के लिए बहुत कुछ छोड़ दिया जाता है, जो कि जहां stringrआता है। यह फ़ंक्शन इनपुट स्ट्रिंग में नियमित अभिव्यक्ति मैचों की एक सूची देता है। ध्यान दें कि एक फ़ंक्शन में रेगेक्स कैसे घिरा हुआ हैperl() यह सिर्फ यह कह रहा है कि रेगेक्स पर्ल-स्टाइल है, न कि आर-स्टाइल।

gsub()इनपुट वेक्टर के प्रत्येक तत्व के लिए एक regex का उपयोग करके एक खोज और प्रतिस्थापित करता है। यहां हम इसे सब कुछ बदलने के लिए कह रहे हैं जो खाली स्ट्रिंग के साथ नंबर या माइनस साइन नहीं है।

आखिर तुमने इसे हासिल कर ही लिया है। अनुरोध पर आगे स्पष्टीकरण खुशी से प्रदान किया जाएगा।


मुझे नहीं लगता कि एक बाहरी पैकेज के लिए स्ट्रिंग निष्कर्षण आउटसोर्सिंग एक अच्छा विचार है। जब बाहरी समुदाय समर्थित पुस्तकालय का उपयोग किया जाता है तो क्या यह खामी नहीं है? यहां तक ​​कि अगर यह ठीक है, तो आपने library(stringr)अपने स्रोत में शामिल क्यों नहीं किया ?
आंद्रे

2

कोबरा - 165

def f(s='')
    l=int[](6)
    for i in 6,for n in RegularExpressions.Regex.matches(s,'(-?\\d+) *m?['yodhis'[i]]'),l[i]+=int.parse('[n.groups[1]]')
    print'{[l.join('|')]}'

2

सी ++ 14, 234 229 बाइट्स

संपादित करें: के बजाय पुरानी शैली घोषणा का उपयोग करके 5 बाइट्स में कटौती करेंauto

मुझे पता है कि विजेता को पहले ही चुना जा चुका है, और यह अब तक का सबसे लंबा सबमिशन होगा, लेकिन मुझे सिर्फ C ++ समाधान पोस्ट करना था, क्योंकि मुझे यकीन है कि किसी को भी उम्मीद नहीं थी :)

सच कहूं तो, मैं बहुत खुश हूं कि यह कितना छोटा हो गया (सी ++ माप से, बिल्कुल), और मुझे यकीन है कि यह किसी भी छोटे से नहीं मिल सकता है (यह सिर्फ एक टिप्पणी के साथ, नीचे देखें) । यह C ++ 11/14 में नई सुविधाओं का काफी अच्छा संग्रह है।

यहां कोई भी तृतीय-पक्ष पुस्तकालय नहीं है, केवल मानक पुस्तकालय का उपयोग किया जाता है।

समाधान लंबोदर फ़ंक्शन के रूप में है:

[](auto&s){sregex_iterator e;auto r="{"s;for(auto&t:{"y","mo","d","h","mi","s"}){int a=0;regex g("-?\\d+ *"s+t);decltype(e)i(begin(s),end(s),g);for_each(i,e,[&](auto&b){a+=stoi(b.str());});r+=to_string(a)+"|";}r.back()='}';s=r;};

Ungolfed:

[](auto&s)
{
    sregex_iterator e;
    auto r="{"s;
    for(auto&t:{"y","mo","d","h","mi","s"})
    {
        int a=0;
        regex g("-?\\d+\\s*"s+t);
        decltype(e)i(begin(s),end(s),g);
        for_each(i,e,[&](auto&b)
        {
            a+=stoi(b.str());
        });
        r+=to_string(a)+"|";
    }
    r.back()='}';
    s=r;
}

किसी कारण से, मुझे लिखना पड़ा

regex g("-?\\d+\\s*"s+t);
decltype(e)i(begin(s),end(s),g);

इसके बजाय बस

decltype(e)i(begin(s),end(s),regex("-?\\d+\\s*"s+t));

यदि मैं अस्थायी वस्तु में पास होता हूं तो इट्रेटर केवल एक मैच ही लौटाएगा। यह मुझे सही नहीं लगता, इसलिए मुझे आश्चर्य है कि अगर जीसीसी के रेगेक्स कार्यान्वयन में कोई समस्या है।

पूर्ण परीक्षण फ़ाइल (जीसीसी 4.9.2 के साथ संकलित -std=c++14):

#include <iostream>
#include <string>
#include <regex>

using namespace std;

int main()
{
    string arr[] = {"1 year 2 months 3 seconds",
                    "-2 day 5 year 8months",
                    "3day 9     years 4 seconds -5 minute 4 years 4 years -3seconds"};
    for_each(begin(arr), end(arr), [](auto&s){sregex_iterator e;auto r="{"s;for(auto&t:{"y","mo","d","h","mi","s"}){int a=0;auto g=regex("-?\\d+ *"s+t);decltype(e)i(begin(s),end(s),g);for_each(i,e,[&](auto&b){a+=stoi(b.str());});r+=to_string(a)+"|";}r.back()='}';s=r;});
    for(auto &s : arr) {cout << s << endl;}
}

आउटपुट:

{1|2|0|0|0|3}
{5|8|-2|0|0|0}
{17|0|3|0|-5|1}

0

PHP, 141 बाइट्स

preg_match_all("#(.?\d+)\s*m?(.)#",$argv[1],$m);$r=[0,0,0,0,0,0];foreach($m[1]as$i=>$n)$r[strpos(yodhis,$m[2][$i])]+=$n;echo json_encode($r);

पहली कमांड लाइन तर्क से इनपुट लेता है; के [,]बजाय उत्पादन के लिए उपयोग करता है {|}। साथ चलाना -r

टूट - फूट

preg_match_all("#(.?\d+)\s*m?(.)#",$argv[1],$m);    # find intervals.
# (The initial dot will match the sign, the space before the number or a first digit.)
$r=[0,0,0,0,0,0];                   # init result
foreach($m[1]as$i=>$n)              # loop through matches
    $r[strpos(yodhis,$m[2][$i])]+=$n;   # map token to result index, increase value
echo json_encode($r);               # print result: "[1,2,3,4,5,6]"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.