ব্রেইনফাক হ্যালো ওয়ার্ল্ড আসলে কীভাবে কাজ করে?


118

কেউ আমার কাছে এটি পাঠিয়ে দাবি করেছেন যে এটি ব্রেনফাকের একটি হ্যালো ওয়ার্ল্ড (এবং আমি আশা করি ...)

++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

আমি বেসিকগুলি জানি যা এটি পয়েন্টার এবং বর্ধন এবং স্টাফ কমিয়ে দিয়ে কাজ করে ...

তবুও আমি এখনও জানতে চাই, এটি আসলে কীভাবে কাজ করে? এটি প্রথম স্থানে কীভাবে স্ক্রিনে কিছু মুদ্রণ করে? এটি পাঠ্যটি কীভাবে এনকোড করবে? আমি কিছুতেই বুঝতে পারি না ...


31
এই ভাষায় লিখিত কোনও অ্যাপ্লিকেশন বজায় রাখা বেশ কঠিন হতে হবে ..
e2-e4

17
@ রিং0: নাহ, এটি কেবল লেখার জন্য ভাষা।
LetMeSOThat4U

এটি ব্যবহারিক ব্যবহার কি?
যশ কুমার ভার্মা

10
@ যশ ভার্মার এটির দরকার নেই ..
উন্মাদ

49
@ যশবর্মা এটি ভাষার নামে স্পষ্টভাবে নির্দিষ্ট করা আছে।
মতিন উলহাক

উত্তর:


255

1. বেসিক

ব্রেইনফাক বুঝতে আপনার অবশ্যই 0প্রতিটি দ্বারা সূচিত কক্ষের অসীম অ্যারে কল্পনা করতে হবে ।

...[0][0][0][0][0]...

যখন ব্রেনফাক প্রোগ্রাম শুরু হয়, এটি যে কোনও ঘরে নির্দেশ করে।

...[0][0][*0*][0][0]...

আপনি যদি পয়েন্টারটি ডানদিকে নিয়ে যান তবে আপনি >সেল এক্স থেকে সেল এক্স + 1 এ পয়েন্টারটি সরাচ্ছেন

...[0][0][0][*0*][0]...

আপনি যদি সেল মান বাড়ান তবে +আপনি পাবেন:

...[0][0][0][*1*][0]...

যদি আপনি আবার সেল মান বাড়ান তবে আপনি +পাবেন:

...[0][0][0][*2*][0]...

আপনি যদি কক্ষের মূল্য হ্রাস করেন তবে -পাবেন:

...[0][0][0][*1*][0]...

আপনি যদি পয়েন্টার বামে সরান তবে আপনি <সেল এক্স থেকে সেল এক্স -1 এ পয়েন্টারটি সরাচ্ছেন

...[0][0][*0*][1][0]...

2. ইনপুট

চরিত্রটি পড়তে আপনি কমা ব্যবহার করেন ,। এটি কী করে: স্ট্যান্ডার্ড ইনপুট থেকে অক্ষরটি পড়ুন এবং এর দশমিক ASCII কোডটি প্রকৃত ঘরে লিখুন।

এএসসিআইআই টেবিলটি একবার দেখুন । উদাহরণস্বরূপ, এর দশমিক কোড !হল 33, যখন aরয়েছে 97

ঠিক আছে, আপনার বিএফ প্রোগ্রামের মেমরিটি দেখে মনে হচ্ছে:

...[0][0][*0*][0][0]...

ধরে নিই, স্ট্যান্ডার্ড ইনপুটটি হ'ল, aআপনি যদি কমা ,অপারেটর ব্যবহার করেন , বিএফ যা করে তা aডেসিম্যাল এএসসিআইআই কোডটি 97মেমোরিতে পড়ে:

...[0][0][*97*][0][0]...

আপনি সাধারণত সেভাবে ভাবতে চান তবে সত্যটি কিছুটা জটিল। সত্যটি হ'ল বিএফ একটি চরিত্র পড়েনি তবে একটি বাইট (যা বাইট যাই হোক না কেন)। আমি আপনাকে উদাহরণ দেখাতে দিন:

লিনাক্সে

$ printf ł

কপি করে প্রিন্ট:

ł

যা নির্দিষ্ট পোলিশ চরিত্র। এই অক্ষরটি ASCII এনকোডিং দ্বারা এনকোড করা হয়নি। এই ক্ষেত্রে এটি ইউটিএফ -8 এনকোডিং, তাই এটি কম্পিউটারের মেমোরিতে একাধিক বাইট গ্রহণ করত। আমরা একটি হেক্সাডেসিমাল ডাম্প তৈরি করে এটি প্রমাণ করতে পারি:

$ printf ł | hd

কোন প্রদর্শনী:

00000000  c5 82                                             |..|

জিরোস অফসেট হয়। 82প্রথম এবং c5দ্বিতীয় বাইট প্রতিনিধিত্ব করে ł(ক্রমে আমরা সেগুলি পড়ব)।|..|গ্রাফিকাল উপস্থাপনা যা এই ক্ষেত্রে সম্ভব নয়।

ঠিক আছে, আপনি যদি łআপনার বিএফ প্রোগ্রামটিতে ইনপুট হিসাবে পাস করেন যা একক বাইট পড়ে, প্রোগ্রাম মেমোরিটি দেখতে পাবেন:

...[0][0][*197*][0][0]...

কেন 197? ঠিক 197দশমিক c5হেক্সাডেসিমাল। পরিচিত মনে হচ্ছে? অবশ্যই. এটি প্রথম বাইটł !

3. আউটপুট

চরিত্রটি মুদ্রণের জন্য আপনি বিন্দুটি .যা ব্যবহার করে তা ব্যবহার করুন : ধরে নিই আমরা দশমিক ASCII কোডের মতো প্রকৃত ঘর মানটিকে মান্য করি, মানক আউটপুটের সাথে সম্পর্কিত অক্ষর মুদ্রণ করি।

ঠিক আছে, আপনার বিএফ প্রোগ্রামের মেমরিটি দেখে মনে হচ্ছে:

...[0][0][*97*][0][0]...

আপনি যদি এখনই ডট (।) অপারেটর ব্যবহার করেন, বিএফ যা করে তা মুদ্রণযোগ্য:

একটি

কারণ aএএসসিআইআই-এর দশমিক কোড97

সুতরাং উদাহরণস্বরূপ বিএফ প্রোগ্রামের জন্য (97 টি বিস্ফোরণে 2 বিন্দু):

++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++ ..

ঘরের মূল্য এটি 97 পর্যন্ত বাড়িয়ে তুলবে এবং এটি 2 বার মুদ্রণ করবে।

এএ

4. লুপস

বিএফ লুপে লুপ শুরু [এবং লুপ শেষ থাকে ]। আপনি যখন সি / সি ++ তে থাকতে পারেন তখন অবস্থাটি প্রকৃত সেল মান হিসাবে ভাবতে পারে।

নীচে দেখুন বিএফ প্রোগ্রাম:

++[]

++ প্রকৃত ঘর মান দ্বিগুণ বৃদ্ধি করে:

...[0][0][*2*][0][0]...

এবং []এর মতো while(2) {}, তাই এটি অসীম লুপ।

ধরা যাক আমরা এই লুপটি অসীম হতে চাই না। আমরা উদাহরণস্বরূপ করতে পারি:

++[-]

সুতরাং প্রতিবার একটি লুপ লুপ করে এটি প্রকৃত ঘরের মান হ্রাস করে। একবার প্রকৃত ঘর মান 0লুপ শেষ হয়ে গেলে :

...[0][0][*2*][0][0]...        loop starts
...[0][0][*1*][0][0]...        after first iteration
...[0][0][*0*][0][0]...        after second iteration (loop ends)

সীমাবদ্ধ লুপের আরও একটি উদাহরণ বিবেচনা করা যাক:

++[>]

এই উদাহরণটি দেখায়, আমাদের যে ঘরে লুপটি শুরু হয়েছিল সেটিতে লুপ শেষ করতে হবে না:

...[0][0][*2*][0][0]...        loop starts
...[0][0][2][*0*][0]...        after first iteration (loop ends)

তবে আমরা যেখানে শুরু করেছি সেখানেই শেষ করা ভাল অনুশীলন। কেন? কারণ লুপ যদি অন্য কক্ষটি শুরু করে তবে এটি সেল পয়েন্টারটি কোথায় হবে তা আমরা ধরে নিতে পারি না। সত্যি কথা বলতে কী, এই অনুশীলনটি ব্রেনফাককে ব্রেনফাক কম করে।


4
শীতল, এখন আমি এটি বুঝতে পেরেছি :)
স্পিডার

25
এই ভাষা আদর্শকে বোঝার চেষ্টা করা নবজাতকদের একটি সঠিক সমাধান ছিল। অভিনন্দন, এবং দুর্দান্ত পোস্ট।
কেসি

4
আমি দেখেছি সেরা ব্রেইনফাক পরিচয়। সত্যই আপনি BF কে আপনার পোস্টের মাধ্যমে কিছুটা পূর্বাবস্থায় ফেরান
বায়ানগ

