प्रिंटफ-स्टाइल स्ट्रिंग फॉर्मेटिंग


9

चुनौती

एक फ़ंक्शन लिखें जो सी printf-स्टाइल स्ट्रिंग प्रारूपण को लागू करता है ।

नियम

  1. आप चाहिए लागू कम से कम %%, %c, %s, %dऔर %f
  2. आपको अंतर्निहित स्ट्रिंग स्वरूपण विधि का उपयोग नहीं करना चाहिए
  3. आपको अपने प्रोग्राम से बाहरी प्रोग्राम नहीं चलाना चाहिए या इंटरनेट से कनेक्ट नहीं करना चाहिए
  4. यह आपको तय करना है कि अमान्य इनपुट को कैसे संभालना है, लेकिन आपके कार्यक्रम को असामान्य रूप से समाप्त नहीं करना चाहिए
  5. आप चाहिए एक लिखने variadic समारोह यदि संभव हो तो।

इस दस्तावेज़ में "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALLULD", "SHOULD NOT", "RECOMMENDED", "MAY", और "OPTIONAL" प्रमुख शब्द हैं। आरएफसी 2119 में वर्णित के रूप में व्याख्या की जाएगी ।


क्या करता %cहै? बहुत यकीन है %s, %dऔर %fतार, ints और संबंधित के लिए तैरता है, लेकिन के बारे में अनिश्चित हैं %c
सुमुरै 8

%cएक पारित int-IIRC के ASCII मूल्य को प्रदर्शित करता है
marinus

यह चरित्र प्रिंट, तो 97और 'a'दोनों बन जाएगा aउत्पादन पर।
nyuszika7h

%-02dसही जैसे कुछ फ़ॉर्म का समर्थन करने की आवश्यकता नहीं है ? बस तीन% c,% s,% d?
आप

@ आप सही हैं। बस काफी है।
nyuszika7h

जवाबों:


4

एपीएल (73)

{⊃,/,⌿↑(⊂2∘↓¨Z⊂G),⊂{'c'0≡⍵,∊⊃⍺:⎕UCS⍺⋄⍕⍺}/⍵,⍪⌷∘G¨1↓1+(Z←G='%')/⍳⍴G←'%!',⍺}

कुछ परीक्षण:

      'a:%c b:%s c:%d'{⊃,/,⌿↑(⊂2∘↓¨Z⊂G),⊂{'c'0≡⍵,∊⊃⍺:⎕UCS⍺⋄⍕⍺}/⍵,⍪⌷∘G¨1↓1+(Z←G='%')/⍳⍴G←'%!',⍺} 65 'foo' 67
a:A b:foo c:67 

      printf←{⊃,/,⌿↑(⊂2∘↓¨Z⊂G),⊂{'c'0≡⍵,∊⊃⍺:⎕UCS⍺⋄⍕⍺}/⍵,⍪⌷∘G¨1↓1+(Z←G='%')/⍳⍴G←'%!',⍺}
      '1:%s 2:%s 3:%d 4:%c 5:%c' printf 'foo' 'bar' 100 110 'z'
1:foo 2:bar 3:100 4:n 5:z   
      'The %s brown %c%c%c jumps over the %s dog.' printf 'quick' 102 111 'x' 'lazy'
The quick brown fox jumps over the lazy dog.

स्पष्टीकरण:

  • G←'%!',⍺: स्ट्रिंग के लिए डमी निर्दिष्ट उपसर्ग (आसान प्रसंस्करण के लिए)
  • (Z←G='%')/⍳⍴G: %स्ट्रिंग के सभी वर्णों के सूचक मिलते हैं ; में भी एक बिटमास्क स्टोर करेंZ
  • ⌷∘G¨1↓1+: %एस के बगल में सभी वर्णों का चयन करें , और डमी को छोड़ दें।
  • ⍵,⍪: सही तर्क से इसके मूल्य के साथ प्रत्येक विनिर्देशक का मिलान करें।
  • {... }/: प्रत्येक जोड़ी पर निम्न फ़ंक्शन चलाएँ:
    • 'c'0≡⍵,∊⊃⍺: यदि तर्क एक संख्या है और विनिर्देशक है c:
    • :⎕UCS⍺: तब तर्क का यूनिकोड मान लौटाएं,
    • ⋄⍕⍺: अन्यथा, तर्क का स्ट्रिंग प्रतिनिधित्व वापस करें।
  • : संलग्न करें
  • ⊂2∘↓¨Z⊂G: %एस पर स्ट्रिंग विभाजित करें और फिर प्रत्येक प्रतिस्थापन के पहले दो पात्रों को हटा दें (यह वह जगह है जहां डमी आती है), और उस के परिणाम को संलग्न करें।
  • : दो संलग्न सरणियों में से एक मैट्रिक्स बनाएं, प्रत्येक प्रतिस्थापन को उस मूल्य के साथ मिलान करें जो इसका पालन करना चाहिए।
  • ,⌿: इसके मूल्य के साथ प्रत्येक स्थानापन्न में शामिल हों
  • ⊃,/: फिर परिणामी तार में शामिल हों।

