একটি লিসপ-এর মতো সিনট্যাক্স ফর্ম্যাট করা


23

পটভূমি

(একটি সত্য, হৃদয় ছড়িয়ে দেওয়া গল্পের উপর ভিত্তি করে)

আমার সময়ে, আমি প্রায়শই লিস্প এবং অনুরূপ ভাষার সাথে প্রায় খেলেছি। আমি তাদের সাথে লিখেছি, তাদের চালিয়েছি, তাদের ব্যাখ্যা করেছি, তাদের ডিজাইন করেছি, এবং মেশিনগুলি তাদের সাথে আমার জন্য লেখার জন্য তৈরি করেছি ... এবং যদি আমাকে বিরক্ত করার মতো একটি জিনিস থাকে তবে এটি লিস্পকে দেখছে যা আমার নির্দিষ্ট বিন্যাসের শৈলী মেনে চলে না।

দুর্ভাগ্যক্রমে, কিছু পাঠ্য সম্পাদক ( কাশি এক্সকোড কাশি ) যখনই কোড অনুলিপি এবং পেস্ট করা হচ্ছে তখন আমার সুন্দর ট্যাবগুলি এবং স্পেসগুলি সরিয়ে ফেলেন ... সুন্দরভাবে ব্যবধানযুক্ত লিস্পের মতো সিনট্যাক্সটি নিন:

(A
    (B
        (C)
        (D))
    (E))

( ABCDEস্বেচ্ছাসেবী কর্ম কোথায় )

কিছু পাঠ্য সম্পাদকরা নীচের প্রান্তে এই সুন্দর কোডটি কসাইছেন:

(A
(B
(C)
(D))
(E))

কী এলোমেলো! তা পাঠযোগ্য নয়!

এখানে আমাকে সাহায্য করুন?

চ্যালেঞ্জ

এই চ্যালেঞ্জের আপনার লক্ষ্যটি হ'ল নীচে বর্ণিত একটি ফর্ম্যাটে নিউলাইন দ্বারা পৃথক করা বিভিন্ন ক্রিয়াকলাপ গ্রহণ করা এবং আরও সুন্দর বিন্যাস ফিরিয়ে দেওয়া যা পাঠযোগ্যতা এবং কমনীয়তা হাইলাইট করে।

ইনপুট

আমরা Fআরটি Nআর্গুমেন্টগুলির একটি ক্রিয়াকে নিম্নলিখিতের অনুরূপ নির্মাণ হিসাবে সংজ্ঞায়িত করি :

(F (G1 ...) (G2 ...) (G3 ...) ... (GN ...))

যেখানে G1, G2, ..., GNসমস্ত কার্য নিজের মধ্যে রয়েছে themselves একটি আরটি 0ফাংশন Aসহজভাবে হয় (A), যখন একটি আরটি 2ফাংশন Bফর্মের হয়(B (...) (...))

আপনার কোডটি প্রতিটি ফাংশনের শীর্ষস্থানীয় প্রথম বন্ধনী (প্রথম ফাংশন ব্যতীত) এর আগে একক নিউলাইন সহ ফাংশনের একটি সিরিজ হিসাবে ইনপুট নেওয়া উচিত। উপরের উদাহরণটি বৈধ ইনপুট।

আপনি ধরে নিতে পারেন:

  • প্রথম বন্ধনী সুষম হয়।
  • কোনও ক্রিয়াকলাপটি কখনই 250 এর বেশি বার চাপতে হবে না।
  • প্রতিটি ফাংশন বন্ধনী দ্বারা বেষ্টিত: ()
  • কোনও ফাংশনটির নামটিতে কেবল ছাপাযোগ্য ASCII অক্ষর থাকবে।
  • কোনও ফাংশনের নামে কখনই প্রথম বন্ধনী বা স্পেস থাকবে না।
  • ইনপুটটিতে একটি alচ্ছিক ট্রেলিং নিউলাইন রয়েছে।

আউটপুট