3
আমি অনুমান করি যে আপনার যদি আপনার অতিরিক্ত সময়ের জন্য কোনও প্রকল্পের প্রয়োজন হয় তবে আপনি সর্বদা ব্রেইনফাকে ইউনিকোড সমর্থন যুক্ত করতে পারেন।
vlvaro González

3
আপনার পোস্টের পরে, BF আর! BF!
Thanos.a

52

উইকিপিডিয়ায় কোডটির একটি মন্তব্য সংস্করণ রয়েছে।

+++++ +++++             initialize counter (cell #0) to 10
[                       use loop to set the next four cells to 70/100/30/10
    > +++++ ++              add  7 to cell #1
    > +++++ +++++           add 10 to cell #2 
    > +++                   add  3 to cell #3
    > +                     add  1 to cell #4
    <<<< -                  decrement counter (cell #0)
]                   
> ++ .                  print 'H'
> + .                   print 'e'
+++++ ++ .              print 'l'
.                       print 'l'
+++ .                   print 'o'
> ++ .                  print ' '
<< +++++ +++++ +++++ .  print 'W'
> .                     print 'o'
+++ .                   print 'r'
----- - .               print 'l'
----- --- .             print 'd'
> + .                   print '!'
> .                     print '\n'

আপনার প্রশ্নের উত্তর দিতে, ,এবং. অক্ষরগুলি I / O এর জন্য ব্যবহৃত হয়। পাঠ্যটি ASCII।

উইকিপিডিয়া নিবন্ধ, পাশাপাশি আরো কিছু গভীরতা উপর যায়।

প্রথম লাইনটি a[0] = 100 থেকে দশগুণ বৃদ্ধি করে সূচনা করে 2 লাইন থেকে লুপ কার্যকরভাবে অ্যারের জন্য প্রাথমিক মানগুলি সেট করে: a[1] = 70(72 এর কাছাকাছি, 'এইচ' অক্ষরের জন্য ASCII কোড), a[2] = 100(101 বা 'ই' এর কাছাকাছি ) ), a[3] = 30(32 এর কাছাকাছি, স্থানের কোড) এবং a[4] = 10(নিউলাইন) লুপ 7, 10, 3, এবং আরও 1 টি কোষের যোগ করে কাজ করে a[1], a[2], a[3]এবং a[4]মোট প্রতিটি কক্ষে 10 সংযোজন (দান - যথাক্রমে লুপের মাধ্যমে প্রতিটি সময় a[1]=70ইত্যাদি)। লুপ শেষ হওয়ার পরে a[0]শূন্য হয়। >++.তারপরে পয়েন্টারটি সরিয়ে দেয় a[1], যা 70 টি ধারণ করে, এতে দুটি যুক্ত করে (72 উত্পাদন করে, যা একটি মূলধন এইচ এর ASCII অক্ষর কোড) এবং এটি আউটপুট করে।

পরের রেখাটি অ্যারে পয়েন্টারটিতে স্থানান্তরিত করে a[2]এবং এটিতে একটি যোগ করে 101, একটি নিম্ন-কেস 'ই' উত্পাদন করে যা পরে আউটপুট হয়।

'L' এর পরে 'e' এর পরে সপ্তম অক্ষর হিসাবে দেখা যায়, আউটপুট 'll' এ আরও সাতটি যুক্ত হয় ( +++++++) a[2]এবং ফলাফলটি দ্বিগুণ হয়।

'ও' হ'ল 'এল' এর পরে তৃতীয় অক্ষর, সুতরাং a[2]আরও তিনবার বৃদ্ধি করা হয় এবং ফলাফল আউটপুট করে।

প্রোগ্রামটির বাকি অংশগুলি একইভাবে চলছে। স্থান এবং মূলধনী অক্ষরের জন্য, বিভিন্ন অ্যারে ঘর নির্বাচন করা হয় এবং প্রয়োজনীয় হিসাবে বাড়ানো বা হ্রাস করা হয়।


তবে কেন এটি প্রিন্ট করে? আর কীভাবে? মন্তব্যগুলি আমাকে লাইনের উদ্দেশ্যটি ব্যাখ্যা করছে, এখন এটি কী করে।
স্পিডার

8
এটি মুদ্রণ করে কারণ সংকলকটি এটি জানে ,এবং .I / O- র জন্য ব্যবহৃত হয়, অনেকটা সি প্রিন্টের মতো ব্যবহার করে putchar। এটি একটি বাস্তবায়ন বিশদ যা সংকলক দ্বারা পরিচালিত।
কেন

1
এবং এটি কারণ "হ্যালো ওয়ার্ল্ড"
-তে

আমি আরও গভীরতার ব্যাখ্যা দিয়ে আশা করেছি ... তবে: /
স্পিডার

1
@ স্পিডার - আমি উত্তরটিতে উইকিপিডিয়া থেকে কোডটির গভীরতর ব্যাখ্যা যুক্ত করেছি। আপনি আরও তথ্যের জন্য লিঙ্কিত নিবন্ধ দেখতে পারেন।
কেন

9

কীভাবে এটি মুদ্রণ করতে হবে তার প্রশ্নের উত্তর দিতে, আমি যেখানে মুদ্রণ ঘটে সেখানে ডানদিকে ASCII মানগুলির গণনা যুক্ত করেছি:

> just means move to the next cell
< just means move to the previous cell
+ and - are used for increment and decrement respectively. The value of the cell is updated when the increment/decrement happens

+++++ +++++             initialize counter (cell #0) to 10

[                       use loop to set the next four cells to 70/100/30/10

> +++++ ++              add  7 to cell #1

> +++++ +++++           add 10 to cell #2 

> +++                   add  3 to cell #3

> +                     add  1 to cell #4

<<<< -                  decrement counter (cell #0)

]            

> ++ .                  print 'H' (ascii: 70+2 = 72) //70 is value in current cell. The two +s increment the value of the current cell by 2

> + .                   print 'e' (ascii: 100+1 = 101)

+++++ ++ .              print 'l' (ascii: 101+7 = 108)

.                       print 'l' dot prints same thing again

+++ .                   print 'o' (ascii: 108+3 = 111)

> ++ .                  print ' ' (ascii: 30+2 = 32)

<< +++++ +++++ +++++ .  print 'W' (ascii: 72+15 = 87)

> .                     print 'o' (ascii: 111)

+++ .                   print 'r' (ascii: 111+3 = 114)

----- - .               print 'l' (ascii: 114-6 = 108)

----- --- .             print 'd' (ascii: 108-8 = 100)

> + .                   print '!' (ascii: 32+1 = 33)

> .                     print '\n'(ascii: 10)

9

ব্রেনফাক এর নাম হিসাবে একই। > [ . ] , - +এটিতে কেবলমাত্র 8 টি অক্ষর ব্যবহার করা হয়েছে যা এটি শিখতে দ্রুততম প্রোগ্রামিংয়ের ভাষা তৈরি করে তবে বাস্তবায়ন এবং বোঝার পক্ষে সবচেয়ে কঠিন … .আর আপনাকে চূড়ান্তভাবে চ * দিয়ে আপনার মস্তিস্কের চেক দিয়ে শেষ করে।

এটি অ্যারেতে মানগুলি সঞ্চয় করে: [72] [101] [108] [১১১]

আসুন, প্রাথমিকভাবে অ্যারের 1 কক্ষে নির্দেশকারী পয়েন্টার:

  1. > পয়েন্টারটি 1 দ্বারা ডানদিকে সরান

  2. < 1 দ্বারা বাম দিকে পয়েন্টার সরান

  3. + ঘরের মান 1 দ্বারা বৃদ্ধি করুন

  4. - উপাদানটির মান 1 দ্বারা বৃদ্ধি করুন

  5. . বর্তমান কক্ষের মুদ্রণ মান।

  6. , বর্তমান কক্ষে ইনপুট নিন।

  7. [ ] লুপ, +++ [-] 3 গুন বিসিজেডের কাউন্টার এর আগে এটির 3 ′ + 'থাকে এবং - হ্রাস হ্রাস করে 1 মান দ্বারা পরিবর্তনশীল গণনা করে।

কোষগুলিতে সঞ্চিত মানগুলি আসকি মানসমূহ:

সুতরাং উপরে অ্যারে উল্লেখ: [72] [101] [108] [108] [111] যদি আপনি ascii মান মেলে আপনি দেখতে পাবেন যে এটি হ্যালো লিটার্ন

অভিনন্দন! আপনি বিএফ এর বাক্য গঠনটি শিখেছেন

——- আরও কিছু ———

আসুন আমাদের প্রথম প্রোগ্রাম অর্থাৎ হ্যালো ওয়ার্ল্ড তৈরি করুন , এরপরে আপনি এই ভাষায় আপনার নাম লিখতে সক্ষম হন।

+++++ +++++[> +++++ ++ >+++++ +++++ >+++ >+ <<<-]>++.>+.+++++ ++..+++.++.+++++ +++++ +++++.>.+++.----- -.----- ---.>+.>.

টুকরো টুকরো করা:

+++++ +++++[> +++++ ++ 
                  >+++++ +++++ 
                  >+++ 
                  >+ 
                  <<<-]

4 টি কক্ষের অ্যারে তৈরি করে (সংখ্যার সংখ্যা) এবং 10 টির মতো একটি কাউন্টার সেট করে: ps-puedo কোড—-

array =[7,10,3,1]
i=10
while i>0:
 element +=element
 i-=1

কারণ পাল্টা মান 0 কক্ষে সংরক্ষিত থাকে এবং> সেল 1 এ চলে যায় তার মানটি +7 দ্বারা আপডেট হয়> সেল 2 2 ইনক্রিমেন্ট 10 এর আগের মানে চলে যায় ... ইত্যাদি।

<<< 0 ঘরে ফিরে আসে এবং এর মান 1 দ্বারা হ্রাস পায়

লুপ সমাপ্তির পরে আমাদের অ্যারে রয়েছে: [70,100,30,10]

>++. 

1 ম উপাদানতে স্থানান্তরিত হয় এবং 2 (দুটি '+') দ্বারা এর মান বাড়িয়ে দেয় এবং তারপরে সেই আসকি মান দিয়ে অক্ষর মুদ্রণ করে ('।') করে। উদাহরণস্বরূপ অজগর উদাহরণস্বরূপ: chr (70 + 2) # টি 'এইচ' প্রিন্ট করে

>+.

দ্বিতীয় কক্ষবৃদ্ধি 1 এ তার মান 100 + 1 এ চলে যায় এবং ('।') এর মান যেমন chr (101) chr (101) # মুদ্রণের 'e' এখন নেই> বা <পরের অংশে থাকে তাই এটি বর্তমান মান নেয় এটিতে সর্বশেষতম উপাদান এবং বৃদ্ধি

+++++ ++..

অতএব সর্বশেষ উপাদান = ১০১, ১০১ + twice এবং এটি দু'বার মুদ্রণ করে (যেমন দুটি '..') ক্রিয়াকলাপ (১০০) # মুদ্রণ দুটিবার ব্যবহার করা যেতে পারে

for i in array:
    for j in range(i.count(‘.’)):
           print_value

——— এটি কোথায় ব্যবহৃত হয়? ---

এটি প্রোগ্রামারদের চ্যালেঞ্জ করার জন্য তৈরি একটি কৌতুকপূর্ণ ভাষা এবং ব্যবহারিকভাবে কোথাও ব্যবহার হয় না।


4

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

উদাহরণ:

মনে করুন আপনার কাছে -> char *ptr = [0] [0] [0] [97] [0]... যদি এটি মস্তিষ্কের বিবৃতি হয়: >>>.আপনার পয়েন্টারটি 3 স্পেস ডানদিকে অবতরণ করা উচিত: [97]সুতরাং, এখন *ptr = 97আপনার অনুবাদক একটি মুখোমুখি হওয়ার পরে ., এটি কল করা উচিত

write(1, ptr, 1)

অথবা বর্তমানে পয়েন্ট করা বাইট মুদ্রণের জন্য যে কোনও সমমানের মুদ্রণ বিবৃতি, যার মান 97 রয়েছে এবং চিঠিটি aপরে প্রিন্ট করা হবে std_output


1

আমার মনে হয় আপনি যা জিজ্ঞাসা করছেন তা হ'ল ব্রেনফাক কীভাবে সমস্ত কোড সহ কী করবেন তা জানে does পাইটনের মতো একটি উচ্চ স্তরের ভাষায় একটি পার্সার লেখা আছে যা বিন্দুটির অর্থ কী, বা কোডে একটি সংযোজন চিহ্নের অর্থ কী তা বোঝাতে।

সুতরাং পার্সার আপনার কোড লাইনটি লাইন পড়বে, এবং বলবে ঠিক আছে একটি> চিহ্ন আছে তাই আমাকে মেমরির অবস্থানটি এগিয়ে নিতে হবে, কোডটি সহজভাবে, যদি (সেই স্মৃতি অবস্থানের বিষয়বস্তু) ==>, স্মৃতিচিহ্ন = + স্মৃতিচিহ্ন যা হয় উচ্চ স্তরের ভাষায় লিখিত, একইভাবে যদি (মেমরি অবস্থানের বিষয়বস্তু) == "" ", তবে মুদ্রণ করুন (মেমরি অবস্থানের বিষয়বস্তু)।

আশা করি এটি পরিষ্কার হয়ে যাবে। TC

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.