মিউট্যান্ট প্যাঙ্গোলিন


28

এটি একটি কোড-গল্ফ চ্যালেঞ্জ, যার মাধ্যমে আপনাকে এমন একটি প্রোগ্রাম তৈরি করতে হবে যা মেশিন শেখার চিত্রিত করার জন্য নিজেকে রুপান্তরকারী কোয়াইন বা শিকলের মতো কাজ করে।

পটভূমি

এখানে 'প্যাঙ্গোলিন গেম' নামে একটি প্রাথমিক কৃত্রিম বুদ্ধিমত্তার প্রোগ্রাম রয়েছে যা এখানে বর্ণিত হয়েছে । প্রাথমিক ধারণাটি হ'ল প্রোগ্রামটি যখন প্রথমবার চালিত হয় তখন জিজ্ঞাসা করে:

ঠিক আছে, দয়া করে কিছু ভাবুন

এটি কি প্যাঙ্গোলিন?

এরপরে আপনি উত্তর দিতে পারেন:

হাঁ

এই ক্ষেত্রে এটি বলে:

ভাল. এটা খুব সহজ ছিল।

বা যদি না এটি বলে:

উহু. আচ্ছা আপনি তখন জিতলেন - আপনি কী ভাবছিলেন?

আপনি যা বলতে পারেন:

একটি কুকুর

যা এটা বলবে

দয়া করে আমাকে একটি কুকুর সম্পর্কে একটি প্রশ্ন দিন, তাই আমি কুকুর এবং পাঙ্গোলিনের মধ্যে পার্থক্য বলতে পারি

আপনি উত্তর দিতে পারে

এটি কি পিঁপড়া খায়?

এটি তখন জিজ্ঞাসা করবে:

কুকুরের উত্তর কী?

যা বলতে আপনি

না

এবং এটা বলতে হবে

ধন্যবাদ

পরের বার এটি চলার পরে এটি উপরের প্রশ্নটি জিজ্ঞাসা করবে এবং এ জাতীয় প্রশ্নের একটি বাইনারি গাছ তৈরি করবে।

চ্যালেঞ্জ

পটভূমি যথেষ্ট। এই চ্যালেঞ্জটি একটি স্ব পরিবর্তনকারী প্যাঙ্গোলিন প্রোগ্রাম লেখার জন্য write নিয়মগুলি নিম্নরূপ:

  1. প্রোগ্রাম আউটপুট (উপরে বর্ণিত হিসাবে) হওয়া উচিত STDERR। চূড়ান্ত প্রতিক্রিয়া সর্বদা "ভাল। এটি খুব সহজ ছিল।" বা "ধন্যবাদ"। এর পরে, এটি হয় প্রোগ্রামটির বর্তমান সংস্করণ বা প্রোগ্রামটির নতুন সংস্করণ যা ফলাফলকে যুক্ত করে STDOUT। কোন উত্তর একটি ভাষা যে লিখিতভাবে সমর্থন করে না লেখা STDOUTএবং STDERRবা থেকে পড়া STDINকার্যকর থাকবে।

  2. ইউনিক্সের অধীনে অন্য কথায় আপনি এইভাবে প্রোগ্রামটি চালাতে পারেন:

উদাহরণ:

$ mylanguage myprogram > myprogram.1
[dialog goes here]
$ mylanguage myprogram1 > myprogram.2
[dialog goes here]
  1. প্রোগ্রামটিতে নির্দিষ্ট প্রম্পটগুলি অবশ্যই ব্যবহার করতে হবে (কারণ প্রম্প্টগুলি সংক্ষিপ্ত করা কোনও দক্ষতা দেখায় না)। অনুরোধগুলি হ'ল (উদ্ধৃতি ব্যতীত এবং যেখানে% s প্রতিস্থাপন করা হয়) নীচে রয়েছে:

তালিকা:

"OK, please think of something"
"Is it %s?"
"Good. That was soooo easy."
"Oh. Well you win then -- What were you thinking of?"
"Please give me a question about %s, so I can tell the difference between %s and %s"
"What is the answer for %s?"
"Thanks"
  1. যখন হ্যা / না উত্তর আশা, আপনার প্রোগ্রাম গ্রহণ করা উচিত yবা yes'হ্যাঁ' এর জন্য কোনো ক্ষেত্রে, এবং nবা noজন্য 'না' কোনো ক্ষেত্রে। আপনি অ-সঙ্গতিপূর্ণ ইনপুটগুলি দিয়ে যা করেন তা আপনার উপর নির্ভর করে। উদাহরণস্বরূপ যদি আপনি কোন উত্তর যে দিয়ে শুরু হয় নেওয়া সিদ্ধান্ত নিতে পারে yঅথবা Y'হাঁ' হিসাবে, এবং কোন হিসাবে অন্য কিছু।

  2. আপনি ধরে নিতে পারেন যে সরবরাহিত জিনিসগুলির নাম এবং প্রশ্নগুলিতে কেবলমাত্র ASCII অক্ষর, সংখ্যা, স্পেস, হাইফেনস, প্রশ্ন চিহ্ন, কমা, পুরো স্টপস, কোলোন এবং সেমিকোলন থাকে, অর্থাত্‍ সেগুলি রেগেক্সের সাথে মিলে যায় ^[-?,.;: a-zA-Z]+$। আপনি যদি এর চেয়ে বেশি (বিশেষত আপনার নির্বাচিত ভাষায় উদ্ধৃত চরিত্রগুলি) মোকাবেলা করতে পারেন তবে আপনি স্মাগ হয়ে যাবেন, তবে কোনও অতিরিক্ত পয়েন্ট পাবেন না।

  3. তোমার প্রোগ্রাম পড়তে বা লিখতে নাও হতে পারে কোনো ফাইল (ব্যতীত STDIN, STDOUTআর STDERR), অথবা নেটওয়ার্ক থেকে; বিশেষত এটি ডিস্ক থেকে নিজস্ব কোড না পড়তে বা লিখতে পারে না। এর রাষ্ট্রটি অবশ্যই প্রোগ্রাম কোডে সংরক্ষণ করতে হবে।

  4. যখন প্রোগ্রামটি চালানো হয় এবং উত্তরটি সঠিকভাবে অনুমান করে, তখন এটি অবশ্যই একটি কুইন হিসাবে সম্পাদন করতে হবে, অর্থাত্ এটি অবশ্যই STDOUTতার নিজের কোডটিতে লিখতে হবে , অপরিবর্তিত।

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

  6. আপনাকে অবশ্যই সফ্টওয়্যারটির একাধিক ক্রমিক রানের সাথে মোকাবিলা করতে সক্ষম হতে হবে যাতে এটি অনেকগুলি অবজেক্ট সম্পর্কে জানতে পারে। একাধিক রানের উদাহরণের জন্য এখানে দেখুন ।

  7. টেস্ট রানগুলি মাথার লিঙ্কে দেওয়া হয় (স্পষ্টতই কেবলমাত্র STDINএবং STDERRডায়ালগটি covering েকে দেওয়া)।

  8. স্ট্যান্ডার্ড লুফোলগুলি বাদ দেওয়া হয়েছে।


প্রোগ্রামটি একাধিকবার পরিবর্তন করতে এবং 2 টিরও বেশি প্রাণী সমর্থন করতে সক্ষম হবে? যদি তাই হয়, যখন প্রোগ্রামটি ইতিমধ্যে দু'তত বেশি প্রাণীকে জানে তখন আপনি কি দয়া করে "দয়া করে আমাকে ..." সম্পর্কে একটি কথোপকথনের একটি উদাহরণ সরবরাহ করতে পারেন ?
ক্রিশ্চিয়ান লুপাস্কু

যদি ব্যবহারকারী কেবল "কুকুর" এর পরিবর্তে "কুকুর" বলে? "A / an" সনাক্ত করার জন্য আমরা কি বাক্যটিকে পার্স করব বা আমরা উত্তরটি আক্ষরিকভাবে আচরণ করতে পারি? আমি ধরে নিলাম আপনার দেওয়া অনুরোধগুলি (% s) দেওয়া হয়েছে।
coredump

