ট্র্যাক
/
Factor
Factor
/
অনুশীলনী
/
গ্রন্থাগারিকের খতিয়ান
গ্রন্থাগারিকের খতিয়ান

গ্রন্থাগারিকের খতিয়ান

লার্নিং অনুশীলনী

ভূমিকা

কখনও আপনি একটি সিকোয়েন্সকে একটি মানে মিলিয়ে ফেলতে চান; আবার কখনও এই মিলনের পথে তৈরি হওয়া প্রতিটি মধ্যবর্তী মান দেখতে চান। Factor এদের জন্য দুটি সরঞ্জাম রেখেছে: একক মানে ভাঁজ করার জন্য reduce (sequences-এ), আর চলমান রূপটির জন্য math.statistics-এর কিউমুলেটিভ পরিবার।

reduce: সাধারণ ফোল্ড

reduce ( seq init quot: ( prev elt -- next ) -- result )

reduce একটি সিকোয়েন্সের প্রতিটি আইটেম একে একে পেরিয়ে যায়, সঙ্গে একটি চলমান ফলাফল (অ্যাকিউমুলেটর) বহন করে এবং সেটি একটি দুই-আর্গুমেন্টের কোটেশনে পাঠায়। কোটেশনটি চলমান অ্যাকিউমুলেটর আর পরের এলিমেন্টটি পায়; স্ট্যাকে সে যা রেখে যায়, সেটিই হয়ে ওঠে নতুন অ্যাকিউমুলেটর।

USING: math sequences ;

{ 1 2 3 4 } 0 [ + ] reduce .         ! => 10
{ 1 2 3 4 } 1 [ * ] reduce .         ! => 24

শূন্য নয় এমন একটি সিড আর নিজের বানানো কম্বাইনার, reduce-এর এই দুই অংশে sum আর product-এর নাগাল পৌঁছায় না। যেমন, একটি সিকোয়েন্সের বৃহত্তম মান, আর কোনো মান না ছাড়ালে একটি ডিফল্ট:

USING: math.order ;

{ 3 1 -4 5 -2 } 0 [ max ] reduce .   ! => 5
{ -3 -1 -4 }    0 [ max ] reduce .   ! => 0

সিড 0 তুলনায় অংশ নেয়: সব এলিমেন্ট হারলে সে-ই ফলাফল হয়ে দাঁড়ায়, তাই সব ঋণাত্মক মানের সিকোয়েন্সও কোনো নির্বিচারী ক্ষুদ্রতম মানের বদলে 0-ই দেয়।

কিউমুলেটিভ রিডাকশন

কখনও আপনি শুধু শেষ ফলাফল নয়, প্রতিটি মধ্যবর্তী ফলাফল চান। math.statistics-এর কিউমুলেটিভ পরিবার ইনপুটের সমান দৈর্ঘ্যের একটি সিকোয়েন্স রিটার্ন করে, যেখানে প্রতিটি অবস্থান সেই অবস্থান পর্যন্ত প্রিফিক্সের উপর করা রিডাকশন:

cum-sum     ( seq -- newseq )    ! running total
cum-product ( seq -- newseq )    ! running product
cum-min     ( seq -- newseq )    ! running minimum
cum-max     ( seq -- newseq )    ! running maximum
USING: math.statistics ;

{ 3 1 4 1 5 9 2 6 } cum-sum .        ! => { 3 4 8 9 14 23 25 31 }
{ 1 2 3 4 } cum-product .            ! => { 1 2 6 24 }
{ 3 1 4 1 5 9 2 6 } cum-min .        ! => { 3 1 1 1 1 1 1 1 }
{ 3 1 4 1 5 9 2 6 } cum-max .        ! => { 3 3 4 4 5 9 9 9 }

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

produce: আনফোল্ড

reduce একটি সিকোয়েন্সকে একটি মানে পরিণত করে। produce (sequences-এ) ঠিক উল্টো পথে হাঁটে: বারবার টেস্ট করে আর ধাপ বদলে একটি সিড থেকে একটি সিকোয়েন্স তৈরি করে:

produce ( pred quot -- seq )

