आइए बनाते हैं डाइट हास्केल


21

हास्केल में ट्यूपल्स होते हैं जिन्हें लिखा जा सकता है

(a,b,c)

हालाँकि यह सिर्फ चीनी के लिए है

(,,)a b c

सामान्य तौर पर एक n टपल को n-1 , s के बीच बनाया जा सकता है (... )इसके बाद इसके तत्वों को रिक्त स्थान द्वारा अलग किया जाता है। उदाहरण के लिए 7-ट्यूपल, (1,2,3,4,5,6,7)द्वारा गठित किया जा सकता है

(,,,,,,)1 2 3 4 5 6 7

चूंकि हास्केल के पास 1-ट्यूपल नहीं हैं, इसलिए उनका गठन नहीं किया जा सकता है। आपको खाली टुपल्स के लिए भी जिम्मेदार नहीं ठहराया जाएगा।

संचालन के क्रम को ओवरराइड करने के लिए पार्स का उपयोग करके नेस्टेड ट्यूपल्स का गठन किया जा सकता है।

((1,2),3) == (,)((,)1 2)3

हास्केल से सभी सिंटैक्टिक शुगर को हटाने के लिए हमारी खोज के हिस्से के रूप में मैं आपको एक प्रोग्राम लिखने के लिए कहने जा रहा हूं जो हस्केल के ट्यूपल्स से सिंटैक्टिक शुगर को हटा देता है।

आपके कार्यक्रम में एक टुपल, एक सरणी, या एक शर्करा ट्यूल का प्रतिनिधित्व करने वाला एक स्ट्रिंग होना चाहिए और एक "शुगर-फ्री" टपल का प्रतिनिधित्व करने वाले स्ट्रिंग को आउटपुट करना चाहिए। इनपुट ट्यूपल्स में केवल धनात्मक पूर्णांक या अन्य ट्यूपल होंगे।

