কয়েন টসস হিসাবে অর্ধেকের বেশি মাথা পাওয়ার সম্ভাবনা গণনা করুন।
পুলিশ এন্ট্রি (কনর ও ব্রায়ান পোস্ট করেছেন): /codegolf//a/100521/8927
আসল প্রশ্ন: কয়েন টসসের চেয়ে অর্ধেকের বেশি মাথা পাওয়ার সম্ভাবনা গণনা করুন।
পোস্ট করা সমাধানটিতে কয়েকটি দ্বিধাবিভক্ত কৌশল প্রয়োগ করা হয়েছিল, তারপরে একই অবলম্বন কৌশলটির একাধিক স্তর রয়েছে। প্রথম কয়েকটি কৌতুক অতিক্রান্ত হয়ে গেলে, আসল ফাংশনটি বের করার জন্য এটি একটি সাধারণ (ক্লান্তিকর!) কাজ হয়ে উঠেছে:
nCr(a,b) = a! / ((a-b)! * b!)
result = nCr(x, x/2) / 2^x
আমি কী দেখছিলাম তা উপলব্ধি করার জন্য কিছুটা সময় নিয়েছিলাম (কিছুক্ষণের জন্য আমি এন্ট্রপির সাথে কিছু করার জন্য সন্দেহ করেছিলাম) তবে এটি একবারে দ্বিগুণ হয়ে গেলে আমি "কয়েন টসের সম্ভাবনা" অনুসন্ধান করে খুব সহজেই প্রশ্নটি সন্ধান করতে সক্ষম হয়েছি।
যেহেতু কনর ও'ব্রায়েন তার কোডের গভীরতর ব্যাখ্যাকে চ্যালেঞ্জ জানিয়েছে, তাই এখানে আরও আকর্ষণীয় বিটগুলির একটি রুনডাউন রয়েছে:
এটি কিছু অন্তর্নির্মিত ফাংশন কলগুলি অবলম্বন করে শুরু হয়। এটি ফাংশনটির নামগুলি এনকোডিং করে বেস -২২ দ্বারা অর্জন করা হয়, তারপরে তাদেরকে একটি একক অক্ষরের নতুন গ্লোবাল-নেমস্পেসের নামগুলি প্রদান করে। কেবলমাত্র 'আতব' ব্যবহার করা হয়; অন্যান্য 2 টি কেবল লাল-হার্চিংস (ইওল কেবল অ্যাটোবাইটের মতো একই শর্টহ্যান্ড নেয়, এবং বিটিওএ কেবল ব্যবহৃত হয় না)।
_=this;
[
490837, // eval -> U="undefined" -> u(x) = eval(x) (but overwritten below), y = eval
358155, // atob -> U="function (M,..." -> u(x) = atob(x)
390922 // btoa -> U="function (M,..." -> n(x) = btoa(x), U[10] = 'M'
].map(
y=function(M,i){
return _[(U=y+"")[i]] = _[M.toString(2<<2<<2)]
}
);
এর পরে কোডটি লুকানোর জন্য বেশ কয়েকটি তুচ্ছ স্ট্রিং মিক্স-আপ রয়েছে। এগুলি সহজেই বিপরীত হয়:
u(["","GQ9ZygiYTwyPzE6YSpk","C0tYSki","SkoYSkvZChhLWIpL2QoYikg"].join("K"))
// becomes
'(d=g("a<2?1:a*d(--a)"))(a)/d(a-b)/d(b) '
u("KScpKWIsYShFLCliLGEoQyhEJyhnLGM9RSxiPUQsYT1D").split("").reverse().join("")
// becomes
"C=a,D=b,E=c,g('D(C(a,b),E(a,b))')"
অবসন্নতার মূল অংশটি হ'ল g
ফাংশনটির ব্যবহার , যা কেবল নতুন ফাংশনকে সংজ্ঞায়িত করে। এটি পুনরাবৃত্তভাবে প্রয়োগ করা হয়, ফাংশনগুলি নতুন ফাংশনগুলি ফিরিয়ে দেয় বা পরামিতি হিসাবে ফাংশনগুলির প্রয়োজন হয়, তবে শেষ পর্যন্ত ডানদিকে সরল হয়। এর থেকে বেরিয়ে আসা সবচেয়ে আকর্ষণীয় ফাংশনটি হ'ল:
function e(a,b){ // a! / ((a-b)! * b!) = nCr
d=function(a){return a<2?1:a*d(--a)} // Factorial
return d(a)/d(a-b)/d(b)
}
এই রেখার সাথে একটি চূড়ান্ত কৌশলও রয়েছে:
U[10]+[![]+[]][+[]][++[+[]][+[]]]+[!+[]+[]][+[]][+[]]+17..toString(2<<2<<2)
// U = "function (M,i"..., so U[10] = 'M'. The rest just evaluates to "ath", so this just reads "Math"
যদিও পরের বিটটি ".pow (T, a)" হয় তাই এটি "ম্যাথ" হতে পারে এমন সম্ভাবনা সবসময়ই ছিল!
প্রসারিত ক্রিয়াকলাপের পথে আমি যে পদক্ষেপ নিয়েছি সেগুলি হ'ল:
// Minimal substitutions:
function g(s){return Function("a","b","c","return "+s)};
function e(a,b,c){return (d=g("a<2?1:a*d(--a)"))(a)/d(a-b)/d(b)}
function h(a,b,c){return A=a,B=b,g('A(a,B(a))')}
function j(a,b,c){return a/b}
function L(a,b,c){return Z=a,Y=b,g('Z(a,Y)')}
k=L(j,T=2);
function F(a,b,c){return C=a,D=b,E=c,g('D(C(a,b),E(a,b))')}
RESULT=F(
h(e,k),
j,
function(a,b,c){return _['Math'].pow(T,a)}
);
// First pass
function e(a,b){
d=function(a){return a<2?1:a*d(--a)}
return d(a)/d(a-b)/d(b)
}
function h(a,b){
A=a
B=b
return function(a){
return A(a,B(a))
}
}
function j(a,b){ // ratio function
return a/b
}
function L(a,b){ // binding function (binds param b)
Z=a
Y=b
return function(a){
return Z(a,Y)
}
}
T=2; // Number of states the coin can take
k=L(j,T); // function to calculate number of heads required for fairness
function F(a,b,c){
C=a
D=b
E=c
return function(a,b,c){return D(C(a,b),E(a,b))}
}
RESULT=F(
h(e,k),
j,
function(a){return Math.pow(T,a)}
);
// Second pass
function e(a,b){...}
function k(a){
return a/2
}
function F(a,b,c){
C=a
D=b
E=c
return function(a,b,c){return D(C(a,b),E(a,b))}
}
RESULT=F(
function(a){
return e(a,k(a))
},
function(a,b){
return a/b
},
function(a){return Math.pow(2,a)}
);
// Third pass
function e(a,b) {...}
C=function(a){ // nCr(x,x/2) function
return e(a,a/2)
}
D=function(a,b){ // ratio function
return a/b
}
E=function(a){return Math.pow(2,a)} // 2^x function
RESULT=function(a,b,c){
return D(C(a,b),E(a,b))
}
ফাংশন নেস্টিংয়ের কাঠামোটি ইউটিলিটির চারপাশে ভিত্তি করে; বহিরাগত সর্বাধিক "ডি" / "জে" ফাংশন একটি অনুপাত গণনা করে, তারপরে অভ্যন্তরীণ "সি" / "এইচ" এবং "ই" (ইনলাইন) ফাংশন প্রয়োজনীয় মুদ্রার ফ্লিপ গণনা গণনা করে। তৃতীয় পাসে সরানো "এফ" ফাংশন এগুলি একসাথে ব্যবহারযোগ্য পুরোতে সংযুক্ত করার জন্য দায়ী। একইভাবে "কে" ফাংশনটি যে মাথাগুলি পর্যবেক্ষণ করা প্রয়োজন তা চয়ন করার জন্য দায়ী; একটি কার্য যা এটি প্যারামিটার বাইন্ডিং ফাংশন "এল" এর মাধ্যমে অনুপাতের ফাংশন "ডি" / "জে" এ দেয়; এখানে প্যারামিটার ঠিক করার জন্য ব্যবহৃত b
হয় T
(এখানে সর্বদা 2, মুদ্রাটি নিতে পারে এমন রাজ্যের সংখ্যা)।
শেষ পর্যন্ত, আমরা পাই:
function e(a,b){ // a! / ((a-b)! * b!)
d=function(a){return a<2?1:a*d(--a)} // Factorial
return d(a)/d(a-b)/d(b)
}
RESULT=function(a){
return e(a, a/2) / Math.pow(2,a)
}