1
@ কর্ডম্প্প যদি ব্যবহারকারী বলেন "কুকুর" "কুকুর" নয়, তবে উত্তরগুলি ব্যাকরণগত হবে না। এটি কোনও সমস্যা নয়।
7:55

1
নগদ টাকা। রুনিকে এটি করার চেষ্টা করা দুঃস্বপ্ন হতে পারে। স্বেচ্ছাসেবক ইনপুট স্ট্রিংগুলি মোকাবেলার জন্য সমস্ত বিটগুলি ওয়্যারিং করা (যা তারপরে ফলাফল আউটপুট প্রোগ্রামের স্ট্রিং লিটারাল হিসাবে উপস্থিত হওয়া প্রয়োজন) প্রাথমিক কারণটি অসম্ভব হয়ে ওঠার প্রাথমিক কারণ। ওহ এবং রুনিক STDERR এ আউটপুট দিতে পারে না।
ড্রাকো 18

1
এটি একটি মজাদার "গেম" বলে মনে হয়েছিল, সুতরাং এটি গল্ফের চেয়ে আমি একটি কোডপেন তৈরি করেছি যেখানে আপনি আপনার হৃদয়ের বিষয়বস্তুতে প্যাঙ্গোলিন গেম খেলতে পারেন। উপভোগ করুন!
স্কিডদেব

উত্তর:


20

সাধারণ লিপ, 631 576