चूंकि हम यहां गोल्फ कर रहे हैं, इसलिए आपका आउटपुट कम होना चाहिए। इसमें अनावश्यक नहीं होना चाहिए

  • रिक्त स्थान। रिक्त स्थान का उपयोग केवल एक टपल कार्यों के तर्क को अलग करने के लिए किया जाना चाहिए और एक के बाद )या उससे पहले नहीं दिखाई देना चाहिए(

  • कोष्ठक। कोष्ठक का उपयोग केवल तब किया जाना चाहिए जब टुपल फ़ंक्शंस बनाते हैं या जब ट्यूपल्स को घोंसला बनाते हैं।

यह एक प्रश्न है, इसलिए उत्तर बाइट्स में कम बाइट्स के साथ बेहतर स्कोर किए जाएंगे।

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

(1,2)     -> (,)1 2
(1,2,3)   -> (,,)1 2 3
((1,2),3) -> (,)((,)1 2)3
(1,2,3,4) -> (,,,)1 2 3 4
(1,(2,3)) -> (,)1((,)2 3)
(10,1)    -> (,)10 1

अगर मुझे कुछ याद नहीं आ रहा है, तो आप 1-ट्यूपल को कवर करते हैं, लेकिन खाली ट्यूपल को नहीं ..? क्या खाली ट्यूपल्स वैध इनपुट हैं?
पूरी तरह से

3
@totallyhuman आपको खाली टुपल्स को संभालने की आवश्यकता नहीं है।
गेहूं जादूगर

5 वें परीक्षण-मामले में एक अतिरिक्त है,
एच। विविज़

2
इसके अलावा "संख्या" से क्या आपका मतलब "सकारात्मक पूर्णांक" है?
आउटगॉल्फ

2
सुझाए गए परीक्षण मामले: ((1,(2,3)),4,(5,6))और (1,(2,3),4)
अर्जन जोहान्सन

जवाबों:


17

हास्केल , 169 148 बाइट्स

init.tail.fst.([]%)
p:k="(,"
l%('(':r)|(y,x:s)<-[]%r,m<-y:l=last$m%(p:s):[(p:p:(l>>k)++x:foldl(\r x->x++[' '|x>k,r>k]++r)[x]m,s)|x<',']
l%r=lex r!!0

इसे ऑनलाइन आज़माएं! टपल को एक स्ट्रिंग के रूप में लेता है। init.tail.fst.([]%)अनाम मुख्य कार्य है। इसे उदाहरण के लिए बाँधें fऔर उपयोग करें f "(3,(14,1),4,7)", जो उपज देता है "(,,,)3((,)14 1)4 7"

हास्केल टपल के रूप में इनपुट क्यों नहीं दिया गया है, आप पूछें? क्योंकि हास्केल दृढ़ता से टाइप किया गया है, एक टपल (1,2)का टाइप (Int,Int)1 है और एक टपल (1,(2,3))का टाइप है (Int,(Int,Int))। इस प्रकार एक फ़ंक्शन जो पहले प्रकार के टपल को स्वीकार करता है, उसे दूसरे प्रकार पर लागू नहीं किया जा सकता है, और विशेष रूप से कोई फ़ंक्शन नहीं हो सकता है जो एक मनमाना टुपल 2 लेता है ।

स्पष्टीकरण:

  • p:k="(,"करने के pलिए '('और kकरने के लिए असाइन करने के लिए एक छोटा तरीका है ","
  • (%)पुनरावर्ती पार्सिंग और परिवर्तित कार्य है। पहला तर्क पहले से ही टुप्ड प्रविष्टियों की एक सूची है, दूसरा तर्क मूल स्ट्रिंग का शेष है। प्रत्येक कॉल वर्तमान परिवर्तित टपल (एक स्ट्रिंग के रूप में और कोष्ठक में संलग्न) और शेष के एक टपल को लौटाता है।
    • l%('(':r)यदि स्ट्रिंग एक उद्घाटन ब्रैकेट के साथ शुरू होती है, तो हमें एक नया टपल प्रविष्टि पार्स करने की आवश्यकता है।
      (y,x:s)<-[]%rहम पुनरावर्ती रूप से आवेदन करते हैं %और एक टपल प्रविष्टि प्राप्त करते हैं yऔर शेष स्ट्रिंग को अगले वर्ण xऔर शेष स्ट्रिंग में विभाजित किया जाता है s
      m<-y:lहम yपहले से मिली प्रविष्टियों की वर्तमान सूची में नई प्रविष्टि जोड़ते हैं lऔर परिणाम को कॉल करते हैं m
    • अगला किरदार xअब या तो कॉमा ,या क्लोजिंग ब्रैकेट है )last$ <B> :[ <A> |x<',']सिर्फ लेखन की एक छोटी तरीका है if x == ')' then <A> else <B>
    • इसलिए यदि कोई ,अगला है, तो हमें अगली प्रविष्टि को पुन: पार्स करने की आवश्यकता है: m%(p:s)हम सही मामले को समाप्त करने और पहले से ही दर्ज प्रविष्टियों की सूची को पास करने के लिए एक खोलने वाले ब्रैकेट को तैयार करते हैं m
    • यदि अन्यथा x == ')', हमने वर्तमान टपल को समाप्त कर दिया और आवश्यक परिवर्तन करने की आवश्यकता है:(p:p:(l>>k)++x:foldl(\r x->x++[' '|x>k,r>k]++r)[x]m,s)
      • p:p:(l>>k)++x:हमने पाया है, तो n प्रविष्टियों, तो mहै n तत्वों और yसबसे हाल ही में पाया तत्व जोड़ने से पहले सूची,, है n-1 प्रविष्टियों। यह काम में आता है क्योंकि हमें एक तत्व टपल के लिए n-1 की आवश्यकता होती है और सूचियों पर काम करता है " तत्वों के रूप में सूची को अपने आप में कई बार " । इस प्रकार यह पहला भाग कुछ स्ट्रिंग देता है जैसे ।,nl>>kky"((,,,)"
      • foldl(\r x->x++[' '|x>k,r>k]++r)[x]mm(उल्टे क्रम में) तत्वों को मिलाता है , क्योंकि नई प्रविष्टियों को जोड़कर mस्वयं को उल्टे क्रम में निर्मित किया गया था) जबकि दोनों तत्वों के बीच केवल रिक्त स्थान जोड़ते हुए यदि वे दोनों संख्याएँ हैं: [' '|x>k,r>k]हम जाँचते हैं कि क्या वर्तमान प्रविष्टियाँ xऔर rसंख्याएँ lexicographer द्वारा समान हैं? उन्हें ","- यदि वे संख्या नहीं हैं, तो वे पहले से ही एक टपल प्रतिनिधित्व कोष्ठक में संलग्न हैं, और '(' < ','धारण करते हैं।
    • यदि पैटर्न l%('(':r)शुरुआत में सही से मेल खाता है, तो हम अंतिम पंक्ति में समाप्त होते हैं l%r=lex r!!0:। इसका मतलब है कि हमें एक संख्या को पार्स करने की आवश्यकता है और संख्या और शेष स्ट्रिंग को वापस करना है। सौभाग्य से वहाँ lexफ़ंक्शन है जो वास्तव में ऐसा करता है (यह अगले वैध हास्केल टोकन को पार करता है, न केवल संख्याएं)। हालाँकि परिणामस्वरूप टुपल को एक सूची में लपेटा गया है, इसलिए हम सूची !!0का पहला तत्व प्राप्त करने के लिए उपयोग करते हैं।
  • init.tail.fst.([]%)मुख्य कार्य है जो एक स्ट्रिंग लेता है और %एक खाली सूची के साथ लागू होता है। जैसे एक इनपुट के लिए "(1,2)", ([]%)पैदावार लगाने के लिए ("((,)1 2)",""), इसलिए बाहरी टपल और कोष्ठक को हटाने की आवश्यकता होती है। fstटपल का पहला तत्व मिलता है, tailसमापन कोष्ठक और initउद्घाटन को हटाता है ।