আপনার কোডগুলিতে একই ফাংশনের সেট আউটপুট করা উচিত , যেখানে কেবলমাত্র পরিবর্তনগুলি ফাংশনগুলির শীর্ষস্থানীয় বন্ধনীগুলির আগে স্পেস বা ট্যাবগুলির সংযোজন। আউটপুট নিম্নলিখিত নিয়ম মেনে চলতে হবে:

  • প্রদত্ত প্রথম ফাংশন (এবং পরে শীর্ষ-স্তরের ফাংশন) এর পূর্ববর্তী স্থান থাকা উচিত নয়
  • কোনও ফাংশনের অনুভূমিক অবস্থানের জন্য একটি যুক্তি হ'ল ফাংশনের অনুভূমিক অবস্থানের ডানদিকে এক ট্যাব।
  • একটি ট্যাব বাস্তবায়ন-সংজ্ঞায়িত, তবে কমপক্ষে 3 টি স্পেস থাকতে হবে।
  • আপনি প্রতিটি লাইনের পরে সর্বোচ্চ দুটি স্পেস optionচ্ছিকভাবে মুদ্রণ করতে পারেন।

বিধি

উদাহরণ

ইনপুট:

(A
(B
(C)
(D))
(E))

আউটপুট:

(A
    (B
        (C)
        (D))
    (E))

ইনপুট:

(!@#$%^&*
(asdfghjklm
(this_string_is_particularly_long
(...))
(123456789)))
(THIS_IS_TOP_LEVEL_AGAIN
(HERE'S_AN_ARGUMENT))

আউটপুট:

(!@#$%^&*
    (asdfghjklm
        (this_string_is_particularly_long
            (...))
        (123456789)))
(THIS_IS_TOP_LEVEL_AGAIN
    (HERE'S_AN_ARGUMENT))

ইনপুট:

(-:0
(*:0
(%:0
(Arg:6)
(Write:0
(Read:0
(Arg:30))
(Write:0
(Const:-6)
(Arg:10))))
(%:0
(Const:9)
(/:0
(Const:-13)
(%:0
(Arg:14)
(Arg:0)))))
(WriteArg:22
(-:0
(Const:45)
(?:0
(Arg:3)
(Arg:22)
(Arg:0)))))

আউটপুট:

(-:0
    (*:0
        (%:0
            (Arg:6)
            (Write:0
                (Read:0
                    (Arg:30))
                (Write:0
                    (Const:-6)
                    (Arg:10))))
        (%:0
            (Const:9)
            (/:0
                (Const:-13)
                (%:0
                    (Arg:14)
                    (Arg:0)))))
    (WriteArg:22
        (-:0
            (Const:45)
            (?:0
                (Arg:3)
                (Arg:22)
                (Arg:0)))))

হট নেটওয়ার্ক প্রশ্নগুলির তালিকা তৈরির জন্য অভিনন্দন! : ডি
অ্যালেক্স এ।

@AlexA। হুররে! আমার স্বপ্নগুলি বাস্তবে রূপ নিয়েছে। : ডি
ব্রেইনস্টিল

যদি কোনও ফাংশন নাম না থাকে তবে কি ()?
22:55

ইন্ডেন্টেশনটি কি> = 3 স্পেস থাকতে হবে, বা কোনও ট্যাব গ্রহণযোগ্য?
isaacg

@ আইসএকেজি আপনি ধরে নিতে পারেন যে সমস্ত ফাংশন এই ক্ষেত্রে নামকরণ করা হয়েছে। এবং আপনার ওএস / ভাষাকে যে কোনও অনুভূমিক ট্যাব হিসাবে সংজ্ঞায়িত করা ঠিক আছে is আপনি যদি স্পেস ব্যবহার করেন তবে কমপক্ষে ৩ টি অবশ্যই থাকতে হবে I'll আমি স্পষ্ট করে বলব যে আমি যখন একটি কম্পিউটারে যেতে পারি। ধন্যবাদ!
ব্রেইনস্টিল

উত্তর:


9

পাইথ, 24 20 19 18 বাইট

FN.z+*ZC9N~Z-1/N\)

প্রতিটি লাইনের জন্য একটি কাউন্টার বাড়ায়, এখনও অবধি বন্ধ হওয়া বন্ধনীগুলির মোট সংখ্যা গণনা করে এবং কাউন্টার থেকে বিয়োগ করে। তারপরে আমরা counterট্যাবগুলিতে ইন্ডেন্ট করি ।


@ ডাউনভোটার কেয়ার ব্যাখ্যা করার জন্য?
orlp

আমি ডাউনটোট করি নি, তবে এটি *4একটি হার্ডকোডযুক্ত এবং অপ্রয়োজনীয় পছন্দ। FN.z+*ZC9N~Z-1/N\)আপনাকে আপনার সম্পাদকের ইনডেন্ট প্রস্থ ব্যবহার করতে দেয় এবং একটি বাইট সংরক্ষণ করে।
সিস টিমারম্যান

আমি একমত, একটি ট্যাব একটি চরিত্রের খাটো হবে। \<tab>বা C9
isaacg

9

সাধারণ লিপ - 486 414 বাইট (রুবে গোল্ডবার্গ সংস্করণ)

(labels((p(x d)(or(when(listp x)(#2=princ #\()(p(car x)d)(incf d)(dolist(a(cdr x))(format t"~%~v{   ~}"d'(t))(p a d))(#2# #\)))(#2# x))))(let((i(make-string-input-stream(with-output-to-string(o)(#1=ignore-errors(do(b c)(())(if(member(setq c(read-char))'(#\( #\) #\  #\tab #\newline):test'char=)(progn(when b(prin1(coerce(reverse b)'string)o))(#2# c o)(setq b()))(push c b))))))))(#1#(do()(())(p(read i)0)(terpri)))))

অভিগমন

অন্য সবার মতো করা এবং হাতের মাধ্যমে প্রথম বন্ধনীর সংখ্যা গণনা করার পরিবর্তে আসুন আমরা লিপপ রিডারকে অনুরোধ করি এবং এটি করি সঠিক উপায়ে করুন :-)

  • ইনপুট স্ট্রিম থেকে পড়ুন এবং একটি অস্থায়ী আউটপুট প্রবাহে লিখুন।
  • এটি করার সময়, সামগ্রিক অক্ষরগুলি থেকে আলাদা ( , )স্ট্রিং যেমন হোয়াইটস্পেস বা।
  • মধ্যবর্তী আউটপুট একটি স্ট্রিং তৈরি করতে ব্যবহৃত হয়, এতে সিনট্যাকটিক্যালি সু-সুগঠিত কমন-লিস্প ফর্মগুলি থাকে: স্ট্রিংগুলির নেস্টেড তালিকা।
  • স্ট্রিংটিকে ইনপুট স্ট্রিম হিসাবে ব্যবহার করে readপ্রকৃত তালিকা তৈরি করতে স্ট্যান্ডার্ড ফাংশনটি কল করুন ।
  • pসেই তালিকাগুলির প্রত্যেককে কল করুন, যা অনুরোধকৃত বিন্যাসের সাথে স্ট্যান্ডার্ড আউটপুটে পুনরাবৃত্তি করে তাদের লিখুন। বিশেষত, স্ট্রিংগুলি বিনা শর্তে মুদ্রিত হয়।

এই পদ্ধতির ফলাফল হিসাবে:

  1. ইনপুট ফর্ম্যাটটিতে কম বিধিনিষেধ রয়েছে: আপনি কেবল "প্রতি লাইনে একটি ফাংশন" (উঘ) নয়, ইচ্ছামত বিন্যাসিত ফর্ম্যাট ইনপুটগুলি পড়তে পারেন।
  2. এছাড়াও, যদি ইনপুটটি সুগঠিত না হয় তবে একটি ত্রুটি সংকেত দেওয়া হবে।
  3. পরিশেষে, চমত্কার-মুদ্রণ ফাংশনটি পার্সিং থেকে ভালভাবে ডুপ্লোল করা হয়েছে: আপনি সহজেই প্রিটি-প্রিন্টিং এস-এক্সপ্রেশনগুলির অন্য কোনও পথে স্যুইচ করতে পারেন (এবং আপনি যদি আপনার উল্লম্ব স্থানটিকে মূল্য দেন তবে)।

উদাহরণ

এই মোড়ক ব্যবহার করে একটি ফাইল থেকে পড়া:

(with-open-file (*standard-input* #P"path/to/example/file")
    ...)

ফলাফল এখানে:

(!@#$%^&*
    (asdfghjklm
        (this_string_is_particularly_long
            (...))
        (123456789)))
(THIS_IS_TOP_LEVEL_AGAIN
    (HERE'S_AN_ARGUMENT))
(-:0
    (*:0
        (%:0
            (Arg:6)
            (Write:0
                (Read:0
                    (Arg:30))
                (Write:0
                    (Const:-6)
                    (Arg:10))))
        (%:0
            (Const:9)
            (/:0
                (Const:-13)
                (%:0
                    (Arg:14)
                    (Arg:0)))))
    (WriteArg:22
        (-:0
            (Const:45)
            (?:0
                (Arg:3)
                (Arg:22)
                (Arg:0)))))

(মনে হচ্ছে এখানে ট্যাবগুলি স্পেসে রূপান্তরিত হয়েছে)

বেশ-মুদ্রিত (গল্ফযুক্ত সংস্করণ)

নিরাপদ মূল সংস্করণের বিপরীতে আমরা প্রত্যাশা করি বৈধ হবে be

(labels ((p (x d)
           (or
            (when (listp x)
              (princ #\()
              (p (car x) d)
              (incf d)
              (dolist (a (cdr x)) (format t "~%~v{  ~}" d '(t)) (p a d))
              (princ #\)))
            (princ x))))
  (let ((i
         (make-string-input-stream
          (with-output-to-string (o)
            (ignore-errors
             (do (b
                  c)
                 (nil)
               (if (member (setq c (read-char)) '(#\( #\) #\  #\tab #\newline)
                           :test 'char=)
                   (progn
                    (when b (prin1 (coerce (reverse b) 'string) o))
                    (princ c o)
                    (setq b nil))
                   (push c b))))))))
    (ignore-errors (do () (nil) (p (read i) 0) (terpri)))))

7

রেটিনা , 89 83 বাইট

s`.+
$0<tab>$0
s`(?<=<tab>.*).
<tab>
+ms`^((\()|(?<-2>\))|[^)])+^(?=\(.*^((?<-2><tab>)+))
$0$3
<tab>+$
<empty>

যেখানে <tab>প্রকৃত ট্যাব অক্ষর (0x09) এবং <empty>খালি রেখার জন্য দাঁড়িয়েছে। এই প্রতিস্থাপনগুলি করার পরে, আপনি উপরের কোডটি চালাতে পারেন-s পতাকা । তবে, আমি সেই পতাকাটি গণনা করছি না, কারণ আপনি প্রতিটি লাইনকে তার নিজস্ব উত্স ফাইলটিতে স্রেফ রেখে দিতে পারেন, সেক্ষেত্রে অতিরিক্ত উত্স ফাইলগুলির জন্য 7 টি নতুন লাইনগুলি 7 টি পেনাল্টি বাইট দ্বারা প্রতিস্থাপন করা হবে।

এটি একটি সম্পূর্ণ প্রোগ্রাম, STDIN এ ইনপুট নিচ্ছে এবং ফলাফলটি STDOUT এ মুদ্রণ করছে।

ব্যাখ্যা

প্রতিটি জোড় রেখা একটি রেজেক্স বিকল্পকে সংজ্ঞায়িত করে। মূল ধারণাটি হ'ল প্রদত্ত অবধি বর্তমান গভীরতা গণনা করার জন্য .NET এর ভারসাম্যমূলক গোষ্ঠী ব্যবহার করা (এবং তারপরে তার আগে অনেকগুলি ট্যাব .োকানো (

s`.+
$0<tab>$0

প্রথমত, আমরা ইনপুট প্রস্তুত করি। আমরা সত্যিই শর্তসাপেক্ষ সংখ্যক ট্যাবগুলি আবার লিখতে পারি না, যদি আমরা সেগুলি ক্যাপচারের জন্য ইনপুট স্ট্রিংয়ের কোথাও এটি না পাই। সুতরাং আমরা কোনও ট্যাব দ্বারা পৃথক করে পুরো ইনপুটটির সদৃশ করে শুরু করি। নোট করুন যে s`স্রেফ একক-লাইন (বা "ডট-অল") সংশোধক সক্রিয় করে, এটি নিশ্চিত করে যে .এটিও নতুন লাইনের সাথে মেলে।

s`(?<=<tab>.*).
<tab>

এখন আমরা সেই ট্যাবটির পরে প্রতিটি অক্ষর পাশাপাশি ট্যাবে পরিণত করি। এটি আমাদের এখনও পর্যন্ত মূল স্ট্রিংটি পরিবর্তন না করে স্ট্রিংয়ের শেষে পর্যাপ্ত পরিমাণে ট্যাব সরবরাহ করে।

+ms`^((\()|(?<-2>\))|[^)])+^(?=\(.*^((?<-2><tab>)+))
$0$3

এটি সমাধানের মাংস। mএবং sবহু-লাইন মোড (যাতে সক্রিয় ^লাইনের সূত্রপাত মিলছে) এবং একক লাইন মোড। +রেটিনা বলে এই প্রতিকল্পন পুনরাবৃত্তি না হওয়া পর্যন্ত আউটপুট পরিবর্তন স্টপ (এই ক্ষেত্রে উপায়ে প্যাটার্ন আর স্ট্রিং মিলে যায় যতক্ষণ না যে,) রাখা।

প্যাটার্ন নিজেই ইনপুটটির একটি প্রিফিক্সের সাথে অ-প্রক্রিয়াজাতকরণের সাথে মেলে (( (এটির আগে এটির কোনও ট্যাব নেই, তবে হওয়া উচিত)। একই সময়ে এটি ভারসাম্যপূর্ণ গ্রুপগুলির সাথে উপসর্গের গভীরতা নির্ধারণ করে, যেমন স্ট্যাকের উচ্চতা 2বর্তমান গভীরতার সাথে মিলিত হবে এবং তাই আমাদের সংখ্যক ট্যাব সংযোজন করতে হবে। এটি এই অংশ:

((\()|(?<-2>\))|[^)])+

এটি হয় একটির সাথে মেলে (, এটি 2স্ট্যাকের দিকে ঠেলাঠেলি করে , বা এটি )একটির সাথে মেলে , 2স্ট্যাক থেকে শেষ ক্যাপচারিংটি পোপ করে , বা এটি অন্য কোনও কিছুর সাথে মেলে এবং স্ট্যাকটি আড়াল করে ফেলে। যেহেতু প্রথম বন্ধনীগুলি ভারসাম্যযুক্ত হওয়ার গ্যারান্টিযুক্ত আমাদের খালি স্ট্যাক থেকে পপ করার চেষ্টা করার চিন্তা করার দরকার নেই।

আমরা এই জাতীয় স্ট্রিংটি (পেরিয়ে যাওয়ার পরে এবং থামার জন্য কোনও প্রক্রিয়াবিহীন দেখতে পেলাম , ততক্ষণে তক্ষকটি স্ট্রিংয়ের শেষের দিকে এগিয়ে 3যায় এবং 2স্ট্যাক থেকে ফাঁকা হয়ে যাওয়ার পরে ট্যাবগুলিকে গ্রুপে ক্যাপচার করে :

(?=\(.*^((?<-2><tab>)+))

+সেখানে একটি ব্যবহার করে , আমরা নিশ্চিত করে নিই যে প্যাটার্নটি কেবলমাত্র কোনও কিছুর সাথে মিলে যায় যদি কমপক্ষে একটি ট্যাব ম্যাচে sertedোকানো উচিত - যখন একাধিক রুট-স্তরের ফাংশন থাকে তখন এটি অসীম লুপটিকে এড়িয়ে চলে।

<tab>+$
<empty>

শেষ অবধি, ফলাফলটি সাফ করার জন্য আমরা স্ট্রিংয়ের শেষে সেই সাহায্যকারী ট্যাবগুলি থেকে মুক্তি পেয়েছি।


এটি খুব দুর্দান্ত। সাবাশ! রেটিনা দেখে সর্বদা আনন্দ হয়
BrainSteel

6

সি: 95 94 টি অক্ষর

এটি এখনও খুব গল্ফ হয়নি, এবং প্রশ্ন থেকে আমি নিশ্চিত নই যে ট্যাব গ্রহণযোগ্য কিনা, যা আমি এখানে ব্যবহার করি।

i,j;main(c){for(;putchar(c=getchar()),c+1;i+=c==40,i-=c==41)if(c==10)for(j=i;j--;putchar(9));}

Ungolfed:

i,j;
main(c){
  for(
    ;
    putchar(c=getchar()),
    c+1;
    i+=c==40,
    i-=c==41
  )
    if(c==10)
      for(
        j=i;
        j--;
        putchar(9)
      );
}

সম্পাদনা করুন: এটি তৈরি করুন যাতে এটি ইওএফ ছাড়বে।


ট্যাবগুলি পুরোপুরি গ্রহণযোগ্য।
ব্রেইনস্টিল

2
আপনি কি if(c<11)পরিবর্তে ব্যবহার করতে পারেন if(c==10)?
ডিজিটাল ট্রমা

5

জুলিয়া, 103 99 97 94 88 বাইট

p->(i=j=0;for l=split(p,"\n") i+=1;println("\t"^abs(i-j-1)*l);j+=count(i->i=='\)',l)end)

এটি একটি নামবিহীন ফাংশন সংজ্ঞায়িত করে যা একটি স্ট্রিং গ্রহণ করে এবং ইনডেন্টেড সংস্করণটি মুদ্রণ করে। এটি কল করার জন্য, এটির একটি নাম দিন f=p->...। নোট করুন যে ইনপুটটি অবশ্যই একটি বৈধ জুলিয়া স্ট্রিং হওয়া উচিত, তাই ডলারের লক্ষণগুলি ( $) অবশ্যই অব্যাহতি লাভ করতে পারে।

অবহেলিত + ব্যাখ্যা:

function f(p)
    # Set counters for the line number and the number of close parens
    i = j = 0

    # Loop over each line of the program
    for l in split(p, "\n")
        # Increment the line number
        i += 1

        # Print the program line with |i-j-1| tabs
        println("\t"^abs(i-j-1) * l)

        # Count the number of close parens on this line
        j += count(i -> i == '\)', l)
    end
end

উদাহরণস্বরূপ, চারটি স্পেসের প্রতিটি সেট ভান করা একটি ট্যাব:

julia> f("(A
(B
(C)
(D))
(E))")

(A
    (B
        (C)
        (D))
    (E))

কোন পরামর্শ স্বাগত চেয়ে বেশি!



3

পার্ল, 41

$_="\t"x($i-$j).$_;$i+=y/(/(/;$j+=y/)/)/

40+1জন্য অক্ষর -p

সাথে চালান:

cat input.txt | perl -pe'$_="\t"x($i-$j).$_;$i+=y/(/(/;$j+=y/)/)/'

3

পাইথন 2 - 88 78 বাইট

মোটামুটি সোজা (এবং খুব সংক্ষিপ্ত নয়) সমাধান:

l=0
for x in raw_input().split():g=x.count;d=l*'\t'+x;l+=g("(")-g(")");print d

একটি দম্পতি টিপস: 1) আপনি '\t'পরিবর্তে ব্যবহার করতে পারেন ' 'এবং একটি বাইট সংরক্ষণ করতে পারেন ; 2) দায়িত্ব অর্পণ কোন প্রয়োজন থেকে input.split(), একটি পরিবর্তনশীল যেহেতু এটি শুধুমাত্র একবার (একই ব্যবহৃত হচ্ছে c, সেইসাথে d--just সরাতে printবিবৃতি); 3) অপারেটর অগ্রাধিকার অর্থ কাছাকাছি প্রথম বন্ধনী l*cপ্রয়োজন হয় না। এছাড়াও, দেখে মনে হচ্ছে fএটি কোনও কিছুর জন্য ব্যবহৃত হয় না - এটি কি আগের সংস্করণের একটি প্রতীক?
ডিএলসাস

এছাড়াও, এটি যদি পাইথন 2 হয় তবে আপনার raw_inputপরিবর্তে এটি ব্যবহার করতে হবে input(এবং এর পরে বন্ধনীগুলি ভুলে যাবেন না!)।
ডিএলসাস

2

সিজোম, 20 বাইট

r{_')e=NU)@-:U9c*r}h

সিজেএম ইন্টারপ্রেটারে এটি অনলাইনে চেষ্টা করুন ।

কিভাবে এটা কাজ করে

r                    e# Read a whitespace-separated token R from STDIN.
{                 }h e# Do, while R is truthy: 
  _')e=              e#   Push C, the number of right parentheses in R. 
       NU            e#   Push a linefeed and U (initially 0).
         )@-         e#   Compute U + 1 - C.
            :U       e#   Save in U.
              9c*    e#   Push a string of U tabulators.
                 r   e#   Read a whitespace-separated token R from STDIN.
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.