यह हमेशा आनंद देने वाली भाषाओं को देखने के लिए मज़ेदार होता है जो जिबरिश की तरह दिखती हैं। ;)
nyuszika7h

2
@ nyuszika7h: यह वास्तव में एक गंभीर भाषा है। यह 1960 के दशक से है और यह अभी भी उपयोग में है। अगर यह गोल्फ नहीं था तो यह गिबरीश की तरह थोड़ा कम दिखाई देगा।
मारिनस

मैं देखता हूं, दिलचस्प है।
nyuszika7h

@ nyuszika7h: ठीक है, तकनीकी रूप से यह सूची उन्मुख प्रोग्रामिंग भाषा है, इसलिए आप कह सकते हैं कि यह कोड गोल्फ के लिए डिज़ाइन किया गया है, विशेष रूप से इसे ध्यान में रखते हुए कार्यक्रमों को अधिक पठनीय बनाने के लिए एक विशेष वर्ण सेट का उपयोग करता है, और कम क्रिया। और यह जे प्रोग्रामिंग भाषा और गोल्फस्क्रिप्ट के लिए एक प्रेरणा थी ।
कोनराड बोरोस्की

@ एक्सफ़िक्स मुझे लगा कि LISP सूची उन्मुख प्रोग्रामिंग भाषा थी? हमने असली काम के लिए विश्वविद्यालय में एपीएल का उपयोग किया - मूल रूप से सरणियों को संभालने में सक्षम होना वास्तव में आसान है। जे एपीएल के आविष्कारकों में से एक द्वारा इसके "उत्तराधिकारी" के रूप में डिजाइन किया गया था - बेशक इसका मतलब यह नहीं है कि यह कोड गोल्फ के लिए उपयोगी नहीं है ...
जेरी यिर्मयाह

2

रूबी: 102 अक्षर

f=->s,*a{s.gsub(/%(.)/){$1==?%??%:a.shift.send({?c=>:chr,?s=>:to_s,?d=>:to_i,?f=>:to_f}[$1])rescue$&}}

नमूना रन:

irb(main):001:0> f=->s,*a{s.gsub(/%(.)/){$1==?%??%:a.shift.send({?c=>:chr,?s=>:to_s,?d=>:to_i,?f=>:to_f}[$1])rescue$&}}
=> #<Proc:0x96634ac@(irb):1 (lambda)>

irb(main):002:0> puts f["percent : %%\n   char : %c or %c\n string : %s or %s or %s\ndecimal : %d or %d or %d\n  float : %f or %f or %f\ninvalid : %x or %s or %d or %f", 65, 'B', 'format me', 42, Math::PI, 42, Math::PI, '2014', 42, Math::PI, '2014', 'more']
percent : %
   char : A or B
 string : format me or 42 or 3.141592653589793
decimal : 42 or 3 or 2014
  float : 42.0 or 3.141592653589793 or 2014.0
invalid : %x or  or 0 or 0.0
=> nil

अमान्य प्रारूप विनिर्देशकों को रखा गया है। तर्क मान के बिना प्रारूप विनिर्देशक को दिए गए प्रकार के रिक्त मान से बदल दिया जाता है।


आप एक अनाम फ़ंक्शन की आपूर्ति कर सकते हैं, इसलिए f
बिल्ली

वास्तव में। लेकिन जैसा कि मुझे याद है, इस पोस्ट के समय, गुमनाम कार्यों को सर्वसम्मति से स्वीकार नहीं किया गया था। चूंकि अब तक न तो लूआ जवाब अनाम फ़ंक्शन (वर्णों की समान मात्रा को बचाने के लिए) में अपडेट किया गया था, मुझे लगता है कि मैं अपडेट अभियान शुरू नहीं करूंगा।
मैनटवर्क

