गोल्फ स्ट्रिंग का प्रारूप () उलटा


13

प्रारूप विधि उल्टा।

Formatस्ट्रिंग क्लास (या समतुल्य, जैसे sprintf) की विधि अधिकांश भाषाओं में उपलब्ध है। यह मूल रूप से एक "प्रारूप" स्ट्रिंग लेता है जिसमें कुछ अतिरिक्त स्वरूपण वाले प्लेसहोल्डर हो सकते हैं, और उन प्लेसहोल्डर्स के बजाय शून्य या अधिक मान डाले जा सकते हैं।

आपका काम अपनी पसंद की भाषा में उलटा फ़ंक्शन लागू करना है।

एपीआई

विधि का नाम होना चाहिए या तो format1या deformat

इनपुट : 1 पैरामीटर "प्रारूप" स्ट्रिंग होगा, मूल प्रारूप विधि की तरह। 2 पैरामीटर पार्स स्ट्रिंग (नीचे उदाहरण देखें) होगा। किसी अन्य पैरामीटर की आवश्यकता नहीं है और न ही अनुमति है।

आउटपुट : मानों की एक सरणी (या आपकी भाषा-पसंद का समकक्ष) जो प्रारूप में प्लेसहोल्डर्स के साथ संगत रूप से निकाली गई थी।

प्लेसहोल्डर हैं {0}, {1}, {2}, आदि

खराब प्रारूप के मामले में आप एक त्रुटि फेंक सकते हैं, या जो कुछ भी आप चाहते हैं उसे वापस कर सकते हैं।

अमान्य इनपुट के मामले में, आप एक त्रुटि फेंक सकते हैं, या जो कुछ भी आप चाहते हैं उसे वापस कर सकते हैं। अमान्य इनपुट ऐसा है जो String.Format द्वारा एक ही प्रारूप स्ट्रिंग का उपयोग करके उत्पन्न नहीं किया जा सकता है, उदाहरण के लिए '{0}{0}', 'AAB':।

उदाहरण

deformat('{0} {1}', 'hello world') => ['hello', 'world']
deformat('http{0}://', 'https://') => ['s']
deformat('http{0}://', 'http://') => [''] // array of one item which is an empty string
deformat('{0}{1}{0}', 'ABBA') => ['A', 'BB']

अस्पष्टता

अस्पष्टता के मामले में आप किसी भी उपयुक्त उत्तर को वापस कर सकते हैं। उदाहरण के लिए:

deformat('{0} {1}', 'Edsger W. Dijkstra')
// both ['Edsger', 'W. Dijkstra'] and ['Edsger W.', 'Dijkstra'] are applicable.

कुछ और नियम

  • इसे आसान बनाने के लिए, वास्तव में स्वरूपण का समर्थन करने की कोई आवश्यकता नहीं है। आप सभी प्रमुख शून्य, दशमलव बिंदु या गोलाई के मुद्दों को भूल सकते हैं। बस स्ट्रिंग के रूप में मान उत्पन्न करते हैं।
  • इसे गैर-तुच्छ बनाने के लिए, नियमित अभिव्यक्ति की अनुमति नहीं है
  • आपको इनपुट में घुंघराले ब्रेसिज़ की देखभाल करने की आवश्यकता नहीं है (अर्थात द्वितीय इनपुट पैरामीटर में कोई {s या }s नहीं होगा )।

जीतना

यह ! (के रूप में पढ़ा जाना चाहिए "यह स्पार्टा है!") सबसे कम लंबाई वाली सही फ़ंक्शन जीत है। मानक खामियों को मना किया जाता है।


उदाहरण में deformat('{0}{1}{0}', 'ABBA') => ['A', 'BB'], अगर हमें इसके बदले दिया गया तो क्या होगा deformat('{0}{1}{0}', 'AAAA')?
xnor

@xnor - से हम एक अस्पष्टता है, और निम्न में से प्रत्येक के लिए एक वैध उत्पादन होगा: ['', 'AAAA'], ['A', 'AA'],['AA', '']
याकूब

एक तो उत्पादन किया जा सकता है deformat('{0}{1}{0}', 'ABBA') => ['', 'ABBA']? यदि ऐसा है, तो एक सस्ता समाधान है जब तक कि प्रत्येक स्ट्रिंग कम से कम दो बार दिखाई न दे।
xnor

क्या आपका सस्ता उपाय भी काम आएगा deformat('{0}_{1}_{0}', 'A_BB_A')?
याकूब