संपादित करें: 21 बाइट्स के कुल के लिए @ Editrjan जोहान्सन को बहुत धन्यवाद !


1 असल में, टाइप (Num t1, Num t) => (t, t1) है , लेकिन यह एक अलग कहानी है।

2 आईडी जैसे बहुरूपी कार्यों को अनदेखा करना , जो वास्तव में उनके इनपुट के साथ काम नहीं कर सकते हैं।


1
एक एक बहुरूपी समारोह एक typeclass का उपयोग कर लिख सकता है Desugarable, लेकिन एक के लिए घोषित उदाहरणों करने के लिए होता Intहै, और सभी टपल प्रकार के।
बरगी

1
gको छोटा किया जा सकता है foldr1(\x r->x++[' '|x>k,r>k]++r)
अर्जन

@ बर्गी: ... और कोई भी सही मायने में सभी प्रकार के उदाहरणों की घोषणा नहीं कर सकता । :-) (प्रयास करें: show (1,2,3,4,5,6,7,8,9,0,1,2,3,4,5)GHCi में, फिर ,6अंत में जोड़ें और फिर से कोशिश करें।)
wchargin

1
छह और बाइट्स के लिए इनलाइनिंग में सुधार: उपयोग करें m<-y:l, दाएं के बजाय बाएं मुड़ें और [x]प्रारंभिक मूल्य के रूप में उपयोग करें । इसे ऑनलाइन आज़माएं!
अर्जन जोहान्सन

1
fअनाम हो सकता है init.tail.fst.([]%):।
अर्जन जोहान्सन

11

हास्केल, 141 बाइट्स138 बाइट्स (अर्जन जोहान्सन के लिए धन्यवाद)

import Language.Haskell.TH
f(TupE l)='(':tail(","<*l)++')':""%l
q%(LitE(IntegerL i):l)=q++show i++" "%l
_%(e:l)='(':f e++')':""%l
_%[]=[]

fप्रकार है Exp -> String

  • इनपुट: एक टेम्पलेट हास्केलExp सत्र (यानी, मनमाने ढंग-प्रकार हास्केल मूल्यों का मानक एएसटी प्रतिनिधित्व - मूल रूप से, प्रकार की जाँच से पहले पार्स किए गए हास्केल कोड); केवल गैर-पूर्णांक संख्याओं और ऐसे अन्य tuples युक्त एक tuple का प्रतिनिधित्व करना चाहिए।

  • आउटपुट: एक स्ट्रिंग जो उस टुपल एक्सप्रेशन के लिए डिगर्डेड सिंटैक्स से युक्त होती है।

डेमो:

$ ghci TupDesugar.hs 
GHCi, version 8.3.20170711: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/sagemuej/.ghc/ghci.conf
Loaded GHCi configuration from /home/sagemuej/.ghci
[1 of 1] Compiling Main             ( TupDesugar.hs, interpreted )
Ok, 1 module loaded.
*Main> :set -XTemplateHaskell -XQuasiQuotes
*Main> f <$> runQ [|(1,2)|]
"(,)1 2"
*Main> f <$> runQ [|(1,2,3)|]
"(,,)1 2 3"
*Main> f <$> runQ [|((1,2),3)|]
"(,)((,)1 2)3"
*Main> f <$> runQ [|(1,2,3,4)|]
"(,,,)1 2 3 4"
*Main> f <$> runQ [|(1,(2,3))|]
"(,)1((,)2 3)"
*Main> f <$> runQ [|(10,1)|]
"(,)10 1"

2
आप बदल सकते हैं ")"++करने के लिए ')':दो स्थानों पर, और बाद स्थान बचाने के tailबाहर कोष्ठकों को ले जाकर।
अर्जन जोहान्सन

7

हास्केल , 119 बाइट्स

data T=I Int|U[T]
f(U t)="(("++init(t>>",")++')':foldr(\x y->f x++[' '|f x>",",y>","]++y)")"t
f(I n)=show n
init.tail.f

इसे ऑनलाइन आज़माएं! यह Ttuples का प्रतिनिधित्व करने के लिए एक कस्टम डेटा प्रकार का उपयोग करता है , जो कि tuple के ((1,2),3)रूप में दर्शाया जाता है U[U[I 1,I 2],I 3]। उदाहरण उपयोग: init.tail.f $ U[U[I 1,I 2],I 3]पैदावार (,)((,)1 2)3



4

GNU sed, 149 82 + 2 = 84 बाइट्स

-rझंडे के लिए +2 बाइट्स ।