2

लुआ 5.2, 115 बाइट्स

-- Function definition, 115 chars
function f(f,...)n,t=0,{...}return(f:gsub('%%(%a)',function(s)n=n+1return(({c=s.char})[s]or tostring)(t[n])end))end

-- Usage example
print(f('Happy %cew %d %s %f',78,2014,'Year!',math.pi))
-- Output: Happy New 2014 Year! 3.1415926535898

अच्छा है। Lua का कौन सा संस्करण? 5.1.5 "1return" के पास "विकृत संख्या" देता है। "% C" के साथ छोटी समस्या, यह 78 के बजाय 'एन' पर विफल रहता है। या यह सिर्फ मेरी पुरानी लुआ की ख़ासियत है?
मैनटवर्क


हां, वहां काम करता है।
13

लुआ 5.2.3 पर मेरे लिए काम करता है।
nyuszika7h

1

C ++ (281 अक्षर)

#include<sstream>
#include<cstdarg>
#define q(x)va_arg(v,x);break;case
std::string p(char*f,...){std::ostringstream r;va_list v;va_start(v,f);while(*f)if(*f=='%')switch(++f,*f++){case's':r<<q(char*)'d':r<<q(int)'c':r<<(char)q(int)'%':r<<'%';}else r<<*f++;va_end(v);return r.str();}

मैं सी ++ से नफरत करता हूं, लेकिन यह एक अच्छा विकल्प लगता था (मैं वास्तव में सी के साथ जाऊंगा, अगर नहीं कि char*सूचक को वास्तव में उपयोगी होने के लिए बहुत प्रयास की आवश्यकता होती है)। ले जाता है char*तर्क है, और std::stringपरिणाम है, लेकिन हे, सी है कि ++, इसलिए जो स्थिरता के बारे में (भाषा में है जो अपने आप संगत नहीं है) परवाह करता है?


यह संकलित नहीं करता है, क्योंकि इसमें एक मुख्य कार्य नहीं है।
nyuszika7h

@ nyuszika7h: सवाल एक समारोह बनाने का था, नहीं main। लेकिन अगर आपको नमूना की आवश्यकता है main, तो gist.github.com/xfix/8238576 पर प्रयास करें (मैंने इस फ़ंक्शन का परीक्षण करते समय इसका उपयोग किया था)।
कोनराड बोरोवस्की

सच है, आप वास्तव में एक सार्थक mainकार्य नहीं कर सकते हैं , एक जोड़ने से सिर्फ चरित्र गणना बढ़ जाएगी। अगर मैं कोड को संशोधित नहीं करना चाहता था, तो मैं #includeअपने टेस्ट प्रोग्राम से एक साथ हेडर फ़ाइल जोड़ सकता था।
nyuszika7h

1

जावा , 201 186 174 बाइट्स

केविन क्रूज़सेन के लिए 12 बाइट्स धन्यवाद

String f(String s,Object...a){String r="";for(char c,i=0,j=0;i<s.length();r+=c==37?(c=s.charAt(i++))<38?c:c==99?(char)(int)a[j++]:a[j++]:c==37?"":c)c=s.charAt(i++);return r;}

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


मैं पूरी तरह यकीन नहीं है, लेकिन मुझे लगता है कि आप निकाल सकते हैं =s.charAt(0)से char c=s.charAt(0)यह तब भी काम करता है जब मैं ऐसा करता हूं।
केविन क्रूज़सेन

@ केविनक्रूजसेन मैं कसम खाता हूं कि वह काफी चालाक है।
लीक नून

मुझे पता है कि यह थोड़ी देर हो गई है, लेकिन आप सीधे प्रिंट करके 8 और बाइट्स बचा सकते हैं: void f(String s,Object...a){for(char c,i=0,j=0;i<s.length();System.out.print(c==37?(c=s.charAt(i++))<38?c:c==99?(char)(int)a[j++]:a[j++]:c==37?"":c))c=s.charAt(i++);} 166 बाइट्स (और जावा 8 में कनवर्ट करके कुछ और, लेकिन यह वास्तव में आपकी चीज नहीं है, यह है?)
केविन क्रूज़सेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.