এক ইচ্ছায় আমি এই বছরগুলি করার সিদ্ধান্ত নিয়েছি কোডের আবির্ভাব বিশুদ্ধ SQL এ। এটি একটি আকর্ষণীয় অভিজ্ঞতা ছিল যা আমি প্রত্যেকের কাছে সুপারিশ করতে পারি কারণ এটি আপনাকে সমস্যাগুলি সম্পর্কে ভিন্নভাবে চিন্তা করতে বাধ্য করে। এবং আমি যে রিপোর্ট করতে পারেন বিশুদ্ধ এসকিউএল-এ প্রতিটি সমস্যা সমাধান করা সম্ভব ছিল.
অনেক ক্ষেত্রে SQL আসলে ব্যবহার করা আশ্চর্যজনকভাবে আনন্দদায়ক ছিল। 11 দিনের জন্য সম্পূর্ণ সমাধান (ধাঁধা ইনপুট সহ) নীচে দেখানো হয়েছে:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
with recursive aoc10_input(i) as (select ' 89010123 78121874 87430965 96549874 45678903 32019012 01329801 10456732 '), lines(y,line) as ( select 0, substr(i,1,position(E'\n' in i)-1), substr(i,position(E'\n' in i)+1) from aoc10_input union all select y+1,substr(r,1,position(E'\n' in r)-1), substr(r,position(E'\n' in r)+1) from lines l(y,l,r) where position(E'\n' in r)>0 ), field(x,y,v) as ( select x,y,ascii(substr(line,x::integer,1))-48 from (select * from lines l where line<>'') s, lateral generate_series(1,length(line)) g(x) ), paths(x,y,v,sx,sy) as ( select x,y,9,x,y from field where v = 9 union all select f.x,f.y,f.v,p.sx,p.sy from field f, paths p where f.v=p.v-1 and ((f.x=p.x and abs(f.y-p.y)=1) or (f.y=p.y and abs(f.x-p.x)=1)) and p.v>0), results as (select * from paths where v=0), part1 as (select distinct * from results) select (select count(*) from part1) as part1, (select count(*) from results) as part2 |
এসকিউএল-এ ইনপুট পার্স করা কিছুটা বেদনাদায়ক, তবে এটি খুব খারাপ নয়। লাইন 1-10 হল কেবল ধাঁধা ইনপুট, লাইন 11-17 ইনপুটটিকে পৃথক লাইনে বিভক্ত করে এবং 18-21 লাইনগুলি ইনপুট থেকে একটি 2D অ্যারে তৈরি করে। অ্যালগরিদম নিজেই বেশ সংক্ষিপ্ত, লাইন 22-27 ক্ষেত্রের একটি পুনরাবৃত্তিমূলক ট্রাভার্সাল সম্পাদন করে এবং 28-39 লাইনগুলি ট্রাভার্সাল ফলাফল থেকে ধাঁধার উত্তর বের করে। এই ধরনের ছোট স্কেল ট্রাভার্সালের জন্য এসকিউএল ঠিক কাজ করে।
অন্যান্য দিনগুলি আরও বেদনাদায়ক ছিল। দিন 16 উদাহরণস্বরূপ, ধারণাগতভাবে একটি ক্ষেত্রের খুব অনুরূপ ট্রাভার্সাল করে এবং এটি প্রতিটি পরিদর্শনের জন্য ন্যূনতম ট্রাভার্সাল দূরত্ব গণনা করে। সহজে এসকিউএল-এ প্রকাশ করা, কিন্তু মূল্যায়ন অপব্যয়। একটি বাস্তব ধাঁধা ইনপুট দিয়ে রেফারেন্স ইনপুট প্রতিস্থাপন করার সময় ক্ষেত্রটি বেশ বড়, এবং পুনরাবৃত্ত ক্যোয়ারী অনেক স্টেট তৈরি করে এবং সংরক্ষণ করে, যদিও আমরা শুধুমাত্র পুনরাবৃত্ত প্রশ্নের শেষ পুনরাবৃত্তির বিষয়ে চিন্তা করি। ফলস্বরূপ আপনার সেই ক্যোয়ারীটি চালানোর জন্য 200GB এর বেশি মেমরি সহ একটি মেশিনের প্রয়োজন, যদিও বেশিরভাগ গণনা করা টিপলগুলি অপ্রাসঙ্গিক। আমরা ব্যবহার করে যে অত্যধিক মেমরি খরচ ঠিক করতে পারে পুনরাবৃত্তি শব্দার্থিক পুনরাবৃত্তির সময়, কিন্তু এটি DBMSes দ্বারা ব্যাপকভাবে সমর্থিত নয়। Umbra এটি করতে পারে, কিন্তু Postgres এবং DuckDB পারে না, এইভাবে আমি আমার সমাধানগুলিতে এটি ব্যবহার করিনি।
এবং কখনও কখনও পুনরাবৃত্ত SQL এর প্রোগ্রামিং মডেল আমরা যা করতে চাই তার সাথে সংঘর্ষ হয়। চালু দিন 23 আমাদের স্পার্স গ্রাফে সর্বাধিক চক্র খুঁজে বের করতে হয়েছিল। এই সঙ্গে যুক্তিসঙ্গতভাবে ভাল গণনা করা যেতে পারে ব্রন-কারবোশ অ্যালগরিদমকিন্তু পুনরাবৃত্ত এসকিউএল-এ প্রকাশ করা বেশ জটিল কারণ অ্যালগরিদম একাধিক সেট বজায় রাখতে চায়, কিন্তু রিকার্সিভ এসকিউএল শুধুমাত্র একটি সেট বরাবর পাস করে। এটা করা যেতে পারে, কিন্তু ফলাফল সুন্দর দেখায় না.
এই পরীক্ষাটি আমাকে দুটি জিনিস দেখিয়েছে 1) এসকিউএল-এ বেশ জটিল অ্যালগরিদম কোড করা সম্ভব, এবং প্রায়শই এসকিউএল কোড আশ্চর্যজনকভাবে আনন্দদায়ক হয় এবং 2) পুনরাবৃত্ত এসকিউএল অনেক বেশি দক্ষ এবং ব্যবহার করা আরও আনন্দদায়ক হবে যদি আমাদের কাছে ব্যবস্থা থাকে আপডেট অবস্থা। আছে চলমান কাজ একটি ট্রামপোলিন মেকানিজমের মাধ্যমে পুনরাবৃত্তিতে আরও জটিল নিয়ন্ত্রণ প্রবাহকে সমর্থন করার বিষয়ে, যা খুব দরকারী, কিন্তু আমাদের অবশ্যই আরও জটিল রাষ্ট্রীয় ম্যানিপুলেশন প্রক্রিয়ার দিকে নজর দেওয়া উচিত। ডাটাবেসের ভিতরে জটিল অ্যালগরিদম চালানোর জন্য মাত্র কিছুটা অতিরিক্ত কার্যকারিতার সাথে SQL একটি কঠিন পছন্দ হবে।