ओह, मैं देख रहा हूं, मैं परिणामों में वास्तविक पात्रों के बारे में भूल गया था। मैं अभी भी अपने सिर को चारों ओर लपेटने की कोशिश कर रहा हूं कि यह एल्गोरिदम कितना कठिन है। मुझे देखने दो कि क्या मैं वास्तव में विकृत उदाहरण बना सकता हूं।
xnor

जवाबों:


2

हास्केल, 220 वर्ण

import Data.Map;f""""=[empty]
f('{':b)d=[insert k m b|(k,('}':a))<-lex b,(m,c)<-[splitAt n d|n<-[0..length d]],b<-f a c,notMember k b||b!k==m]
f(x:b)(y:d)|x==y=f b d;f _ _=[];format1 x y=elems$mapKeys((0+).read)$f x y!!0

यदि आप एक ही पैटर्न ( {1}बनाम {01}) के लिए कई अभ्यावेदन का उपयोग करते हैं, तो उनकी समानता को लागू नहीं करता है, इसके बजाय सभी के लिए मैचों को छोड़ देता है।

mapKeys((0+).read)$अगर 10 पैटर्न से ऊपर के मैचों का उचित क्रम मायने नहीं रखता है, या यदि समान लंबाई के लिए पैडिंग की आवश्यकता हो सकती है, या यदि पैटर्न के स्ट्रिंग क्रम स्वीकार्य हैं, तो 19 वर्णों को चूकने से बचाया जा सकता है। किसी भी स्थिति में, यदि किसी पैटर्न को पहले तर्क से छोड़ दिया जाता है, तो उसे परिणाम से भी छोड़ दिया जाता है।

!!0अंत से हटाने से format1केवल पहले के बजाय सभी समाधानों की सूची वापस आ जाती है।

गोल्फिंग से पहले:

import Data.Map
import Control.Monad

cuts :: [a] -> [([a],[a])]
cuts a=[splitAt n a | n <- [0..length a]]

f :: String -> String -> [Map String String]
-- empty format + empty parsed = one interpretation with no binding
f "" "" = [empty]
-- template-start format + some matched = branch search
f ('{':xs) ys = do
    let [(key, '}':xr)] = lex xs
    (match, yr) <- cuts ys
    b <- f xr yr
    guard $ notMember key b || b!key == match
    return $ insert key match b
-- non-empty format + matching parsed = exact match
f (x:xs) (y:ys) | x == y = f xs ys
-- anything else = no interpretation
f _ _ = []

deformat :: String -> String -> [String]
deformat x y = elems $ mapKeys ((0+).read) $ head $ f x y

whi वहाँ है (0+)? क्या सिर्फ पढ़ना कम नहीं है?
गर्वित हैकेलर

@proudhaskeller readआपको एक अस्पष्ट प्रकार के साथ छोड़ देता है। हास्केल को पता नहीं है कि कुंजियों को पढ़ने के लिए किस प्रकार का क्रमबद्ध प्रकार है। +0एक संख्या को बल देता है, जिसमें से हास्केल पहले से ही एक मनमाना विकल्प बनाने में सक्षम है और पूर्णांक के लिए जाता है।
जॉन ड्वोरक

2

रूबी, 312 अक्षर

class String
def-@
self[0,1].tap{self[0,1]=''}end
end
def format1 f,s,r=[]
loop{if'{'==c=-f
n,f=f.split('}',2)
[*1..s.length,0].each{|i|next if'{'!=f[0]&&s[i]!=f[0]
if u=format1((g=f.gsub("{#{n}}",q=s[0,i])).dup,s[i..-1],r.dup)
r,s,f=u,s[i..-1],g
r[n.to_i]=q
break
end}else
c!=-s&&return
end
""==c&&break}
r
end

5 अक्षर शून्य लंबाई मैचों पसंद करते हैं, बनाने के द्वारा बचाया जा सकता है ABBAसमाधान ['', 'ABBA'], बल्कि सवाल का पसंदीदा समाधान की तुलना में। मैंने विनिर्देशन के निहित भाग के रूप में उदाहरणों की व्याख्या करने के लिए चुना।


1

पायथन, 208 वर्ण, यद्यपि अपूर्ण।

def format1(i,o):
 i+=" ";o+=" ";x=y=0;s=[]
 while x<len(i):
  if i[x]=="{":
   try:y+=len(s[int(i[x+1])])
   except:
    s+=[""]
    while o[y]!=i[x+3]:s[int(i[x+1])]+=o[y];y+=1
   x+=3
  x+=1;y+=1
 return s

फ़ंक्शन दोनों तारों को एक साथ स्वीप करता है, जब तक कि यह इनपुट स्ट्रिंग में एक उद्घाटन ब्रेस नहीं पाता है, एक प्लेसहोल्डर को दर्शाता है।

फिर, यह मानता है कि प्लेसहोल्डर का पहले से ही विस्तार हो चुका है, और अब तक मिले मूल्यों की सूची को देखते हुए आउटपुट स्ट्रिंग के सूचकांक को आगे बढ़ाने की कोशिश करता है।

यदि इसका विस्तार नहीं किया गया है, तो यह मूल्यों की सूची में एक नई प्रविष्टि जोड़ता है, और आउटपुट स्ट्रिंग से वर्णों में जोड़ना शुरू करता है जब तक कि यह इनपुट स्ट्रिंग में प्लेसहोल्डर के बाद चरित्र तक नहीं पहुंचता।

जब यह इनपुट स्ट्रिंग के अंत में जाता है, तो यह अब तक मिले मूल्यों को लौटाता है।


यह सरल आदानों के लिए अच्छी तरह से काम करता है, लेकिन इसमें कई समस्याएं हैं:

  • इनपुट में प्रत्येक प्लेसहोल्डर के बाद इसे एक ज्ञात परिसीमन की आवश्यकता होती है, इसलिए यह प्लेसहोल्डर्स के साथ एक दूसरे के ठीक बगल में काम नहीं करता है "{0} {1}"। यही कारण है कि मुझे दोनों तारों के लिए एक स्पेस चार को जोड़ने की आवश्यकता थी।

  • यह मानता है कि प्रत्येक प्लेसहोल्डर के पहले उदाहरण क्रम में हैं जैसे "{ 0 } { 1 } {1} {0} { 2 }"।

  • यह केवल पहले 10 प्लेसहोल्डर्स के लिए काम करता है क्योंकि यह मानता है कि वे सभी 3 चार्ट लंबे हैं।

  • यह अस्पष्ट मामलों को बिल्कुल नहीं संभालता है :(


1

सी ++ 11 कोड, 386 वर्ण

#include <string>
#include <map>
using namespace std;using _=map<int,string>;using X=const char;_ format1(X*p,X*s,_ k=_()){_ r;while(*p!='{'){if(!*p||!*s){return*p==*s?k:r;}if(*p++!=*s++)return r;}int v=0;while(*++p!='}'){v=v*10+(*p-48);}p++;if(k.find(v)!=k.end()){return format1((k[v]+p).c_str(),s,k);}while((r=format1(p,s,k)).empty()){k[v]+=*s++;if(!*s){return*p==*s?k:r;}}return r;}

Format1 फ़ंक्शन में इनपुट (const char *) के रूप में 2 स्ट्रिंग्स हैं और चाबियाँ पूर्णांक (पैटर्न) के साथ एक हैशमैप देता है और मान की पहचान की गई स्ट्रिंग है। यदि कुछ भी नहीं मिला है या कोई त्रुटि है, तो एक खाली हैशमैप वापस आ जाता है।

उपयोग:

for (auto v : format1("{1} {2}", "one two")){
    cout << v.first << "=" << v.second << endl;
}

आउटपुट:

1=one
2=two

उदाहरण 2:

auto v = format1("{1} {2}", "one two");
cout << v[1] << " and " << v[2] << endl;

आउटपुट:

one and two

पैटर्न दशमलव प्रतिनिधित्व में हैं, इससे बड़ा इनपुट MAXINTअतिप्रवाह होगा, लेकिन यह अभी भी काम करता है।

हालांकि अन्य प्रोग्रामिंग भाषाओं में छोटे समाधान हैं, फिर भी यह सबसे छोटा C ++ है - फिर भी! :)

यह गोल्फिंग से पहले का कोड है:

#include <string>
#include <map>
using namespace std;

using res = map<int,string>;

res format1(const char* p, const char* s, res k=res()){
    res r; // intermediate result, empty until the end
    // match until first '{'
    while (*p != '{'){
        if (!*p || !*s){
            // exit case
            return ((*p == *s) ? k : r); // == 0
        }
        if (*p++ != *s++)
               return r;
    }

    // *p == '{'
    int v = 0;
    while(*++p != '}'){
        v = v*10 + (*p - '0');
    }
    p++; // advance past '}'

    // match back-references
    if (k.find(v) != k.end()){
       return format1((k[v]+p).c_str(), s, k);
    }

    // recursive search
    while ( (r=format1(p, s, k)).empty() ){
        k[v] += *s++;
        if (!*s){
            return *p == *s ? k : r;
        }
    }
    return r;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.