(let((X"a pangolin"))#1=(labels((U(M &AUX(S *QUERY-IO*))(IF(STRINGP M)(IF(Y-OR-N-P"Is it ~A?"M)(PROG1 M(FORMAT S"Good. That was soooo easy.~%"))(LET*((N(PROGN(FORMAT S"Oh. Well you win then -- What were you thinking of?~%")#2=(READ-LINE S)))(Q(PROGN(FORMAT S"Please give me a question about ~A, so I can tell the difference between ~A and ~A~%"N N M)#2#)))(PROG1(IF(Y-OR-N-P"What is the answer for ~A?"N)`(,Q ,N ,M)`(,Q ,M ,N))(FORMAT S"Thanks~%"))))(DESTRUCTURING-BIND(Q Y N)M(IF(Y-OR-N-P Q)`(,Q ,(U Y),N)`(,Q ,Y,(U N)))))))(write(list'let(list`(X',(U x)))'#1#):circle t)()))

উদাহরণ সেশন

স্ক্রিপ্টটির নাম দিন pango1.lispএবং কার্যকর করুন (এসবিসিএল ব্যবহার করে):

~$ sbcl --noinform --quit --load pango1.lisp > pango2.lisp
Is it a pangolin? (y or n) n
Oh. Well you win then -- What were you thinking of?
a cat
Please give me a question about a cat, so I can tell the difference between a cat and a pangolin
Does it sleep a lot?
What is the answer for a cat? (y or n) y
Thanks

আরেকটি বৃত্তাকার, ভালুক যোগ করুন:

~$ sbcl --noinform --quit --load pango2.lisp > pango3.lisp
Does it sleep a lot? (y or n) y

Is it a cat? (y or n) n
Oh. Well you win then -- What were you thinking of?
a bear
Please give me a question about a bear, so I can tell the difference between a bear and a cat
Does it hibernate?
What is the answer for a bear? (y or n) y
Thanks

একটি অলস যোগ করা হচ্ছে (উত্তরটি "না" যেখানে রয়েছে তা আমরা পরীক্ষা করি):

~$ sbcl --noinform --quit --load pango3.lisp > pango4.lisp
Does it sleep a lot? (y or n) y

Does it hibernate? (y or n) n

Is it a cat? (y or n) n
Oh. Well you win then -- What were you thinking of?
a sloth
Please give me a question about a sloth, so I can tell the difference between a sloth and a cat
Does it move fast?
What is the answer for a sloth? (y or n) n
Thanks

শেষ ফাইলটি পরীক্ষা করা হচ্ছে:

~$ sbcl --noinform --quit --load pango4.lisp > pango5.lisp
Does it sleep a lot? (y or n) y

Does it hibernate? (y or n) n

Does it move fast? (y or n) y

Is it a cat? (y or n) y
Good. That was soooo easy.

মন্তব্য

  • আমি প্রথম মুদ্রণ ভুলে গেছি "Thanks", এখানে।
  • আপনি দেখতে পাচ্ছেন, প্রশ্নগুলি অনুসরণ করা হয় (y or n), কারণ আমি বিদ্যমান y-or-n-pফাংশনটি ব্যবহার করছি । প্রয়োজনে এই আউটপুটটি সরিয়ে ফেলতে আমি উত্তর আপডেট করতে পারি।
  • কমন লিস্পের একটি দ্বি *QUERY-IO*- নির্দেশমূলক প্রবাহ থাকে যা ব্যবহারকারী- কথোপকথনে উত্সর্গীকৃত, যা আমি এখানে ব্যবহার করছি। স্ট্যান্ডার্ড আউটপুট এবং ব্যবহারকারীর ইন্টারঅ্যাকশন বিঘ্নিত হয় না, যা আইএমএইচওকে অনুসরণ করে of
  • ব্যবহার SAVE-LISP-AND-DIEকরা অনুশীলনে আরও ভাল পদ্ধতির হতে পারে।

উত্পাদিত আউটপুট

এখানে সর্বশেষ উত্পন্ন স্ক্রিপ্টটি রয়েছে:

(LET ((X
       '("Does it sleep a lot?"
              ("Does it hibernate?" "a bear"
               ("Does it move fast?" "a cat" "a sloth"))
              "a pangolin")))
  #1=(LABELS ((U (M &AUX (S *QUERY-IO*))
                (IF (STRINGP M)
                    (IF (Y-OR-N-P "Is it ~A?" M)
                        (PROG1 M (FORMAT S "Good. That was soooo easy.~%"))
                        (LET* ((N
                                (PROGN
                                 (FORMAT S
                                         "Oh. Well you win then -- What were you thinking of?~%")
                                 #2=(READ-LINE S)))
                               (Q
                                (PROGN
                                 (FORMAT S
                                         "Please give me a question about ~A, so I can tell the difference between ~A and ~A~%" 
                                         N N M)
                                 #2#)))
                          (PROG1
                              (IF (Y-OR-N-P "What is the answer for ~A?" N)
                                  `(,Q ,N ,M)
                                  `(,Q ,M ,N))
                            (FORMAT S "Thanks~%"))))
                    (DESTRUCTURING-BIND
                        (Q Y N)
                        M
                      (IF (Y-OR-N-P Q)
                          `(,Q ,(U Y) ,N)
                          `(,Q ,Y ,(U N)))))))
       (WRITE (LIST 'LET (LIST `(X ',(U X))) '#1#) :CIRCLE T)
       NIL))

ব্যাখ্যা

সিদ্ধান্ত গাছ হতে পারে:

  • একটি "a pangolin"পাতার মতো , যা একটি পাতার প্রতিনিধিত্ব করে।
  • তিনটি উপাদানের একটি তালিকা: (question if-true if-false)যেখানে questionএকটি বন্ধ হ্যাঁ / কোনও প্রশ্ন নেই, একটি স্ট্রিং হিসাবে এবং if-trueএবং if-falseপ্রশ্নের সাথে যুক্ত দুটি সম্ভাব্য সাবট্রি রয়েছে।

Uফাংশন পদচারনা এবং ফেরৎ একটি সম্ভবত পরিবর্তিত গাছ। প্রতিটি প্রশ্নের পরিবর্তে জিজ্ঞাসা করা হয়, ব্যবহারকারীর সাথে কথোপকথনের সময় মূল থেকে শুরু করে কোনও পাতায় পৌঁছানো পর্যন্ত।

  • কোন মধ্যবর্তী নোড ফিরে মান (Q Y N)হয় (Q (U Y) N)(রেস্প। (Q Y (U N))যদি প্রশ্নের উত্তর) Qহয় হ্যাঁ (রেস্প। কোন )।

  • ব্যবহারকারীর কাছ থেকে নেওয়া মূল্যবোধ অনুসারে প্রোগ্রামটি সঠিকভাবে উত্তরটির জন্য অনুমান করে থাকে, বা একটি শোধিত গাছ যেখানে পাতাটি একটি প্রশ্ন এবং দুটি সম্ভাব্য ফলাফল দ্বারা প্রতিস্থাপন করা হয়, তা হ'ল একটি পাতার জন্য প্রত্যাবর্তিত মানটি হয় পাতা itself

এই অংশটি বরং সরল ছিল। উত্স কোডটি মুদ্রণের জন্য, আমরা স্ব-রেফারেন্সিয়াল কোড তৈরি করতে পাঠক ভেরিয়েবল ব্যবহার করি।*PRINT-CIRCLE*সত্য হিসাবে সেট করে, আমরা সুন্দর-প্রিন্টিংয়ের সময় অসীম পুনরাবৃত্তি এড়িয়ে চলি।এর WRITEসাথে ব্যবহারের কৌশলটি :print-circle Tহ'ল লেখার শেষ রূপটি কিনা তার উপর নির্ভর করে ফাংশনটি আরপিএলকেও মূল্য ফেরত দিতে পারে এবং তাই, যদি আরইপিএল বিজ্ঞপ্তি কাঠামো পরিচালনা করে না, যেমন এর মানক ডিফল্ট মান দ্বারা সংজ্ঞায়িত করা হয় *PRINT-CIRCLE*, সেখানে একটি অসীম পুনরাবৃত্তি হবে। আমাদের কেবল নিশ্চিত করতে হবে যে বিজ্ঞপ্তি কাঠামোটি আরইপিএলে ফিরে আসে না, এজন্যই এলইটির শেষ অবস্থানে একটি এনআইএল রয়েছে। এই পদ্ধতির ফলে সমস্যাটি হ্রাস হয়।


ভাল লাগছে! (y or n)প্রয়োজন হয় না, কিন্তু আমি যেমন একটি উন্নতি এটা অনুমতি প্রলুব্ধ করছি।
17

ধন্যবাদ Y / n সম্পর্কে, এটি দুর্দান্ত হবে, এটি সাহায্য করে এবং IMHO এটি # 3 এর সাথে বৈপরীত্যের নয় যা প্রম্পটগুলি সংক্ষিপ্ত করা এড়ানো সম্পর্কে।
coredump

9

পাইথন 2.7.6, 820 728 বাইট

(বিভিন্ন সংস্করণে কাজ করতে পারে তবে আমি নিশ্চিত নই)

def r(O,R):
 import sys,marshal as m;w=sys.stderr.write;i=sys.stdin.readline;t=O;w("OK, please think of something\n");u=[]
 def y(s):w(s);return i()[0]=='y'
 while t:
  if type(t)==str:
   if y("Is it %s?"%t):w("Good. That was soooo easy.")
   else:w("Oh. Well you win then -- What were you thinking of?");I=i().strip();w("Please give me a question about %s, so I can tell the difference between %s and %s"%(I,t,I));q=i().strip();a=y("What is the answer for %s?"%q);w("Thanks");p=[q,t];p.insert(a+1,I);z=locals();exec"O"+"".join(["[%s]"%j for j in u])+"=p"in z,z;O=z["O"]
   t=0
  else:u+=[y(t[0])+1];t=t[u[-1]]
 print"import marshal as m;c=%r;d=lambda:0;d.__code__=m.loads(c);d(%r,d)"%(m.dumps(R.__code__),O)
r('a pangolin',r)

ঠিক আছে, এটি কমন লিস্প উত্তরের মতো সংক্ষিপ্ত নয়, তবে এখানে কিছু কোড রয়েছে!


4

পাইথন 3, 544 বাইট

q="""
d=['a pangolin'];i=input;p=print
p("OK, Please think of something")
while len(d)!=1:
    d=d[1+(i(d[0])[0]=="n")]
x=i("Is it "+d[0]+"?")
if x[0]=="n":
    m=i("Oh. Well you win then -- What were you thinking of?")
    n=[i("Please give me a question about "+m+", so I can tell the difference between "+d[0]+" and "+m),*[[d[0]],[m]][::(i("What is the answer for "+m+"?")[0]=="n")*2-1]]
    p("Thanks")
    q=repr(n).join(q.split(repr(d)))
else:
    p("Good. That was soooo easy.")
q='q=""'+'"'+q+'""'+'"'+chr(10)+'exec(q)'
p(q)
"""
exec(q)

অনলাইনে চেষ্টা করে দেখুন!

প্রশ্ন / উত্তর / প্রতিক্রিয়াগুলি একটি অ্যারেতে সংরক্ষণ করা হয়, যেখানে অ্যারেটি যদি তিনটি আইটেম (উদাঃ ['Does it eat ants',['a pangolin'],['a dog']]) সঞ্চয় করে তবে তা প্রশ্নের উত্তর পেয়ে উত্তর এবং উপর নির্ভর করে দ্বিতীয় বা তৃতীয় আইটেমের বিষয়বস্তু দিয়ে পুনরাবৃত্তি করে। যখন এটি কেবল একটি আইটেম সহ একটি অ্যারেতে পৌঁছে, এটি প্রশ্নটি জিজ্ঞাসা করে, এবং এর সম্পূর্ণ উত্স কোডাসের একটি স্ট্রিং রয়েছে তাই এটি নতুন শাখা যুক্ত করতে অ্যারেটিতে এক্সটেনশন সন্নিবেশ করানোর জন্য বিভক্ত-যোগ পদ্ধতিটি ব্যবহার করতে সক্ষম হয় ।

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

q="""
print("Some actual stuff")
q='q=""'+'"'+q+'""'+'"'+chr(10)+'exec()'
print(q)
"""
exec(q)

1

পাইথন 3 , 497 বাইট

t=["a pangolin"];c='''p=print;i=input;a=lambda q:i(q)[0]in"Yy"
def q(t):
  if len(t)<2:
    g=t[0]
    if a(f"Is it {g}?"):p("Good. That was soooo easy.")
    else:s=i("Oh. Well you win then -- What were you thinking of?");n=i(f"Please give me a question about {s}, so I can tell the difference between {s} and {g}.");t[0]=n;t+=[[g],[s]][::1-2*a(f"What is the answer for {s}?")];p("Thanks")
  else:q(t[2-a(t[0])])
p("Ok, please think of something");q(t);p(f"t={t};c=''{c!r}'';exec(c)")''';exec(c)

গাছের উপস্থাপনের জন্য হরমলেসের উত্তরের সাথে বেশ মিল। তালিকার গভীরে যাওয়ার সময় এটি কেবল একবারে প্রতিক্রিয়া না পাওয়া পর্যন্ত পুনরাবৃত্তভাবে পরবর্তী প্রশ্ন জিজ্ঞাসা করে।

অবরুদ্ধ সংস্করণ (বিনা বাধায়)

tree = ['a pangolin']

def ask(question):
  answer = input(question + '\n')
  if answer.lower() in ['yes', 'no']:
    return answer.lower() == 'yes'
  else:
    print('Please answer "yes" or "no".')
    return ask(question)
    
def query(tree):
  if len(tree) == 1:
    guess = tree.pop()
    if ask(f'Is it {guess}?'):
      print('Good. That was soooo easy.')
      tree.append(guess)
    else:
      thing = input('Oh. Well you win then -- What were you thinking of?\n')
      new_question = input(f'Please give me a question about {thing}, so I can tell the difference between {thing} and {guess}.\n')
      answer = ask(f'What is the answer for {thing}?')
      print('Thanks')
      tree.append(new_question)
      if answer:
        tree.append([thing])
        tree.append([guess])
      else:
        tree.append([guess])
        tree.append([thing])
  else:
    if ask(tree[0]):
      query(tree[1])
    else:
      query(tree[2])
      
while True:
  input('Ok, please think of something\n')
  query(tree)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.