প্রতিটি ইটারেশনে প্রথমে বর্তমান স্টেটের উপর pred রান করা হয়; সেটি ট্রুথি রিটার্ন করলে পরের এলিমেন্ট তৈরি করতে আর স্টেট হালনাগাদ করতে quot কল করা হয়। pred যখন f রিটার্ন করে, ইটারেশন থেমে যায় আর জমে থাকা এলিমেন্টগুলো রিটার্ন করা হয়।

একটি চিরচেনা উদাহরণ হলো ফিবোনাচি সিকোয়েন্স (প্রতিটি সংখ্যা আগের দুটির যোগফল)। চলমান স্টেট হলো (a, b) জোড়াটি। প্রতিটি ধাপে b নির্গত হয়, তারপর জোড়াটি (b, a + b) দিয়ে প্রতিস্থাপিত হয়:

USING: kernel math sequences ;

! Fibonacci numbers strictly below 100:
0 1 [ dup 100 < ] [ tuck + over ] produce 2nip .
! => { 1 1 2 3 5 8 13 21 34 55 89 }

চলমান স্টেট দুইটি মান জুড়ে বিস্তৃত, তাই জোড়াটি এগিয়ে নিতে বডি tuck ব্যবহার করে (kernel-এর; তিন এলিমেন্টের শাফল, যা উপরের মানটি দ্বিতীয়টির নিচে কপি করে), আর শেষে সব গুছিয়ে দেয় 2nip (kernel-এও আছে, nip-এর দুই-এলিমেন্টের অ্যানালগ)। কলটি বাঁ থেকে ডানে পড়লে:

  • প্রেডিকেট [ dup 100 < ] জোড়ার উপরের মানটি (যে পরের সংখ্যাটি নির্গত হবে) উঁকি দিয়ে দেখে, আর সেটি সীমার নিচে থাকা পর্যন্ত চলতে থাকে।
  • বডি [ tuck + over ] স্টেটকে (b, a + b)-তে এগিয়ে নেয় আর b নির্গত করে, স্ট্যাকে তিনটি মান রেখে যায়: নিচে নতুন জোড়া, উপরে নির্গত সংখ্যা।
  • produce থেমে যাওয়ার পর পিছনে পড়ে থাকা দুটি মান (শেষ জোড়াটি) 2nip দিয়ে ফেলে দেওয়া হয়, ফলে শুধু তৈরি হওয়া সিকোয়েন্সটি পড়ে থাকে।

produce হলো reduce-এর হুবহু দ্বৈত রূপ: যেখানে reduce একটি সিকোয়েন্সকে ভাঁজ করে একটি মানে নামায়, সেখানে produce একটি মান থেকে একটি সিকোয়েন্স খুলে তোলে।

নির্দেশনা

আপনি লাইব্রেরিয়ান, যিনি পাঠকদের অ্যাকাউন্টের খাতা রাখেন। প্রতি সপ্তাহে দুই ধরনের কাজ আপনার ডেস্কে এসে পড়ে:

  • requests-এর একটি সারি: পাঠক যে ক্রেডিটগুলো প্রয়োগ করতে চান (বই ফেরত, পরিশোধিত জরিমানা) এবং সিস্টেম যেসব নতুন ডেবিট লিপিবদ্ধ করেছে (নতুন জমা হওয়া বিলম্বিত জরিমানা)। পাঠকের অ্যাকাউন্টটি ক্রেডিট-প্রোটেক্টেড: যে ক্রেডিট পাঠককে ঋণাত্মকে ঠেলে দিতে পারে, তা কেবল বাকির পরিমাণ পর্যন্তই প্রয়োগ করা হয়, ফলে চলমান ব্যালেন্স কখনো শূন্যের নিচে নামে না।
  • transactions-এর একটি তালিকা: অ্যাকাউন্টে আগেই লিপিবদ্ধ এন্ট্রি। ধনাত্মক অঙ্ক ডেবিট (নতুন জরিমানা), ঋণাত্মক অঙ্ক ক্রেডিট (পরিশোধ)।

