সি, 59 বাইট
i;f(char*s){while(*s&3?*s&9||(i+=i+*s%5):putchar(i),*s++);}
যাদু নম্বর, যাদু নম্বর সর্বত্র!
(এছাড়াও, পাইথন, জেএস, পিএইচপি, এবং রুবির চেয়ে সি সংক্ষিপ্ততর? শুনিনি!)
এটি এমন একটি ফাংশন যা ইনপুট হিসাবে স্ট্রিং নেয় এবং STDOUT এ আউটপুট দেয়।
walkthrough
মূল কাঠামোটি হ'ল:
i; // initialize an integer i to 0
f(char*s){
while(...); // run the stuff inside until it becomes 0
}
এখানে "ভিতরে থাকা স্টাফ" হ'ল কোডের একটি গোছা ,*s++
, যেখানে কমা অপারেটর কেবল তার দ্বিতীয় যুক্তির মান প্রদান করে। অতএব, এটি স্ট্রিংয়ের মধ্য দিয়ে চলবে এবং প্রস্থান করার আগে *s
অনুশীলনকারী NUL বাইট (যেহেতু পোস্টফিক্স ++
পূর্ববর্তী মানটি দেয়) সহ প্রতিটি অক্ষরে সেট করবে ।
বাকিটা একবার দেখে নিই:
*s&3?*s&9||(i+=i+*s%5):putchar(i)
ত্রৈমাসিক এবং শর্ট সার্কিটগুলি ছড়িয়ে দিয়ে ||
এটিকে প্রসারিত করা যেতে পারে
if (*s & 3) {
if (!(*s & 9)) {
i += i + *s % 5;
}
} else {
putchar(i);
}
এই যাদু নম্বরগুলি কোথা থেকে আসে? জড়িত সমস্ত চরিত্রের বাইনারি উপস্থাপনা এখানে:
F 70 01000110
B 66 01000010
i 105 01101001
z 122 01111010
u 117 01110101
32 00100000
\0 0 00000000
প্রথমত, আমাদের বাকী অক্ষর থেকে স্থান এবং NUL আলাদা করতে হবে। এই অ্যালগরিদম যেভাবে কাজ করে, এটি "বর্তমান" সংখ্যার সঞ্চয়কারী রাখে এবং যখন এটি কোনও স্থান বা স্ট্রিংয়ের শেষে (অর্থাত্ '\0'
) পৌঁছে যায় তখনই এটি মুদ্রণ করে । এটি লক্ষ্য করে ' '
এবং '\0'
কেবলমাত্র দুটি তাত্পর্যপূর্ণ বিট সেট না রাখার জন্য কেবলমাত্র অক্ষর, আমরা অক্ষরে অক্ষরে এবং অক্ষরটি 0b11
শূন্যের সাথে পেতে পারি যদি অন্যথায় চরিত্রটি স্থান বা NUL এবং nonzero হয়।
আরও গভীর খনন, প্রথম "যদি" শাখায়, এখন আমাদের একটি চরিত্র রয়েছে যা এর মধ্যে একটি FBizu
। আমি কেবলমাত্র F
এস এবং এসগুলিতে সংযোজক আপডেট করতে বেছে নিয়েছি B
, সুতরাং এস ফিল্টার করার জন্য আমার কিছু উপায়ের প্রয়োজন ছিল izu
। সুবিধামতো, F
এবং B
উভয়েরই কেবল দ্বিতীয়, তৃতীয়, বা সপ্তমতম সর্বনিম্ন উল্লেখযোগ্য বিট সেট রয়েছে এবং অন্য সমস্ত সংখ্যায় কমপক্ষে একটি অন্য বিট সেট রয়েছে। আসলে, তাদের সবারই প্রথম বা চতুর্থ অন্তত গুরুত্বপূর্ণ বিট রয়েছে। অত: পর, আমরা bitwise করতে এবং 0b00001001
, যা 9 0 উত্পাদ করবে F
এবং B
এবং অশূন্য অন্যথায়।
একবার আমরা এই সিদ্ধান্তে পৌঁছেছি আমরা একটি আছে F
বা B
আমরা তাদের ম্যাপ করতে পারেন 0
এবং 1
তাদের মডুলাস 5 গ্রহণ করে যথাক্রমে কারণ F
হয় 70
এবং B
হয় 66
। তারপরে স্নিপেট
i += i + *s % 5;
বলার এক গোলাপি উপায় way
i = (i * 2) + (*s % 5);
যা হিসাবে প্রকাশ করা যেতে পারে
i = (i << 1) | (*s % 5);
যা সর্বনিম্ন তাৎপর্যপূর্ণ অবস্থানে নতুন বিটটি সন্নিবেশ করায় এবং বাকি সমস্ত কিছু 1 এর চেয়ে বেশি স্থানান্তর করে।
"কিন্তু অপেক্ষা করো!" আপনি প্রতিবাদ করতে পারেন। "আপনি মুদ্রণের পরে i
, এটি কখন 0 এ পুনরায় সেট হয়?" ঠিক আছে, putchar
এটির পক্ষে তার যুক্তিটি কাস্ট করে unsigned char
যা আকারে 8 বিট হতে পারে। এর অর্থ অষ্টমতম তাত্পর্যপূর্ণ বিট (অর্থাৎ পূর্ববর্তী পুনরাবৃত্তির জাঙ্ক) থেকে সমস্ত কিছু ফেলে দেওয়া হয় এবং আমাদের এটি নিয়ে উদ্বিগ্ন হওয়ার দরকার নেই।
একটি বাইট সংরক্ষণের সাথে প্রতিস্থাপনের পরামর্শ দেওয়ার জন্য @ETH প্রডাকশনগুলিকে ধন্যবাদ !57
9