y/(),/<>'/
:
s/([^<>']+)'/,\1 /
t
s/ ?<(,+)([^>]+)>/((\1)\2)/
t
s/^.|(\)) |.$/\1/g

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

व्याख्या

y/(),/<>'/                   # Replace parens and commas with brackets and apostrophes
:
  s/([^<>']+)'/,\1 /.          # Remove each apostrophe and insert comma after <
  t                            # Branch to : if substitution was made
  s/ ?<(,+)([^>]+)>/((\1)\2)/  # Change <,,,...> to ((,,,)...)
  t                            # Branch to : if substitution was made
s/^.|(\)) |.$/\1/g           # Remove outermost ()s and extra spaces

यह कुछ और जटिल मामलों पर विफल रहता है: ((1,(2,3)),4,(5,6))और (1,(2,3),4)
अर्जन जोहान्सन

@ ØrrrJohansen अच्छी पकड़। मैं नाश्ते के बाद देखूंगा।
जॉर्डन

3

जावास्क्रिप्ट, 75 बाइट्स

f=a=>`(${t=a.map(x=>'')})${a.map(v=>t=1/v?1/t?' '+v:v:`(${f(v)})`).join``}`

इनपुट संख्या की संख्या | सरणी, आउटपुट स्ट्रिंग।

नील को धन्यवाद, 2 बाइट बचाओ


(1/t?' ':0)+vहो सकता है 1/t?' '+v:v
नील

2

मैथेमेटिका, 94 बाइट्स

{"(",","&/@Most@#,")",c=1>0;(xIf[j=ListQ@x,c=j;"("<>#0@x<>")",If[c,c=j;x," "<>x]])/@#}<>""&

इसमें एक अप्राप्य U+F4A1, एक बिलियन Functionफ़ंक्शन होता है।

Listपूर्णांक Strings लेता है । यदि यह अनुमति नहीं है, यह 10 अधिक बाइट्स जोड़कर तय किया जा सकता है (इस संस्करण एक लेता है Listकी Listएस / Integerओं):

{"(",","&/@Most@#,")",c=1>0;(xIf[j=ListQ@x,c=j;"("<>#0@x<>")",If[c,c=j;""," "]<>ToString@x])/@#}<>""&

2

पिप , 45 बाइट्स

{Y"()"b:yJ',X#a-1Fcab.:c>0?s.cyJ(fc)bR") "')}

यह एक फ़ंक्शन है जो एक सूची को एक तर्क के रूप में लेता है। इसे ऑनलाइन आज़माएं!

टिप्पणी संस्करण

; Define an anonymous function (the argument is available inside as the variable a)
{
  ; Yank the string "()" into y variable
  Y "()"
  ; Create a string of len(a)-1 commas, join y on it, and assign to b
  b: y J ',X#a-1
  ; For each item c in a
  F c a
    ; Concatenate to b the following expression
    b .:
      ; Is c integer or list?
      ; (If c is a positive integer, c>0 is true; but if c is a list, c>0 is false)
      c>0 ?
        ; If c is integer, concatenate space followed by c
        s.c
        ; If c is list, call function recursively on c and use the result to join y
        yJ(fc)
  ; Replace ") " with ")" in b and return the resulting string
  b R ") " ')
}

2

जावास्क्रिप्ट (ईएस 6), 88 84 बाइट्स

f=a=>a.reduce((s,e)=>s+=e[0]?`(${f(e)})`:/\)$/.test(s)?e:' '+e,`(${[...a].fill``})`)

पूर्णांकों और सरणियों की एक सरणी लेता है। संपादित करें: s+=दो अलग-अलग उपयोगों के बजाय 1 बाइट का उपयोग करके सहेजा गया s+। अब एक और 3 बाइट्स सहेजे जो मैं आंतरिक टर्नरी को सरल बना सकता हूं। अगर मैं @ tsh के विचारों को चुराता हूं तो मैं इसे 76 बाइट्स तक ले जा सकता हूं:

f=a=>a.reduce((s,e)=>s+=t=1/e?1/t?' '+e:e:`(${f(e)})`,`(${t=a.map(_=>``)})`)

Your program should take either a tuple or a string representing a sugary tupleमुझे लगता है कि सरणियों / पूर्णांकों की एक सरणी ठीक होनी चाहिए।
जंगवान मिन

1
सुनिश्चित करें कि अनुमति दी गई है
गेहूं जादूगर

1

आर, 316 बाइट्स?

(बाहर सिर करने के लिए और यकीन है कि बाइट्स गिनने का उचित तरीका नहीं है ... प्लस यह एक महान समाधान नहीं है, लेकिन इसे पोस्ट करना चाहता हूं क्योंकि मैंने इसे बनाने में समय बिताया है ...)

p=function(x){
x=eval(parse(text=gsub("\\(","list(",x)))
f=function(j,r=T){
p=paste
s=if(r){"("}else{"(("}
o=paste0(s,p(rep(",",length(j)-1),collapse=""),")")
n=lengths(j)
for(i in seq_along(n)){
v=j[[i]]
if(n[i]>1){v=f(v,F)}
o=p(o,v)}
if(!r){o=p(o,")")}
o=gsub(" *([()]) *","\\1",o)
return(o)}
f(x)
}

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

> p("(1,2)")
[1] "(,)1 2"
> p("(1,2,3)")
[1] "(,,)1 2 3"
> p("((1,2),3)")
[1] "(,)((,)1 2)3"
> p("(1,2,3,4)")
[1] "(,,,)1 2 3 4"
> p("(1,(2,3))")
[1] "(,)1((,)2 3)"
> p("(10,1)")
[1] "(,)10 1"


2
261 बाइट्स के लिए गोल्फ । मैं जो कुछ भी बदल रहा था उसके लिए एक स्पष्टीकरण छोड़ दूंगा , लेकिन विडंबना यह है कि मुझे भी जाना है ... लेकिन +1, मैं इस पर अपना सिर नहीं लपेट सकता था; अच्छा काम!
ग्यूसेप

0

जावास्क्रिप्ट (ईएस 6), 72 बाइट्स

f=(a,b="",c="")=>a.map?b+"("+a.map(x=>'')+")"+a.map(x=>f(x,"(",")"))+c:a

इनपुट: संख्या और / या सरणियों युक्त सरणी

आउटपुट: स्ट्रिंग

उपयोग: f ([...])

सभी परीक्षण मामलों को पूरा करता है, सुधार में आपका स्वागत है


0

सी, 308 या 339 बाइट्स

#include <ctype.h>
#define p putchar
f(s,e,c,i,l)char*s,*e,*c;{i=1,l=40;if(*s++==l){p(l);for(c=s;i;i+=*c==l,i-=*c==41,i+*c==45&&p(44),c++);p(41);}for(;s<e;s=c){for(i=0;isdigit(*s);s+=*s==44)for(i&&p(32),i=1;isdigit(*s);s++)p(*s);*s==l&&p(l);for(c=s,i=1;++c,c<=e&&i;i+=*c==l)i-=*c==41;f(s,c-1);*s==l&&p(41);}}
#define g(x) f(x, x+strlen(x))

308 या 339 बाइट्स, इनपुट स्ट्रिंग के अंत में एक पॉइंटर को पारित करने या न करने पर निर्भर करता है; अंतिम पंक्ति केवल एक स्ट्रिंग शाब्दिक है जो इसकी लंबाई की गणना किए बिना सीधे पारित करने की अनुमति देती है।

व्याख्या

एक बहुत ही सरल एल्गोरिथ्म। यह वर्तमान गहराई पर अल्पविरामों की संख्या को गिनाता है, उन्हें टुपल कंस्ट्रक्टर के रूप में प्रिंट करता है, फिर टपल के तर्कों के साथ अनुसरण करता है, बच जाता है (संख्याओं के बीच रिक्त स्थान, कोष्ठक के बीच नेस्टेड ट्यूपल्स), पुनरावर्ती।

#include <stdio.h>
#include <ctype.h>
typedef enum { false, true } bool;

void tup2ptsfree(char *s, char *e)
{
  int depth;
  char *c;

  if (*s++ == '(') { /* If we are at the start of a tuple, write tuple function `(,,,)` (Otherwise, we are at a closing bracket or a comma) */
    putchar('(');
    /* do the search for comma's */
    c=s; /* probe without moving the original pointer */
    for (depth=1; depth != 0; c++) {
      if (*c == '(') depth++;
      if (*c == ')') depth--;
      if (*c == ',' && depth == 1) putchar(','); /* We have found a comma at the right depth, print it */
    }
    putchar(')');
  }
  while (s < e) { /* The last character is always ')', we can ignore it and save a character. */
    bool wroteNumber;
    for (wroteNumber=false; isdigit(*s); wroteNumber = true) {
      if (wroteNumber) p(' ');           /* If this is not the first number we are writing, add a space */
      while (isdigit(*s)) putchar(*s++); /* Prints the entire number */
      if (*s == ',') s++;                /* We found a ',' instead of a ')', so there might be more numbers following */
    }
    /* Add escaping parenthesis if we are expanding a tuple (Using a small if statement instead of a large branch to prevent doing the same thing twice, since the rest of the code is essentially the same for both cases). */
    if (*s == '(') putchar('(');
    /* Find a matching ')'... */
    c=s+1;
    for (depth=1; c <= e && depth != 0; c++) {
      if (*c == '(') depth++;
      if (*c == ')') depth--;
    }
    /* Found one */
    /* Note how we are looking for a matching paren twice, with slightly different parameters. */
    /* I couldn't find a way to golf this duplication away, though it might be possible. */
    /* Expand the rest of the tuple */
    tup2ptsfree(s, c-1);
    /* idem */
    if (*s == '(') putchar(')');
    /* Make the end of the last expansion the new start pointer. */
    s=c;
  }
}

#define h(x) tup2ptsfree(x, x+strlen(x))

परीक्षण मामलों और आवेदन

#include <stdio.h>

#define ARRAYSIZE(arr) (sizeof(arr)/sizeof(*arr))
static char *examples[] = {
  "(1,2)",
  "(10,1)",
  "(1,2,3)",
  "(1,2,3,4)",
  "((1,2),3)",
  "(1,(2,3))",
  "(1,(2,3),4)",
  "((1,2),(3,4))",
  "((1,(2,3)),4,(5,6))",
  "((1,((2,3), 4)),5,(6,7))",
  "(42,48)",
  "(1,2,3,4,5,6,7)"
};

int main(void)
{
  int i;
  for (i=0; i < ARRAYSIZE(examples); i++) {
    printf("%-32s | \"", examples[i]);
    g(examples[i]); /* Test with golfed version */
    printf("\"\n");
    printf("%-32s | \"", examples[i]);
    h(examples[i]); /* Test with original version */
    printf("\"\n");
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.