প্রতি সপ্তাহে আপনি হিসাব মিলিয়ে দেখেন: অনুরোধগুলো পালন করার পর চূড়ান্ত ব্যালেন্স, লেনদেন থেকে প্রতিদিনের চলমান ব্যালেন্স, এবং জরিমানা যখন লাফিয়ে বেড়েছিল এমন সময়গুলো চিহ্নিত করার জন্য একটি চলমান সর্বনিম্ন সীমা।

1. অনুরোধের সারি পালন করুন

protected-balance ডিফাইন করুন, যা একটি opening ব্যালেন্স এবং requests-এর একটি অ্যারে (চিহ্নযুক্ত পরিমাণ) নেয়, এবং প্রতিটি অনুরোধ পর্যায়ক্রমে পালন করার পর চূড়ান্ত ব্যালেন্স রিটার্ন করে। যে উত্তোলন ব্যালেন্সকে শূন্যের নিচে নামিয়ে দেবে, তা কেবল উপলব্ধ পরিমাণ পর্যন্তই পালন করা হয়, ফলে চলমান ব্যালেন্স শূন্যে গিয়ে থামে।

100 { 50 -200 30 } protected-balance .
! => 30

500 { 100 -300 -250 } protected-balance .
! => 50

0 { -10 50 } protected-balance .
! => 50

2. চলমান ব্যালেন্স

running-balance ডিফাইন করুন, যা transactions-এর একটি অ্যারে নেয় এবং একই দৈর্ঘ্যের একটি ধারা রিটার্ন করে, যার i-তম এলিমেন্ট হলো প্রথম i+1টি লেনদেনের পরের ব্যালেন্স (শূন্য শুরুর ব্যালেন্সের সাপেক্ষে)।

{ 50 -30 -20 100 } running-balance .
! => { 50 20 0 100 }

3. এখন পর্যন্ত সর্বনিম্ন ব্যালেন্স

least-balance-so-far ডিফাইন করুন, যা transactions-এর একটি অ্যারে নেয় এবং একই দৈর্ঘ্যের একটি ধারা রিটার্ন করে, যার i-তম এলিমেন্ট হলো i অবস্থান পর্যন্ত (সহ) দেখা সর্বনিম্ন চলমান ব্যালেন্স। এটিই হলো চলমান সর্বনিম্ন সীমা, যা অ্যাকাউন্টটি যেসব দিনে ঝুঁকিপূর্ণ মনে হয়েছে সেগুলো চোখে ধরতে কাজে লাগে।

{ 50 -30 -20 100 } least-balance-so-far .
! => { 50 20 0 0 }

{ 200 -50 -100 -200 } least-balance-so-far .
! => { 200 150 50 -150 }

4. টার্গেট পর্যন্ত অর্ধেক করা

লাইব্রেরি একটি জরিমানা মওকুফ কার্যক্রম চালাচ্ছে: প্রতি পরিশোধ পর্বে একজন পাঠকের অপরিশোধিত ব্যালেন্স অর্ধেক করা হয়, যতক্ষণ না তা ক্ষমার সীমায় বা তার নিচে নেমে আসে। halve-until ডিফাইন করুন, যা একটি principal এবং একটি target নেয়, এবং প্রথম অর্ধেক করা থেকে শুরু করে অর্ধেক করা মানগুলোর ধারা রিটার্ন করে (ইন্টিজার ডিভিশন ব্যবহার করে), যতক্ষণ চলমান মান কঠোরভাবে target-এর উপরে থাকে ততক্ষণ তা চলতে থাকে। সর্বশেষ যে মানটি তৈরি হবে, সেটিই প্রথম মান, যা target-এ বা তার নিচে নেমে আসে।

100 5 halve-until .
! => { 50 25 12 6 3 }

64 1 halve-until .
! => { 32 16 8 4 2 1 }

3 5 halve-until .
! => { }
GitHub-এর মাধ্যমে সম্পাদনা করুন লিংকটি একটি নতুন উইন্ডো বা ট্যাবে খোলে
Factor Exercism

গ্রন্থাগারিকের খতিয়ান শুরু করতে প্রস্তুত?

Exercism-এ সাইন আপ করুন, Factor ট্র্যাকের 47টি কনসেপ্ট163টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।