বৈধ ব্রেইনফ ** কে প্রোগ্রাম গণনা করুন


41

Golunar / একক সকল বৈধ এনকোড করার একটি উপায় Brainfuck প্রোগ্রাম, কিন্তু এটি একটি শুমার নয় যেহেতু সবচেয়ে স্বাভাবিক সংখ্যার একটি বৈধ প্রোগ্রাম মিলা না।

এই চ্যালেঞ্জের উদ্দেশ্যে, দ্বিগুণ অসীম টেপ এবং কোনও মন্তব্য নেই, অর্থাত্ একটি ব্রেনফাক প্রোগ্রাম বৈধ হয় যদি কেবলমাত্র এটির মধ্যে কেবলমাত্র অক্ষর থাকে <>+-.,[]এবং সমস্ত বাম এবং ডান বন্ধনী মেলে।

উদাহরণস্বরূপ, খালি প্রোগ্রাম, ,[+][-]., [>+<[--].]এবং +[+[+][+[+]+]+]+.বৈধ Brainfuck প্রোগ্রাম, যখন হয় ][, এবং a[]হয় না।

কার্য

এমন একটি প্রোগ্রাম বা ফাংশন লিখুন যা একটি বৈধ ব্রেইনফাক প্রোগ্রামকে ইনপুট হিসাবে গ্রহণ করে এবং নিম্নলিখিত বাধা দিয়ে একটি প্রাকৃতিক সংখ্যা ( 1 , 2 , 3 ,…) প্রদান করে:

  • উত্পন্ন আউটপুট অবশ্যই সমস্ত বৈধ ব্রেইনফাক প্রোগ্রামের জন্য আলাদা হতে হবে।

  • প্রতিটি প্রাকৃতিক সংখ্যা এন এর জন্য অবশ্যই একটি বৈধ ব্রেইনফাক প্রোগ্রাম থাকতে হবে যা ইনপুট হিসাবে সরবরাহ করার পরে আউটপুট এন জেনারেট করে ।

অতিরিক্ত বিধি

  • 100 বা তারও কম বাইটের ব্রেনফাক প্রোগ্রাম দেওয়া, আপনার প্রোগ্রাম বা ফাংশনটি অবশ্যই এক মিনিটের মধ্যে শেষ করতে হবে।

    এর অর্থ হ'ল আপনি যতক্ষণ না ইনপুটটির সাথে মেলে ততক্ষণ পর্যন্ত সমস্ত বৈধ ব্রেইনফাক প্রোগ্রামের মাধ্যমে পুনরাবৃত্তি করতে পারবেন না।

  • স্ট্যান্ডার্ড বিধি প্রযোজ্য।


3
আমি এটিকে কেবল অষ্টাল হিসাবে এনকোড করার কথা ভাবছিলাম কিন্তু ম্যাচিং বন্ধনীগুলি এই জটিল করে তুলছে।
ড্যানকমেস

খালি প্রোগ্রামটি কি একটি বৈধ ব্রেইনফাক প্রোগ্রাম? এটি একটি প্রাকৃতিক পূর্ণসংখ্যার সাথেও ম্যাপ করা উচিত?
orlp

9
কেন নিকট ভোট? এটি একটি আকর্ষণীয় প্রশ্ন এবং সমস্যাটি একটি দুর্দান্ত গল্ফের আকার এবং বিভিন্নতা ঘটায়।
ট্রাইকোপল্যাক্স

1
@ অরলপ হ্যাঁ, খালি প্রোগ্রামটি উপরের সংজ্ঞাটি পূরণ করে
ডেনিস

3
এখনও ব্রেইনফাক-এ লেখা উত্তর দেখার অপেক্ষায় ...
মাইকেল হ্যাম্পটন

উত্তর:


16

পাইথন 3, 443 158 155 154 134 131 128 124 117 116 115 বাইট

c=d=C=D=0
for e in input():v='[<>,.-+]'.find(e);d=d*8+v;c+=c<0<6<v;c-=d>1>v;C,D=(c,C+1,d,D)[v>6::2]
print(-~D*8**C)

এসপি 3000 এবং মিচ শোয়ার্জকে: কয়েকটি বাইট ধন্যবাদ: ডি

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

এটি একটি বৈধ বিএফ প্রোগ্রামগুলিকে সমস্ত সম্ভাব্য, বৈধ বা অবৈধ, বিএফ প্রোগ্রামগুলিতে মানচিত্র দেয় যা [একের সাথে এক অনুপাতের সাথে শুরু হয় না । এর পরে, নতুন প্রোগ্রামটি কেবল অক্টালে রূপান্তরিত হয়।

ম্যাপিং সূত্রটি এখানে:

  1. একটি বিএফ প্রোগ্রাম পৃথকভাবে 3 ভাগে ভাগ করুন। প্রথম অংশটি কেবলমাত্র [অক্ষর নিয়ে গঠিত বৃহত্তম উপসর্গ । তৃতীয় অংশটি কেবলমাত্র ]অক্ষর নিয়ে গঠিত বৃহত্তম পোস্টফিক্স । দ্বিতীয় অংশটি মাঝখানে।
  2. প্রথম অংশটি নিষ্পত্তি করুন। এগুলি পরে সংশোধন করা যেতে পারে।
  3. ]তৃতীয় অংশের সমস্ত বন্ধনী সরিয়ে ফেলুন [যা দ্বিতীয় অংশে বন্ধনীগুলির সাথে মেলে । এগুলি পরে পুনরায় সংশোধন করা যেতে পারে।
  4. দ্বিতীয় এবং তৃতীয় অংশ একসাথে সংযুক্ত করুন।

আপনি যদি এই ব্যাখ্যাটি বুঝতে না পারেন তবে আপনি এখানে শুরু হয়ে চ্যাটটিতে একটি বর্ধিত ব্যাখ্যা পেতে পারেন ।

রেফারেন্সের জন্য, এখানে প্রথম 20 টি প্রোগ্রাম রয়েছে:

1 : 
2 : <
3 : >
4 : ,
5 : .
6 : -
7 : +
8 : []
9 : <[]
10 : <<
11 : <>
12 : <,
13 : <.
14 : <-
15 : <+
16 : [<]
17 : >[]
18 : ><
19 : >>
20 : >,

এখানে প্রথম 1000 টি প্রোগ্রাম রয়েছে: http://pastebin.com/qykBWhmD
আমি তাদের তৈরি করতে যে প্রোগ্রামটি ব্যবহার করেছি তা এখানে: http://ideone.com/e8oTVl

এখানে Hello, World!:

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

মাইনর কুইবল: আপনি 0 তে কোনও প্রোগ্রাম ম্যাপ করতে পারবেন না ।
ডেনিস

@ ডেনিস খালি প্রোগ্রামটি কি কোনও প্রোগ্রাম হিসাবে গণ্য হচ্ছে?
বিটা ক্ষয়


@ ডেনিস আমি যখন এটি গল্ফ করব তখন এটি ঠিক করব।
TheNumberOne

3
এটি বুদ্ধিমান
গর্বিত হাসেলেলার

13

পাইথন 2, 157 বাইট

def f(s,o=0,d=0,D={}):T=s,o,d;x=D[T]=D[T]if T in D else~o and 0**o+sum(f(s[1:],cmp(c,"[")%-3-~o,d or cmp(c,s[0]))for c in"+,-.<>[]")if s else~d<0==o;return+x

এখনও বেশ গল্ফযোগ্য দেখাচ্ছে তবে আমি আপাতত এটি পোস্ট করছি। এটি কিছুটা ক্যাচিংয়ের সাথে পুনরাবৃত্তি ব্যবহার করে। বিরক্তিকরভাবে, D.getক্যাশিংয়ের জন্য শর্ট সার্কিট নেই, সুতরাং আমি 9 বাইট সেভাবে সংরক্ষণ করতে পারি না ...

ম্যাপিংটি প্রথমে দৈর্ঘ্যটিকে অগ্রাধিকার দেয়, তারপরে অর্ডার দিয়ে লিক্সোগ্রাফিকাল ক্রম "][><.-,+"(নীচে আউটপুট উদাহরণগুলি দেখুন)। মূল ধারণাটি উপসর্গগুলি তুলনা করা।

ভেরিয়েবল বর্তমান উপসর্গের জন্য বন্ধনীগুলির oসংখ্যা [এখনও ট্র্যাক করে রাখে , যখন ভেরিয়েবলটি dতিনটি মানের একটি নির্দেশ করে:

  • d = 1: বর্তমানের উপসর্গটি আগের তুলনায় ডিক্সিকোগ্রাফিকভাবে s। এই উপসর্গ এবং দৈর্ঘ্য সহ সমস্ত প্রোগ্রাম যুক্ত করুন <= s,
  • d = -1: বর্তমান উপসর্গ lexicographically চেয়ে পরে s। এই উপসর্গ এবং দৈর্ঘ্য সহ সমস্ত প্রোগ্রাম যুক্ত করুন < s
  • d = 0: বর্তমানের উপসর্গটি একটি উপসর্গ s, সুতরাং আমরা dপরে 1 বা -1 এ পরিবর্তন করতে পারি ।

উদাহরণস্বরূপ, যদি আমাদের থাকে s = "[-]"এবং আমাদের বর্তমান উপসর্গ হয় p = "+", যেহেতু pপরে sঅভিধানিকের তুলনায় আমরা কেবলমাত্র সেই প্রোগ্রামগুলি যুক্ত করতে জানি যাগুলির সাথে আরও pকম সংক্ষিপ্ত হয় s

আরও বিশদ উদাহরণ দেওয়ার জন্য, ধরুন আমাদের একটি ইনপুট প্রোগ্রাম রয়েছে s = "-[]"। প্রথম পুনরাবৃত্তির বিস্তৃতি এটি করে:

  (o == 0)               # Adds a program shorter than s if it's valid
                         # For the first expansion, this is 1 for the empty program
+ f(s[1:], o=-1, d=1)    # ']', o goes down by one due to closing bracket
+ f(s[1:], o=1, d=1)     # '[', o goes up by one due to opening bracket
+ f(s[1:], o=0, d=1)     # '>'
+ f(s[1:], o=0, d=1)     # '<'
+ f(s[1:], o=0, d=1)     # '.', d is set to 1 for this and the previous branches
                         # since they are lexicographically earlier than s's first char
+ f(s[1:], o=0, d=0)     # '-', d is still 0 since this is equal to s's first char
+ f(s[1:], o=0, d=-1)    # ',', d is set to -1 for this and the later branches
                         # since they are lexicographically later than s's first char
+ f(s[1:], o=0, d=-1)    # '+'

নোট কিভাবে আমরা আসলে পুনরাবৃত্তির মধ্যে উপসর্গ ব্যবহার করবেন না - সব আমরা তাদের যত্ন সম্পর্কে ভেরিয়েবল মাধ্যমে বন্দী করা হয় d, oমাপে ইনপুট প্রোগ্রাম এবং s। আপনি উপরে অনেকগুলি পুনরাবৃত্তি লক্ষ্য করবেন - এখানেই ক্যাশে চলে আসে, যা আমাদের সময়সীমার মধ্যে 100-চর প্রোগ্রামগুলি প্রসেস করার অনুমতি দেয়।

কখন sখালি থাকে, আমরা তাকান (d>=0 and o==0), যা 1 (এই প্রোগ্রামটি গণনা করুন কারণ এটি অভিধানের দিক থেকে প্রথম / সমান এবং প্রোগ্রামটি বৈধ) বা 0 (এই প্রোগ্রামটিকে গণনা করবেন না) তা স্থির করে।

সঙ্গে কোন situtation o < 0অবিলম্বে আয় 0, যেহেতু এই উপসর্গ সঙ্গে কোনো প্রোগ্রাম আরো আছে ]চেয়ে গুলি [, এবং এইভাবে অবৈধ।


প্রথম 20 ফলাফলগুলি হ'ল:

 1
> 2
< 3
. 4
- 5
, 6
+ 7
[] 8
>> 9
>< 10
>. 11
>- 12
>, 13
>+ 14
<> 15
<< 16
<. 17
<- 18
<, 19
<+ 20

@ TheNumberOne এর উত্তর হিসাবে একই হ্যালো ওয়ার্ল্ড উদাহরণ ব্যবহার করে:

>>> f("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.")
3465145076881283052460228065290888888678172704871007535700516169748342312215139431629577335423L

4

পাইথন 2, 505 (গল্ফড নয়)

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

F={0:1}

def f(n):
    if n not in F:
        F[n]=6*f(n-1) + sum(f(i)*f(n-2-i) for i in range(n-1))

    return F[n]

def h(x):
    if x=='': return 0

    if len(x)==1: return '+-<>,.'.find(x)

    if x[0]!='[':
        return h(x[0]) * f(len(x)-1) + h(x[1:])

    d=i=1
    while d:
        if x[i]==']': d-=1
        elif x[i]=='[': d+=1
        i+=1

    a=i-2
    b=len(x)-i

    return 6*f(a+b+1) + sum(f(i)*f(a+b-i) for i in range(a)) + h(x[1:i-1]) * f(b) + h(x[i:])

def g(x):
    return sum(f(i) for i in range(len(x))) + h(x) + 1

print g(raw_input())

ফাংশনটি f(n)দৈর্ঘ্যের বৈধ ব্রেনফাক প্রোগ্রামগুলির সংখ্যা গণনা করে nh(x)দৈর্ঘ্য মানচিত্র প্রোগ্রাম nথেকে [0..f(n)-1], এবং g(x)প্রশ্নে bijective র্যাংকিং ফাংশন।

মূল ধারণাটি হ'ল একটি খালি নয় এমন প্রোগ্রামটি হয় [6 টির মধ্যে []নয় বা একটির সাথে শুরু করতে পারে । পূর্ববর্তী ক্ষেত্রে, আমরা মিলের সম্ভাব্য অবস্থানগুলি নিয়ে পুনরাবৃত্তি করতে পারি ]এবং বদ্ধ অংশে এবং লেজের উপর পুনরাবৃত্তি করতে পারি (যেখানে লেজটি নীচের অংশের নীচের অংশটিকে বোঝায় ])। পরবর্তী ক্ষেত্রে, আমরা লেজের উপর পুনরাবৃত্তি করতে পারি (যেখানে লেজ মানে প্রথম অক্ষরটি ড্রপ হয়)। এই যুক্তি গণনা এবং গণনা র‌্যাঙ্কের জন্য উভয়ই ব্যবহৃত হতে পারে।

সংক্ষিপ্ত প্রোগ্রামগুলিতে সর্বদা দীর্ঘ প্রোগ্রামগুলির চেয়ে কম র‌্যাঙ্ক থাকবে এবং বন্ধনী বিন্যাস একটি গৌণ নির্ধারক উপাদান determin অ- []অক্ষরগুলি "+ - <>," অনুসারে বাছাই করা হয় " (যা নির্বিচারে)

উদাহরণস্বরূপ n=4আমাদের এই কেসগুলি রয়েছে:

zxxx
[]xx
[x]x
[xx]

যেখানে zঅক্ষরবিহীন []এবং xকোনও অক্ষরের জন্য দাঁড়িয়েছে, সেই বিধিনিষেধের অধীনে ]যেটি প্রাথমিকটির সাথে মিলে যায় [। প্রোগ্রামগুলি সেই ক্রম অনুসারে র‌্যাঙ্ক করা হয়, এবং বিবর্তনীয় xক্ষেত্রে ডান বিভাগের চেয়ে বাম অংশটিকে অগ্রাধিকার দেওয়া সহ ধারাগুলিতে পুনরাবৃত্তভাবে হয় । র‌্যাঙ্ক গণনাটি মিশ্র-রেডিক্স সংখ্যার সিস্টেমগুলির মতো এবং fবর্তমান "রেডিক্স" গণনার জন্য গুরুত্বপূর্ণ।


4

এই উত্তরটি TheNumberOne , গণনা বৈধ Brainf ** কে প্রোগ্রামগুলির উত্তরের একটি আনুষ্ঠানিক প্রমাণ , যেখানে গণনাটি সঠিক কেন তা সূক্ষ্ম বিষয়গুলি বুঝতে কিছুটা কঠিন হতে পারে। এটি কেন অবৈধ প্রোগ্রাম নয় যে কোনও সংখ্যক মানচিত্রে কোনও বৈধ প্রোগ্রামের আওতাভুক্ত নয় তা বোঝার বিষয়টি অনর্থক।

এই পুরো উত্তর জুড়ে মূলধনগুলি প্রোগ্রামগুলি বোঝাতে ব্যবহৃত হয় এবং ছোট হাতের অক্ষরগুলি ফাংশন এবং পূর্ণসংখ্যার জন্য ব্যবহৃত হয়। ~ হ'ল সংক্ষিপ্ত অপারেটর।

প্রস্তাব 1:

ফাংশন চ এর উত্তর বর্ণিত প্রোগ্রাম হতে দিন। তারপরে প্রতিটি প্রোগ্রাম ইউ এর জন্য একটি বৈধ প্রোগ্রাম ভি উপস্থিত থাকে যেমন f (U) = f (V)

সংজ্ঞা 1:

[প্রোগ্রামটি এক্স-তে প্রদর্শিত সংখ্যাটি জি (এক্স) হতে দিন এবং এইচ (এক্স) এর উপস্থিতির সংখ্যা হতে দিন ]

সংজ্ঞা 2:

এই ফাংশন হতে পি (এক্স) সংজ্ঞায়িত করুন:

P(x) = "" (the empty program) when x <= 0
P(x) = "]" when x = 1
P(x) = "]]" when x = 2
etcetera

সংজ্ঞা 3:

এক্স প্রোগ্রাম দেওয়া হয়েছে, এক্স 1 কে এটি [অক্ষরের বৃহত্তম উপসর্গ , X2 এর কেন্দ্র এবং X3 এর ]অক্ষরের সবচেয়ে বড় প্রত্যয় হিসাবে চিহ্নিত করুন।

প্রস্তাব 1 এর প্রমাণ:

যদি g (U) = h (U) হয় তবে ইউ একটি বৈধ প্রোগ্রাম এবং আমরা ভি = ইউ নিতে পারি। (তুচ্ছ ঘটনা)

যদি g (U) <h (U) হয় তবে আমরা n = h (U) - g (U) [চিহ্নগুলি প্রেরণ করে ভি তৈরি করতে পারি । স্পষ্টত f (V) = f (U) [উপসর্গের সমস্ত চিহ্ন সরিয়ে ফেলা হয়েছে।

এখন g (U)> h (U) বিবেচনা করুন। টি = ইউ 2 ~ ইউ 3 সংজ্ঞায়িত করুন। যদি g (টি) <= h (টি) হয়, তবে আমরা n = g (U) - h (U) [চিহ্নগুলি সরিয়ে ভি তৈরি করতে পারি ।

সুতরাং আমরা ধরে নিতে পারি যে এইচ (টি) <g (টি)। ভি = টি ~ পি (জি (টি) - এইচ (টি)) গঠন করুন।

এগিয়ে যাওয়ার জন্য আমাদের তিনটি ছোট তথ্য দরকার:

দাবি 1: g (U2) = g (টি)

U3 [এর সংজ্ঞা অনুসারে কোনও চিহ্ন নেই । টি = ইউ 2 ~ ইউ 3 হিসাবে, এর [চিহ্নগুলি সমস্ত প্রথম অংশে রয়েছে।

দাবি 2: এইচ (ইউ 3) <জি (টি)

এটি এইচ (টি) <g (টি) এবং এইচ (ইউ 3) <জ (ইউ 3 ~ ইউ 2) = এইচ (টি) উল্লেখ করে চলেছে।

দাবি 3: এইচ (ভি 3) = জি (ইউ 2) - এইচ (ইউ 2)

h(V3) = h(U3) + g(T) - h(T)                           using the construction of V
h(V3) = h(U3) + g(U2) + g(U3) - h(U2) - h(U3)         apply the definition of T
h(V3) = g(U2) - h(U2) *one term cancels, g(U3)        is always zero, as U3 contains only `]` symbols*

এখন আমরা সেই ফ (ভি) = চ (ইউ) দেখি।

f(U) = U2 ~ P(h(U3) - g(U2)) = U2                     claim 2, definition of P

f(V) = U2 ~ P(h(V3) - g(V2))
     = U2 ~ P(h(V3) - g(U2))
     = U2 ~ P(g(U2) - h(U2) - g(U2))                  claim 3
     = U2 ~ P(-h(U2))
     = U2                                             definition P

এটি প্রমাণ সম্পূর্ণ করে। Qed

এর পাশাপাশি স্বতন্ত্রতা করা যাক।

প্রস্তাব 2:

ইউ, ভি দুইটি ভিন্ন, বৈধ প্রোগ্রাম হতে দিন। তারপরে চ (ইউ)! = চ (ভ)

এটি পূর্ববর্তী প্রস্তাবের তুলনায় মোটামুটি সোজা।

ধরা যাক ইউ 2 = ভি 2 V তবে তারপরে ইউ এবং ভি পৃথক হতে পারে একমাত্র উপায় যথাক্রমে ইউ 1 এবং ইউ 3 এর সাথে এন [এবং ]চিহ্নগুলি যুক্ত বা মুছে ফেলা । তবুও এটি চ এর আউটপুট পরিবর্তন করে, যেহেতু চ ]প্রত্যয়টির সাথে তুলনাহীন প্রতীকগুলির সংখ্যা গণনা করবে ।

এভাবে ইউ 2! = ভি 2

স্পষ্টতই, এটি একটি দ্বন্দ্ব বাড়ে। যেহেতু ইউ 2 এবং ভি 2 আক্ষরিক অর্থে চ (ইউ) এবং এফ (ভি) এর আউটপুটে অন্তর্ভুক্ত রয়েছে তাই 'প্রান্ত' ব্যতীত পৃথক হতে পারে না, যেখানে ইউ 2 সংঘটিত হয় ইউ 3 দিয়ে। তবে ইউ 2 এবং ভি 2 এর প্রথম এবং শেষ চিহ্নগুলি সংজ্ঞা [বা ]সংজ্ঞা অনুসারে হতে পারে না , যখন সেগুলি যথাক্রমে ইউ 1, ইউ 3, ভি 1, ভি 3 এবং যথাক্রমে আবার অনুমোদিত symb এইভাবে আমরা ইউ 2 = ভি 2 পাই। Qed

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