39 বাইট পাচ্ছেন
আমি কীভাবে 39-বাইট সমাধান পেয়েছিলাম তার ব্যাখ্যা, যা ডেনিস এবং জনাথন ফ্রেচ পৃথকভাবে খুঁজে পেয়েছিল। অথবা, বরং এটি ব্যাখ্যা করে যে কীভাবে কেউ উত্তরকে দৃষ্টিনন্দন করে পৌঁছে দিতে পারে, এমনভাবে এটি আমার সত্যিকারের পথের চেয়ে অনেক সুন্দর, এটি জঞ্জাল যুক্তি এবং মৃত প্রান্তে পূর্ণ ছিল।
n=0
exec"print n;n=n+2^-(n+2^n)%3;"*400
এটিকে কিছুটা কম গল্ফযুক্ত এবং আরও বেশি প্যারেন দিয়ে লিখতে দেখে মনে হচ্ছে:
n=0
for _ in range(400):
print n
n=(n+2)^(-((n+2)^n))%3
বিট সমতা
আমরা আমার 47-বাইট সমাধানটি ফর্মের সমস্ত সংখ্যার আউটপুট থেকে একটি ধারণা দিয়ে শুরু করি n=2*k+b
যেখানে k
শীর্ষে রয়েছে 0,1,...,399
এবং b
এটি একটি সমতা বিট যা সামগ্রিক সংখ্যাকে 1 এর সমান করে তোলে।
চল লিখি par(x)
জন্য বিট সমতা এর x
, XOR (যে ^
) এ বিট সব x
। এটি যদি 1-বিটগুলির একটি সংখ্যক সংখ্যা হয় (সংখ্যাটি মন্দ হয়), এবং 1-বিটগুলির মধ্যে একটি বিজোড় সংখ্যা রয়েছে তবে 1 এটি। কারণ n=2*k+b
, আমাদের রয়েছে par(n) = par(k)^b
তাই মন্দ অর্জনের জন্য par(n)==0
আমাদের প্রয়োজন পূর্ববর্তী বিটগুলির সামান্য সমতা হওয়া b=par(k)
lastn
Golfing এ আমার প্রথম প্রচেষ্টা প্রকাশ ছিল par(k)
, প্রথম সরাসরি সঙ্গে bin(k).count('1')%2
সঙ্গে, এবং তারপর বিট ম্যানিপুলেশন ।
সমতা আপডেট
তবুও, একটি সংক্ষিপ্ত প্রকাশ বলে মনে হচ্ছে না। পরিবর্তে, এটি বুঝতে সাহায্য করে যে কাজ করার জন্য আরও তথ্য রয়েছে। কেবলমাত্র বর্তমান সংখ্যার বিট সমতা গণনা করার চেয়ে,
k ----> par(k)
হিসাবে আমরা বাড়ায় আমরা বিট সমতা আপডেট করতে পারেন k
থেকে k+1
।
k ----> par(k)
|
v
k+1 ----> par(k+1)
এটি হ'ল যেহেতু আমরা গণনা করছি k=0,1,2,...
, প্রতিবার স্ক্র্যাচ থেকে এটি গণনা করার পরিবর্তে আমাদের কেবল বর্তমান বিট সমতা বজায় রাখা দরকার need বিট সমতা আপডেট par(k+1)^par(k)
থেকে যাচ্ছে ফ্লিপ বিট সংখ্যা সমতা হয় k
থেকে k+1
, যে হয় par((k+1)^k)
।
par(k+1) ^ par(k) = par((k+1)^k)
par(k+1) = par(k) ^ par((k+1)^k)
এর ফর্ম (k+1)^k
এখন আমাদের গণনা করা দরকার par((k+1)^k)
। দেখে মনে হতে পারে আমরা আর কোথাও না পেয়েছি কারণ কম্পিউটিং বিট প্যারিটি হ'ল আমরা সমাধান করার চেষ্টা করছি exactly তবে, সংখ্যাগুলি (k+1)^k
ফর্ম হিসাবে প্রকাশিত 1,3,7,15,..
, এটি 2 এর শক্তির নীচে, একটি বিট হ্যাকগুলিতে প্রায়শই ব্যবহৃত হয় । আসুন দেখা যাক কেন।
যখন আমরা বৃদ্ধি করি k
, বাইনারি বহনের প্রভাবটি সর্বশেষ 0
এবং সমস্তকে 1
তার ডানদিকে উল্টানো হয় , 0
যদি কিছুই না থাকে তবে একটি নতুন নেতৃত্ব তৈরি করে । উদাহরণস্বরূপ, নিনk=43=0b101011
**
101011 (43)
+ 1
------
= 101100 (44)
101011 (43)
^101100 (44)
------
= 000111 (77)
বহনকারী কলামগুলির সাথে চিহ্নিত করা হয়েছে *
। এই একটি আছে 1
একটি পরিবর্তন 0
এবং একটি বহন বিট পাস 1
, যা পর্যন্ত এটি একটি হিট বাম প্রচারের রাখে 0
মধ্যে k
, যা পরিবর্তিত 1
। বাম দিকে আরও বিটগুলি প্রভাবিত হয় না। সুতরাং যখন k^(k+1)
চেক যা বিট পদের অদল বদল k
করার k+1
, এটা ডানদিকে অবস্থিত অবস্থানের খুঁজে বের করে 0
এবং 1
তার ডান দিকে 'র। অর্থাৎ পরিবর্তিত বিটগুলি প্রত্যয় গঠন করে, সুতরাং ফলাফলটি এক বা একাধিক 1 এর পরে হয়। শীর্ষস্থানীয় শূন্যগুলি ব্যতীত, বাইনারি সংখ্যা রয়েছে 1, 11, 111, 1111, ...
যা 2 এর শক্তির নীচে এক।
কম্পিউটিং par((k+1)^k)
এখন যে আমরা বুঝতে পারি যে (k+1)^k
এটি সীমাবদ্ধ 1,3,7,15,...
, আসুন এই জাতীয় সংখ্যার বিট প্যারিটি গণনা করার একটি উপায় খুঁজে বের করুন find এখানে, একটি দরকারী তথ্য যেহেতু এবং এর মধ্যে 1,2,4,8,16,...
বিকল্প মডুলু । সুতরাং, গ্রহণ মডিউল দেয় , ঠিক তাদের বিট দলগুলো যা। পারফেক্ট!3
1
2
2==-1 mod 3
1,3,7,15,31,63...
3
1,0,1,0,1,0...
সুতরাং, আমরা par(k+1) = par(k) ^ par((k+1)^k)
হিসাবে আপডেট করতে পারেন
par(k+1) = par(k) ^ ((k+1)^k)%3
b
ভেরিয়েবল হিসাবে ব্যবহার করে আমরা প্যারিটি স্টোর করছি, দেখতে এটির মতো লাগে
b^=((k+1)^k)%3
কোড লেখা
এটিকে কোডে একসাথে রেখে আমরা শুরু করি k
এবং b
উভয় ক্ষেত্রে সমতা বিট করি 0
, তারপরে বারবার মুদ্রণ n=2*k+b
এবং আপডেট b=b^((k+1)^k)%3
এবং k=k+1
।
46 বাইট
k=b=0
exec"print 2*k+b;b^=(k+1^k)%3;k+=1;"*400
এটি অনলাইন চেষ্টা করুন!
আমরা প্রায় ডান বন্ধনী মুছে k+1
মধ্যে ((k+1)^k)%3
কারণ পাইথন প্রাধান্য প্রথম যাহাই হউক না কেন, অদ্ভুত যেমন দেখায় উপরন্তু আছে।
কোড উন্নতি
আমরা একক ভেরিয়েবলের সাথে সরাসরি কাজ করে n=2*k+b
এবং তার উপর সরাসরি আপডেটগুলি সম্পাদন করে আমরা আরও ভাল করতে পারি । এর k+=1
সাথে সঙ্গতিপূর্ণ n+=2
। এবং, আপডেট করার b^=(k+1^k)%3
সাথে সম্পর্কিত n^=(k+1^k)%3
। এখানে, k=n/2
আপডেট করার আগে n
।
44 বাইট
n=0
exec"print n;n^=(n/2+1^n/2)%3;n+=2;"*400
এটি অনলাইন চেষ্টা করুন!
আমরা নতুন করে লিখে সংক্ষিপ্ত করতে পারি n/2+1^n/2
(এটি মনে রাখবেন (n/2+1)^n/2
)
n/2+1 ^ n/2
(n+2)/2 ^ n/2
(n+2 ^ n)/2
যেহেতু /2
শেষ বিটটি সরিয়ে ফেলা হয়েছে, তাই আমরা জোর-ইন করার আগে বা পরে এটি করি কিনা তা বিবেচ্য নয়। সুতরাং, আমরা আছে n^=(n+2^n)/2%3
। আমরা লক্ষ করেন, মডিউল দ্বারা অন্য বাইট সংরক্ষণ করতে পারবেন 3
, /2
সমতূল্য *2
সমতূল্য -
, তিনি উল্লেখ করেছেন n+2^n
তাই বিভাজন মেঝে ছাড়া প্রকৃত halving হয়। এই দেয়n^=-(n+2^n)%3
41 বাইট
n=0
exec"print n;n^=-(n+2^n)%3;n+=2;"*400
এটি অনলাইন চেষ্টা করুন!
পরিশেষে, আমরা অপারেশন একত্রিত করতে পারেন n^=c;n+=2
মধ্যে n=(n+2)^c
, যেখানে c
একটি বিট। এটি কাজ করে কারণ ^c
কেবল সর্বশেষ বিটটিতে কাজ করে এবং শেষ বিটের +2
কোনও যত্ন করে না তাই অপারেশনগুলি যাত্রা শুরু করে। আবার, প্রাধান্য আমাদের প্যারেনস বাদ দিতে এবং লিখতে দেয় n=n+2^c
।
39 বাইট
n=0
exec"print n;n=n+2^-(n+2^n)%3;"*400
এটি অনলাইন চেষ্টা করুন!