Live Coding

একটি অবজেক্ট খালি কিনা তা পরীক্ষা করুন

একটি জাভাস্ক্রিপ্ট অবজেক্ট খালি কিনা তা কিভাবে পরীক্ষা করবেন?

ব্যাখ্যা: একটি অবজেক্ট খালি হয় যদি এটির কোনো নিজস্ব গণনযোগ্য বৈশিষ্ট্য না থাকে। আমরা 'Object.keys(obj)' ব্যবহার করতে পারি যা একটি প্রদত্ত অবজেক্টের নিজস্ব গণনযোগ্য বৈশিষ্ট্যের নামগুলির একটি অ্যারে প্রদান করে। যদি এই অ্যারের দৈর্ঘ্য 0 হয়, তাহলে অবজেক্টটি খালি।

function isEmpty(obj) {   return Object.keys(obj).length === 0; } console.log(isEmpty({})); // true console.log(isEmpty({ a: 1 })); // false

একটি স্ট্রিং উল্টান

একটি প্রদত্ত স্ট্রিং উল্টানোর জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: সবচেয়ে সহজ উপায় হল স্ট্রিংটিকে অক্ষরগুলির একটি অ্যারেতে রূপান্তর করা, অ্যারেগুলির জন্য বিল্ট-ইন 'reverse()' পদ্ধতি ব্যবহার করা এবং তারপর অক্ষরগুলিকে আবার একটি স্ট্রিংয়ে যোগ করা।

function reverseString(str) {   return str.split('').reverse().join(''); } console.log(reverseString('hello')); // 'olleh'

প্যালিনড্রোম পরীক্ষা

একটি প্রদত্ত স্ট্রিং একটি প্যালিনড্রোম কিনা তা পরীক্ষা করার জন্য একটি ফাংশন লিখুন।

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

function isPalindrome(str) {   const reversed = str.split('').reverse().join('');   return str === reversed; } console.log(isPalindrome('racecar')); // true console.log(isPalindrome('hello')); // false

একটি অ্যারেতে সর্বোচ্চ সংখ্যা খুঁজুন

সংখ্যাগুলির একটি অ্যারেতে সবচেয়ে বড় সংখ্যাটি খুঁজে বের করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: আপনি অ্যারের মাধ্যমে পুনরাবৃত্তি করতে পারেন, এখন পর্যন্ত পাওয়া সবচেয়ে বড় সংখ্যাটির ট্র্যাক রাখতে পারেন। বিকল্পভাবে, আপনি 'Math.max()' ফাংশনটি স্প্রেড সিনট্যাক্স ('...') সহ ব্যবহার করতে পারেন অ্যারে উপাদানগুলিকে আর্গুমেন্ট হিসাবে পাস করতে।

function findMaxNumber(arr) {   if (arr.length === 0) return undefined; // Or throw an error   return Math.max(...arr); } console.log(findMaxNumber([1, 5, 2, 9, 3])); // 9

ফিজবাজ

একটি প্রোগ্রাম লিখুন যা 1 থেকে n পর্যন্ত সংখ্যাগুলি প্রিন্ট করে। কিন্তু তিনের গুণিতকগুলির জন্য, সংখ্যার পরিবর্তে 'Fizz' প্রিন্ট করুন এবং পাঁচের গুণিতকগুলির জন্য, 'Buzz' প্রিন্ট করুন। যে সংখ্যাগুলি তিন এবং পাঁচ উভয়ের গুণিতক, সেগুলির জন্য 'FizzBuzz' প্রিন্ট করুন।

ব্যাখ্যা: এই ক্লাসিক সমস্যাটি মৌলিক লুপ এবং শর্তাধীন যুক্তি পরীক্ষা করে। আপনাকে 1 থেকে n পর্যন্ত পুনরাবৃত্তি করতে হবে এবং 3 এবং 5 দ্বারা বিভাজ্যতা পরীক্ষা করতে মডুলো অপারেটর ('%') ব্যবহার করতে হবে।

function fizzBuzz(n) {   for (let i = 1; i <= n; i++) {     if (i % 3 === 0 && i % 5 === 0) {       console.log('FizzBuzz');     } else if (i % 3 === 0) {       console.log('Fizz');     } else if (i % 5 === 0) {       console.log('Buzz');     } else {       console.log(i);     }   } } fizzBuzz(15);

একটি অ্যারে থেকে ডুপ্লিকেট সরান

একটি ফাংশন লিখুন যা একটি অ্যারে থেকে ডুপ্লিকেট উপাদানগুলি সরিয়ে দেয়।

ব্যাখ্যা: এটি অর্জন করার একটি আধুনিক এবং সংক্ষিপ্ত উপায় হল একটি 'Set' ব্যবহার করা। সেটগুলি শুধুমাত্র অনন্য মান সংরক্ষণ করে। আপনি অ্যারেটিকে একটি সেটে রূপান্তর করতে পারেন এবং তারপর আবার একটি অ্যারেতে।

function removeDuplicates(arr) {   return [...new Set(arr)]; } console.log(removeDuplicates([1, 2, 2, 3, 4, 4, 5])); // [1, 2, 3, 4, 5]

অ্যানাগ্রাম পরীক্ষা

দুটি স্ট্রিং একে অপরের অ্যানাগ্রাম কিনা তা পরীক্ষা করার জন্য একটি ফাংশন লিখুন।

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

function isAnagram(str1, str2) {   const clean = (str) => str.replace(/[^a-z0-9]/gi, '').toLowerCase();   const sorted = (str) => clean(str).split('').sort().join('');     return sorted(str1) === sorted(str2); } console.log(isAnagram('listen', 'silent')); // true console.log(isAnagram('hello', 'world')); // false

ফ্যাক্টরিয়াল গণনা করুন

একটি অ-নেতিবাচক পূর্ণসংখ্যার ফ্যাক্টরিয়াল গণনা করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: একটি সংখ্যার ফ্যাক্টরিয়াল (n!) হল n এর সমান বা তার কম সমস্ত ধনাত্মক পূর্ণসংখ্যার গুণফল। আমরা 1 থেকে n পর্যন্ত সংখ্যাগুলি গুণ করে পুনরাবৃত্তিমূলকভাবে এটি গণনা করতে পারি।

function factorial(n) {   if (n < 0) return undefined; // Factorial is not defined for negative numbers   if (n === 0) return 1;   let result = 1;   for (let i = 1; i <= n; i++) {     result *= i;   }   return result; } console.log(factorial(5)); // 120

একটি অ্যারেতে সমস্ত সংখ্যা যোগ করুন

একটি ফাংশন লিখুন যা একটি অ্যারেতে সমস্ত সংখ্যার যোগফল প্রদান করে।

ব্যাখ্যা: আপনি 'reduce' পদ্ধতিটি ব্যবহার করতে পারেন, যা একটি অ্যারে থেকে একক মান সংগ্রহ করার জন্য আদর্শ। এটি একটি কলব্যাক ফাংশন এবং একটি প্রাথমিক মান (যোগফলের জন্য 0) নেয়।

function sumArray(arr) {   return arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0); } console.log(sumArray([1, 2, 3, 4])); // 10

একটি নেস্টেড অ্যারে সমতল করুন

একটি নেস্টেড অ্যারে সমতল করার জন্য একটি ফাংশন লিখুন। সরলতার জন্য, শুধুমাত্র এক স্তরের নেস্টিং অনুমান করুন।

ব্যাখ্যা: এক স্তরের নেস্টিংয়ের জন্য, আপনি স্প্রেড অপারেটর বা 'flat()' পদ্ধতি (ES2019) সহ 'Array.prototype.concat()' ব্যবহার করতে পারেন।

function flattenArray(arr) {   // Using flat() (simpler if ES2019+ is okay)   // return arr.flat();   // Using reduce and concat   return arr.reduce((acc, val) => acc.concat(val), []); } console.log(flattenArray([1, [2, 3], 4, [5]])); // [1, 2, 3, 4, 5]

একটি স্ট্রিংয়ে স্বরবর্ণ গণনা করুন

একটি ফাংশন লিখুন যা একটি প্রদত্ত স্ট্রিংয়ে স্বরবর্ণের সংখ্যা (a, e, i, o, u) গণনা করে।

ব্যাখ্যা: স্ট্রিংয়ের মাধ্যমে পুনরাবৃত্তি করুন (কেস-অসংবেদনশীলভাবে) এবং প্রতিটি অক্ষর স্বরবর্ণ কিনা তা পরীক্ষা করুন। একটি কাউন্টার বজায় রাখুন।

function countVowels(str) {   const vowels = 'aeiou';   let count = 0;   for (let char of str.toLowerCase()) {     if (vowels.includes(char)) {       count++;     }   }   return count; } console.log(countVowels('Hello World')); // 3

একটি বাক্যকে টাইটেল কেস করুন

একটি ফাংশন লিখুন যা একটি বাক্যকে টাইটেল কেসে রূপান্তরিত করে (প্রতিটি শব্দের প্রথম অক্ষর বড় হাতের)।

ব্যাখ্যা: বাক্যটিকে শব্দগুলিতে বিভক্ত করুন, তারপর প্রতিটি শব্দের মাধ্যমে পুনরাবৃত্তি করুন, প্রথম অক্ষরটিকে বড় হাতের করুন এবং বাকিগুলিকে ছোট হাতের করুন। অবশেষে, শব্দগুলিকে আবার একসাথে যোগ করুন।

function titleCase(str) {   return str.toLowerCase().split(' ').map(word => {     return word.charAt(0).toUpperCase() + word.slice(1);   }).join(' '); } console.log(titleCase('i am a little tea pot')); // 'I Am A Little Tea Pot'

টু সাম সমস্যা

পূর্ণসংখ্যা 'nums' এর একটি অ্যারে এবং একটি পূর্ণসংখ্যা 'target' দেওয়া হলে, দুটি সংখ্যার সূচকগুলি ফেরত দিন যাতে তারা 'target' এর সাথে যোগ করে।

ব্যাখ্যা: একটি সাধারণ পদ্ধতি হল একটি হ্যাশ ম্যাপ (বা একটি জাভাস্ক্রিপ্ট অবজেক্ট) ব্যবহার করা সংখ্যা এবং তাদের সূচকগুলি সংরক্ষণ করার জন্য যখন আপনি পুনরাবৃত্তি করেন। প্রতিটি সংখ্যার জন্য, 'target - current_number' ম্যাপে বিদ্যমান কিনা তা পরীক্ষা করুন।

function twoSum(nums, target) {   const map = {};   for (let i = 0; i < nums.length; i++) {     const complement = target - nums[i];     if (map[complement] !== undefined) {       return [map[complement], i];     }     map[nums[i]] = i;   }   return []; // Or null, or throw error if no solution } console.log(twoSum([2, 7, 11, 15], 9)); // [0, 1]

ক্লোজার ব্যবহার করে একটি কাউন্টার প্রয়োগ করুন

একটি ফাংশন তৈরি করুন যা একটি কাউন্টার ফাংশন প্রদান করে। যতবার ফিরে আসা ফাংশনটি কল করা হয়, এটি বৃদ্ধি এবং একটি গণনা প্রদান করবে।

ব্যাখ্যা: এটি ক্লোজার প্রদর্শন করে। অভ্যন্তরীণ ফাংশনটির বাইরের ফাংশনের স্কোপের 'count' ভেরিয়েবলে অ্যাক্সেস রয়েছে, এমনকি বাইরের ফাংশনটি এক্সিকিউশন শেষ করার পরেও।

function createCounter() {   let count = 0;   return function() {     count++;     return count;   }; } const counter1 = createCounter(); console.log(counter1()); // 1 console.log(counter1()); // 2 const counter2 = createCounter(); console.log(counter2()); // 1

প্রথম পুনরাবৃত্তি না হওয়া অক্ষরটি খুঁজুন

একটি ফাংশন লিখুন যা একটি স্ট্রিংয়ে প্রথম পুনরাবৃত্তি না হওয়া অক্ষরটি খুঁজে বের করে।

ব্যাখ্যা: আপনি অক্ষর ফ্রিকোয়েন্সি গণনা করতে একটি হ্যাশ ম্যাপ ব্যবহার করতে পারেন। প্রথমে, ফ্রিকোয়েন্সি ম্যাপ তৈরি করতে স্ট্রিংয়ের মাধ্যমে পুনরাবৃত্তি করুন। তারপর, আবার স্ট্রিংয়ের মাধ্যমে পুনরাবৃত্তি করুন এবং 1 এর গণনা সহ প্রথম অক্ষরটি ফেরত দিন।

function firstNonRepeatingChar(str) {   const charCount = {};   for (const char of str) {     charCount[char] = (charCount[char] || 0) + 1;   }   for (const char of str) {     if (charCount[char] === 1) {       return char;     }   }   return null; // Or some indicator if all repeat } console.log(firstNonRepeatingChar('aabbcdeeff')); // 'c' console.log(firstNonRepeatingChar('swiss')); // 'w'

অ্যারে চাঙ্কিং

একটি ফাংশন লিখুন যা একটি অ্যারে নির্দিষ্ট আকারের গ্রুপগুলিতে বিভক্ত করে।

ব্যাখ্যা: অ্যারের মাধ্যমে পুনরাবৃত্তি করুন, নির্দিষ্ট আকারের টুকরোগুলি নিন এবং সেগুলিকে একটি নতুন অ্যারেতে পুশ করুন। শেষ খণ্ডটি ছোট হতে পারে এমন ক্ষেত্রেও হ্যান্ডেল করুন।

function chunkArray(arr, size) {   const chunked = [];   let index = 0;   while (index < arr.length) {     chunked.push(arr.slice(index, index + size));     index += size;   }   return chunked; } console.log(chunkArray([1, 2, 3, 4, 5, 6, 7], 3)); // [[1, 2, 3], [4, 5, 6], [7]]

একটি সংখ্যা মৌলিক কিনা তা পরীক্ষা করুন

একটি প্রদত্ত সংখ্যা একটি মৌলিক সংখ্যা কিনা তা নির্ধারণ করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: একটি মৌলিক সংখ্যা হল 1 এর চেয়ে বড় একটি স্বাভাবিক সংখ্যা যার 1 এবং নিজেই ব্যতীত অন্য কোন ধনাত্মক ভাজক নেই। সংখ্যার বর্গমূল পর্যন্ত 2 থেকে পুনরাবৃত্তি করুন, বিভাজ্যতা পরীক্ষা করুন। 1 এবং 2 এর মতো প্রান্তিক কেসগুলিও হ্যান্ডেল করুন।

function isPrime(num) {   if (num <= 1) return false;   if (num <= 3) return true;   if (num % 2 === 0 || num % 3 === 0) return false;   for (let i = 5; i * i <= num; i = i + 6) {     if (num % i === 0 || num % (i + 2) === 0) return false;   }   return true; } console.log(isPrime(7)); // true console.log(isPrime(10)); // false

একটি স্ট্রিংয়ে দীর্ঘতম শব্দটি খুঁজুন

একটি ফাংশন লিখুন যা একটি বাক্যে দীর্ঘতম শব্দটি খুঁজে বের করে।

ব্যাখ্যা: স্ট্রিংটিকে শব্দগুলির একটি অ্যারেতে বিভক্ত করুন। তারপর, অ্যারের মাধ্যমে পুনরাবৃত্তি করুন, এখন পর্যন্ত পাওয়া দীর্ঘতম শব্দটির ট্র্যাক রাখুন (বা এটির দৈর্ঘ্য)।

function findLongestWord(str) {   const words = str.split(' ');   let longestWord = '';   for (const word of words) {     // Clean words if needed (e.g., remove punctuation)     if (word.length > longestWord.length) {       longestWord = word;     }   }   return longestWord; } console.log(findLongestWord('The quick brown fox jumped over the lazy dog')); // 'jumped'

'Array.prototype.map' প্রয়োগ করুন

'Array.prototype.map' ফাংশনের আপনার নিজস্ব সংস্করণ প্রয়োগ করুন।

ব্যাখ্যা: 'map' ফাংশনটি একটি কলব্যাক নেয় এবং মূল অ্যারের প্রতিটি উপাদানে কলব্যাক প্রয়োগ করে একটি নতুন অ্যারে তৈরি করে। আপনার ফাংশনটি অ্যারের মাধ্যমে পুনরাবৃত্তি করবে এবং নতুন অ্যারে তৈরি করবে।

function myMap(arr, callback) {   const mappedArray = [];   for (let i = 0; i < arr.length; i++) {     mappedArray.push(callback(arr[i], i, arr));   }   return mappedArray; } const numbers = [1, 4, 9]; const roots = myMap(numbers, Math.sqrt); console.log(roots); // [1, 2, 3]

'Array.prototype.filter' প্রয়োগ করুন

'Array.prototype.filter' ফাংশনের আপনার নিজস্ব সংস্করণ প্রয়োগ করুন।

ব্যাখ্যা: 'filter' ফাংশনটি একটি কলব্যাক নেয় এবং প্রদত্ত কলব্যাক ফাংশন দ্বারা প্রয়োগ করা পরীক্ষা পাস করে এমন সমস্ত উপাদান সহ একটি নতুন অ্যারে তৈরি করে।

function myFilter(arr, callback) {   const filteredArray = [];   for (let i = 0; i < arr.length; i++) {     if (callback(arr[i], i, arr)) {         filteredArray.push(arr[i]);     }   }   return filteredArray; } const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present']; const result = myFilter(words, word => word.length > 6); console.log(result); // ['exuberant', 'destruction', 'present']

'Array.prototype.reduce' প্রয়োগ করুন

'Array.prototype.reduce' ফাংশনের আপনার নিজস্ব সংস্করণ প্রয়োগ করুন।

ব্যাখ্যা: 'reduce' ফাংশনটি অ্যারের প্রতিটি উপাদানে একটি ব্যবহারকারী-সরবরাহকৃত 'reducer' কলব্যাক ফাংশন সম্পাদন করে, পূর্ববর্তী উপাদানের গণনার ফেরত মান পাস করে। অ্যারের সমস্ত উপাদান জুড়ে রিডিউসার চালানোর চূড়ান্ত ফলাফল হল একটি একক মান। প্রাথমিক মান আর্গুমেন্ট হ্যান্ডেল করুন।

function myReduce(arr, callback, initialValue) {   let accumulator = initialValue;   let startIndex = 0;   if (initialValue === undefined) {       if (arr.length === 0) throw new TypeError('Reduce of empty array with no initial value');       accumulator = arr[0];       startIndex = 1;   }   for (let i = startIndex; i < arr.length; i++) {     accumulator = callback(accumulator, arr[i], i, arr);   }   return accumulator; } const array1 = [1, 2, 3, 4]; const sum = myReduce(array1, (acc, curr) => acc + curr, 0); console.log(sum); // 10

মেমোাইজেশন - ফিবোনাচি ক্রম

কর্মক্ষমতা অপ্টিমাইজ করার জন্য মেমোাইজেশন ব্যবহার করে একটি ফিবোনাচি ফাংশন প্রয়োগ করুন।

ব্যাখ্যা: ফিবোনাচি ক্রমে বারবার গণনা জড়িত। মেমোাইজেশন ব্যয়বহুল ফাংশন কলগুলির ফলাফল সংরক্ষণ করে এবং একই ইনপুট আবার ঘটলে ক্যাশ করা ফলাফল প্রদান করে।

function memoizedFib() {   const cache = {};   function fib(n) {     if (n in cache) {       return cache[n];     }     if (n <= 1) {       return n;     }     const result = fib(n - 1) + fib(n - 2);     cache[n] = result;     return result;   }   return fib; } const fibonacci = memoizedFib(); console.log(fibonacci(10)); // 55 console.log(fibonacci(40)); // 102334155 (much faster than non-memoized)

ভারসাম্যপূর্ণ বন্ধনীগুলির জন্য পরীক্ষা করুন

বন্ধনী {}[]() ধারণকারী একটি স্ট্রিং ভারসাম্যপূর্ণ কিনা তা পরীক্ষা করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: একটি স্ট্যাক ব্যবহার করুন। যখন আপনি একটি খোলা বন্ধনী দেখতে পান, তখন এটিকে স্ট্যাকে পুশ করুন। যখন আপনি একটি বন্ধ বন্ধনী দেখতে পান, তখন স্ট্যাকটি খালি কিনা বা শীর্ষ উপাদানটি মিলে যাওয়া খোলা বন্ধনী কিনা তা পরীক্ষা করুন। যদি এটি মিলে যায়, স্ট্যাকটি পপ করুন। যদি না হয়, বা যদি স্ট্যাকটি খালি হয়, তাহলে এটি ভারসাম্যহীন। শেষে, একটি খালি স্ট্যাক মানে ভারসাম্যপূর্ণ।

function isBalanced(str) {   const stack = [];   const map = { '(': ')', '{': '}', '[': ']' };   for (let char of str) {     if (map[char]) {       stack.push(char);     } else if (Object.values(map).includes(char)) {       if (stack.length === 0) return false;       const lastOpen = stack.pop();       if (map[lastOpen] !== char) return false;     }   }   return stack.length === 0; } console.log(isBalanced('({[]})')); // true console.log(isBalanced('([)]')); // false

একটি সাধারণ কিউ প্রয়োগ করুন

enqueue (পিছনে যোগ করুন) এবং dequeue (সামনে থেকে সরান) পদ্ধতি সহ একটি কিউ ডেটা স্ট্রাকচার প্রয়োগ করুন।

ব্যাখ্যা: একটি কিউ ফার্স্ট-ইন, ফার্স্ট-আউট (FIFO) নীতি অনুসরণ করে। একটি অ্যারে ব্যবহার করা যেতে পারে, enqueue এর জন্য push এবং dequeue এর জন্য shift সহ।

class Queue {   constructor() {     this.items = [];   }   enqueue(element) {     this.items.push(element);   }   dequeue() {     if (this.isEmpty()) return 'Underflow';     return this.items.shift();   }   front() {     if (this.isEmpty()) return 'No elements in Queue';     return this.items[0];   }   isEmpty() {     return this.items.length === 0;   } } const q = new Queue(); q.enqueue(10); q.enqueue(20); console.log(q.dequeue()); // 10 console.log(q.front()); // 20

একটি সাধারণ স্ট্যাক প্রয়োগ করুন

push (উপরে যোগ করুন) এবং pop (উপর থেকে সরান) পদ্ধতি সহ একটি স্ট্যাক ডেটা স্ট্রাকচার প্রয়োগ করুন।

ব্যাখ্যা: একটি স্ট্যাক লাস্ট-ইন, ফার্স্ট-আউট (LIFO) নীতি অনুসরণ করে। একটি অ্যারে ব্যবহার করা যেতে পারে, push এবং pop পদ্ধতি সহ।

class Stack {   constructor() {     this.items = [];   }   push(element) {     this.items.push(element);   }   pop() {     if (this.isEmpty()) return 'Underflow';     return this.items.pop();   }   peek() {     return this.items[this.items.length - 1];   }   isEmpty() {     return this.items.length === 0;   } } const s = new Stack(); s.push(10); s.push(20); console.log(s.pop()); // 20 console.log(s.peek()); // 10

ক্রমে অনুপস্থিত সংখ্যা খুঁজুন

0, 1, 2, ..., n থেকে নেওয়া n স্বতন্ত্র সংখ্যা ধারণকারী একটি অ্যারে দেওয়া হলে, অ্যারে থেকে অনুপস্থিত সংখ্যাটি খুঁজুন।

ব্যাখ্যা: 0 থেকে n পর্যন্ত সংখ্যাগুলির যোগফল n*(n+1)/2 সূত্র ব্যবহার করে গণনা করা যেতে পারে। অ্যারে উপাদানগুলির আসল যোগফল গণনা করা যেতে পারে। এই দুটি যোগফলের পার্থক্যই হবে অনুপস্থিত সংখ্যা।

function findMissingNumber(nums) {   const n = nums.length;   const expectedSum = n * (n + 1) / 2;   const actualSum = nums.reduce((sum, num) => sum + num, 0);   return expectedSum - actualSum; } console.log(findMissingNumber([3, 0, 1])); // 2 console.log(findMissingNumber([9, 6, 4, 2, 3, 5, 7, 0, 1])); // 8

ডিবউন্স ফাংশন

একটি ডিবউন্স ফাংশন প্রয়োগ করুন। ডিবউন্সিং নিশ্চিত করে যে একটি ফাংশনটি কল করার পর একটি নির্দিষ্ট সময় অতিবাহিত না হওয়া পর্যন্ত এটি আবার কল করা হবে না।

ব্যাখ্যা: 'setTimeout' এবং 'clearTimeout' ব্যবহার করুন। যতবার ডিবউন্সড ফাংশনটি কল করা হয়, পূর্ববর্তী টাইমআউটটি পরিষ্কার করুন এবং একটি নতুন সেট করুন। আসল ফাংশন কলটি শুধুমাত্র তখনই ঘটে যখন টাইমআউটটি সম্পূর্ণ হয়।

function debounce(func, delay) {   let timeoutId;   return function(...args) {     clearTimeout(timeoutId);     timeoutId = setTimeout(() => {       func.apply(this, args);     }, delay);   }; } // Example usage: const sayHello = () => console.log('Hello!'); const debouncedHello = debounce(sayHello, 1000); debouncedHello(); // Called after 1 sec (if not called again) debouncedHello(); // Resets timer debouncedHello(); // Resets timer, will actually run 1 sec after this call.

থ্রটল ফাংশন

একটি থ্রটল ফাংশন প্রয়োগ করুন। থ্রটলিং নিশ্চিত করে যে একটি ফাংশন একটি নির্দিষ্ট সময় বিরতিতে সর্বাধিক একবার কল করা হয়।

ব্যাখ্যা: একটি কল অনুমোদিত কিনা তা নির্দেশ করতে একটি ফ্ল্যাগ ব্যবহার করুন। যখন কল করা হয়, যদি অনুমোদিত হয়, ফাংশনটি এক্সিকিউট করুন, ফ্ল্যাগটিকে মিথ্যাতে সেট করুন এবং বিরতির পরে ফ্ল্যাগটি পুনরায় সেট করতে 'setTimeout' ব্যবহার করুন।

function throttle(func, limit) {   let inThrottle = false;   return function(...args) {     if (!inThrottle) {       func.apply(this, args);       inThrottle = true;       setTimeout(() => inThrottle = false, limit);     }   }; } // Example usage: const logScroll = () => console.log('Scrolling...'); const throttledScroll = throttle(logScroll, 1000); // window.addEventListener('scroll', throttledScroll); // Will log at most once per second.

ক্যারিং ফাংশন

একটি ফাংশন লিখুন যা দুটি আর্গুমেন্ট সহ একটি ফাংশন নেয় এবং এটির একটি কারিড সংস্করণ প্রদান করে।

ব্যাখ্যা: কারিং একাধিক আর্গুমেন্ট সহ একটি ফাংশনকে ফাংশনগুলির একটি অনুক্রমে রূপান্তরিত করে, প্রতিটি একটি একক আর্গুমেন্ট নেয়। 'f(a, b)' হয়ে যায় 'f(a)(b)'।

function curry(fn) {   return function(a) {     return function(b) {       return fn(a, b);     };   }; } function add(a, b) {   return a + b; } const curriedAdd = curry(add); const add5 = curriedAdd(5); console.log(add5(3)); // 8 console.log(curriedAdd(10)(20)); // 30

একটি অবজেক্ট ডিপ ক্লোন করুন

একটি জাভাস্ক্রিপ্ট অবজেক্টের একটি ডিপ ক্লোন সম্পাদন করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: একটি শ্যালো ক্লোন শুধুমাত্র টপ-লেভেল বৈশিষ্ট্যগুলি অনুলিপি করে। একটি ডিপ ক্লোন রিকার্সিভলি সমস্ত বৈশিষ্ট্য অনুলিপি করে, যার মধ্যে নেস্টেড অবজেক্ট এবং অ্যারে অন্তর্ভুক্ত। একটি সহজ উপায় (সীমাবদ্ধতা সহ, যেমন, ফাংশন, তারিখ, রেজেক্স ভালভাবে পরিচালনা করে না) হল 'JSON.parse(JSON.stringify(obj))' ব্যবহার করা। একটি রিকার্সিভ পদ্ধতি আরও শক্তিশালী।

function deepClone(obj) {   // Simple version (with limitations)   try {       return JSON.parse(JSON.stringify(obj));   } catch (e) {       console.error('Cloning failed:', e);       return null;   }     // More robust recursive (basic example):   /*   if (obj === null || typeof obj !== 'object') {       return obj;   }   let clone = Array.isArray(obj) ? [] : {};   for (let key in obj) {       if (Object.prototype.hasOwnProperty.call(obj, key)) {           clone[key] = deepClone(obj[key]);       }   }   return clone;   */ } const original = { a: 1, b: { c: 2 } }; const cloned = deepClone(original); cloned.b.c = 3; console.log(original.b.c); // 2 (proves it's a deep clone) console.log(cloned.b.c); // 3

অবজেক্ট কীগুলি পান

একটি অবজেক্ট থেকে কীগুলির একটি অ্যারে কিভাবে পাবেন?

ব্যাখ্যা: 'Object.keys(obj)' ব্যবহার করুন।

function getKeys(obj) {   return Object.keys(obj); } console.log(getKeys({a: 1, b: 2})); // ['a', 'b']

অবজেক্ট মানগুলি পান

একটি অবজেক্ট থেকে মানগুলির একটি অ্যারে কিভাবে পাবেন?

ব্যাখ্যা: 'Object.values(obj)' ব্যবহার করুন।

function getValues(obj) {   return Object.values(obj); } console.log(getValues({a: 1, b: 2})); // [1, 2]

অ্যারেতে মান অন্তর্ভুক্ত কিনা তা পরীক্ষা করুন

একটি অ্যারেতে একটি নির্দিষ্ট মান রয়েছে কিনা তা কিভাবে পরীক্ষা করবেন?

ব্যাখ্যা: 'Array.prototype.includes(value)' ব্যবহার করুন।

function checkIncludes(arr, val) {   return arr.includes(val); } console.log(checkIncludes([1, 2, 3], 2)); // true

দুটি অ্যারে মার্জ করুন

দুটি অ্যারে কিভাবে একটিতে মার্জ করবেন?

ব্যাখ্যা: স্প্রেড সিনট্যাক্স ('...') বা 'Array.prototype.concat()' ব্যবহার করুন।

function mergeArrays(arr1, arr2) {   return [...arr1, ...arr2]; } console.log(mergeArrays([1, 2], [3, 4])); // [1, 2, 3, 4]

গ্লোবাল স্কোপে 'this' ব্যাখ্যা করুন

একটি ব্রাউজারে গ্লোবাল স্কোপে 'this' কী বোঝায়?

ব্যাখ্যা: গ্লোবাল এক্সিকিউশন কনটেক্সটে (যেকোন ফাংশনের বাইরে), 'this' গ্লোবাল অবজেক্টকে বোঝায়, যা ওয়েব ব্রাউজারগুলিতে 'window' হয়।

console.log(this === window); // true (in a browser environment)

একটি অবজেক্ট পদ্ধতিতে 'this' ব্যাখ্যা করুন

একটি অবজেক্ট পদ্ধতির ভিতরে ব্যবহার করা হলে 'this' কী বোঝায়?

ব্যাখ্যা: যখন একটি ফাংশনকে একটি অবজেক্টের পদ্ধতি হিসাবে কল করা হয়, তখন 'this' সেই অবজেক্টটিকে বোঝায় যার উপর পদ্ধতিটি কল করা হয়েছে।

const myObject = {   prop: 'Hello',   greet() {     return this.prop;   } }; console.log(myObject.greet()); // 'Hello'

অ্যারো ফাংশনগুলির সাথে 'this' ব্যাখ্যা করুন

অ্যারো ফাংশনগুলি 'this' কিভাবে পরিচালনা করে?

ব্যাখ্যা: অ্যারো ফাংশনগুলির নিজস্ব 'this' কনটেক্সট নেই। পরিবর্তে, তারা তাদের সংজ্ঞায়িত করা আশেপাশের (lexical) স্কোপ থেকে 'this' উত্তরাধিকার সূত্রে পায়।

function MyClass() {   this.value = 42;   setTimeout(() => {     console.log(this.value); // Logs 42 because 'this' is inherited   }, 100); } new MyClass();

'let', 'const' এবং 'var' এর মধ্যে পার্থক্য

'let', 'const' এবং 'var' এর মধ্যে প্রধান পার্থক্যগুলি কী কী?

ব্যাখ্যা: 'var' ফাংশন-স্কোপড এবং হোস্ট করা হয়। 'let' এবং 'const' ব্লক-স্কোপড এবং হোস্ট করা হয় তবে ঘোষণার আগে একটি 'টেম্পোরাল ডেড জোন'-এ থাকে। 'const' অবশ্যই ইনিশিয়ালাইজ করা উচিত এবং পুনরায় অ্যাসাইন করা যাবে না।

function scopeTest() {   var a = 1;   let b = 2;   const c = 3;   if (true) {     var a = 10; // Re-declares and affects outer 'a'     let b = 20; // New 'b' within block     // const c = 30; // Would be a new 'c'     console.log(a, b, c); // 10, 20, 3   }   console.log(a, b, c); // 10, 2, 3 } scopeTest();

একটি প্রতিশ্রুতি কী?

জাভাস্ক্রিপ্টে একটি প্রতিশ্রুতি কী তা ব্যাখ্যা করুন।

ব্যাখ্যা: একটি প্রতিশ্রুতি হল একটি অবজেক্ট যা একটি অ্যাসিঙ্ক্রোনাস অপারেশনের চূড়ান্ত সমাপ্তি (বা ব্যর্থতা) এবং এর ফলে প্রাপ্ত মানকে উপস্থাপন করে। এটি তিনটি অবস্থার মধ্যে একটিতে থাকতে পারে: মুলতুবি, পূর্ণ বা প্রত্যাখ্যাত।

const myPromise = new Promise((resolve, reject) => {   setTimeout(() => {     resolve('Success!');     // reject('Error!');   }, 1000); }); myPromise   .then(result => console.log(result))   .catch(error => console.error(error));

'async/await' ব্যবহার করা

'async' এবং 'await' কীভাবে প্রতিশ্রুতির সাথে কাজ করাকে সহজ করে?

ব্যাখ্যা: 'async/await' প্রতিশ্রুতির উপর সিনট্যাক্টিক সুগার প্রদান করে, অ্যাসিঙ্ক্রোনাস কোডকে সিনক্রোনাস কোডের মতো দেখতে এবং আচরণ করতে সাহায্য করে। একটি 'async' ফাংশন সর্বদা একটি প্রতিশ্রুতি প্রদান করে এবং 'await' একটি প্রতিশ্রুতি নিষ্পত্তি না হওয়া পর্যন্ত এক্সিকিউশনকে বিরতি দেয়।

function delay(ms) {   return new Promise(resolve => setTimeout(resolve, ms)); } async function run() {   console.log('Starting...');   await delay(1000);   console.log('Waited 1 second.');   await delay(500);   console.log('Waited another 0.5 seconds.');   return 'Finished!'; } run().then(console.log);

স্ট্রিংকে সংখ্যায় রূপান্তর করুন

একটি স্ট্রিংকে কিভাবে একটি সংখ্যায় রূপান্তর করবেন?

ব্যাখ্যা: 'parseInt()', 'parseFloat()', বা একাকী প্লাস অপারেটর ('+') ব্যবহার করুন।

const str = '123.45'; console.log(parseInt(str)); // 123 console.log(parseFloat(str)); // 123.45 console.log(+str); // 123.45

সংখ্যাকে স্ট্রিংয়ে রূপান্তর করুন

একটি সংখ্যাকে কিভাবে একটি স্ট্রিংয়ে রূপান্তর করবেন?

ব্যাখ্যা: 'String()', 'number.toString()', বা স্ট্রিং কনক্যাটেনেশন ব্যবহার করুন।

const num = 123; console.log(String(num)); // '123' console.log(num.toString()); // '123' console.log('' + num); // '123'

'JSON.stringify' কী?

'JSON.stringify' কী করে?

ব্যাখ্যা: এটি একটি জাভাস্ক্রিপ্ট অবজেক্ট বা মানকে একটি JSON স্ট্রিংয়ে রূপান্তরিত করে।

const obj = { name: 'Alice', age: 30 }; const jsonString = JSON.stringify(obj); console.log(jsonString); // '{"name":"Alice","age":30}'

'JSON.parse' কী?

'JSON.parse' কী করে?

ব্যাখ্যা: এটি একটি JSON স্ট্রিং পার্স করে, স্ট্রিং দ্বারা বর্ণিত জাভাস্ক্রিপ্ট মান বা অবজেক্ট তৈরি করে।

const jsonString = '{"name":"Alice","age":30}'; const obj = JSON.parse(jsonString); console.log(obj.name); // 'Alice'

অ্যারেতে স্প্রেড অপারেটর

অ্যারেগুলির সাথে স্প্রেড অপারেটর কিভাবে ব্যবহার করা হয়?

ব্যাখ্যা: এটি একটি ইটারেবল (যেমন একটি অ্যারে) প্রসারিত করার অনুমতি দেয় যেখানে শূন্য বা তার বেশি আর্গুমেন্ট বা উপাদান প্রত্যাশিত। অনুলিপি করা, মার্জ করা এবং উপাদান যোগ করার জন্য দরকারী।

const arr1 = [1, 2]; const arr2 = [3, 4]; const combined = [...arr1, ...arr2]; // [1, 2, 3, 4] const copy = [...arr1]; // [1, 2]

অবজেক্টে স্প্রেড অপারেটর

অবজেক্টগুলির সাথে স্প্রেড অপারেটর কিভাবে ব্যবহার করা হয়?

ব্যাখ্যা: এটি অবজেক্ট বৈশিষ্ট্যগুলি অনুলিপি এবং মার্জ করার অনুমতি দেয়।

const obj1 = { a: 1, b: 2 }; const obj2 = { b: 3, c: 4 }; const merged = { ...obj1, ...obj2 }; // { a: 1, b: 3, c: 4 } const copy = { ...obj1 }; // { a: 1, b: 2 }

অ্যারে ডিস্ট্রাকচারিং

একটি উদাহরণ সহ অ্যারে ডিস্ট্রাকচারিং ব্যাখ্যা করুন।

ব্যাখ্যা: এটি একটি সিনট্যাক্স যা অ্যারে থেকে মানগুলিকে স্বতন্ত্র ভেরিয়েবলগুলিতে আনপ্যাক করা সম্ভব করে তোলে।

const [a, b] = [10, 20]; console.log(a); // 10 console.log(b); // 20 const [x, , z] = [1, 2, 3]; console.log(z); // 3

অবজেক্ট ডিস্ট্রাকচারিং

একটি উদাহরণ সহ অবজেক্ট ডিস্ট্রাকচারিং ব্যাখ্যা করুন।

ব্যাখ্যা: এটি অবজেক্ট থেকে বৈশিষ্ট্যগুলিকে স্বতন্ত্র ভেরিয়েবলগুলিতে আনপ্যাক করা সম্ভব করে তোলে।

const person = { name: 'Bob', age: 25 }; const { name, age } = person; console.log(name); // 'Bob' console.log(age); // 25 const { name: personName } = person; console.log(personName); // 'Bob'

'call' প্রয়োগ করুন

'Function.prototype.call' এর একটি মৌলিক সংস্করণ কিভাবে প্রয়োগ করবেন?

ব্যাখ্যা: 'call' একটি নির্দিষ্ট 'this' মান এবং স্বতন্ত্রভাবে প্রদত্ত আর্গুমেন্ট সহ একটি ফাংশন আহ্বান করে। আপনি ফাংশনটিকে 'this' কনটেক্সটে সংযুক্ত করতে পারেন, এটিকে কল করতে পারেন এবং তারপর এটিকে সরিয়ে দিতে পারেন।

Function.prototype.myCall = function(context, ...args) {   context = context || window;   const uniqueId = Symbol(); // Use a unique key   context[uniqueId] = this;   const result = context[uniqueId](...args);   delete context[uniqueId];   return result; } function greet(greeting, punctuation) {   console.log(`${greeting}, ${this.name}${punctuation}`); } greet.myCall({ name: 'Charlie' }, 'Hi', '!'); // Hi, Charlie!

'apply' প্রয়োগ করুন

'Function.prototype.apply' এর একটি মৌলিক সংস্করণ কিভাবে প্রয়োগ করবেন?

ব্যাখ্যা: 'apply' 'call' এর অনুরূপ, তবে এটি একটি অ্যারে হিসাবে আর্গুমেন্ট গ্রহণ করে।

Function.prototype.myApply = function(context, argsArray) {   context = context || window;   const uniqueId = Symbol();   context[uniqueId] = this;   const result = context[uniqueId](...(argsArray || []));   delete context[uniqueId];   return result; } function greet(greeting, punctuation) {   console.log(`${greeting}, ${this.name}${punctuation}`); } greet.myApply({ name: 'David' }, ['Hello', '.']); // Hello, David.

ইভেন্ট লুপ ব্যাখ্যা করুন

জাভাস্ক্রিপ্ট ইভেন্ট লুপ সংক্ষেপে ব্যাখ্যা করুন।

ব্যাখ্যা: জাভাস্ক্রিপ্ট একক-থ্রেডেড, কিন্তু এটি একটি ইভেন্ট লুপ ব্যবহার করে সমান্তরালতা অর্জন করে। কল স্ট্যাক সিঙ্ক্রোনাস কোড পরিচালনা করে। ওয়েব API গুলি অ্যাসিঙ্ক্রোনাস অপারেশন (যেমন setTimeout, fetch) পরিচালনা করে। যখন একটি অ্যাসিঙ্ক্রোনাস অপারেশন শেষ হয়, তখন তার কলব্যাক কলব্যাক কিউতে (অথবা প্রমিজের জন্য মাইক্রোটাস্ক কিউতে) যায়। ইভেন্ট লুপ ক্রমাগত পরীক্ষা করে দেখে যে কল স্ট্যাক খালি আছে কিনা; যদি থাকে, তাহলে এটি কিউ থেকে পরবর্তী কলব্যাককে এক্সিকিউশনের জন্য স্ট্যাকের দিকে নিয়ে যায়।

console.log('Start'); setTimeout(() => { console.log('Timeout Callback'); // কলব্যাক কিউতে যায় }, 0); Promise.resolve().then(() => { console.log('Promise Resolved'); // মাইক্রোটাস্ক কিউতে যায় }); console.log('End'); // আউটপুট অর্ডার: Start, End, Promise Resolved, Timeout Callback // (মাইক্রোটাস্কগুলি ম্যাক্রোটাস্ক/কলব্যাকগুলির আগে চলে)

বাইনারি সার্চ

একটি সাজানো অ্যারের জন্য একটি বাইনারি সার্চ ফাংশন প্রয়োগ করুন।

ব্যাখ্যা: বাইনারি সার্চ একটি সাজানো অ্যারেতে একটি আইটেমকে দক্ষতার সাথে খুঁজে বের করে সার্চ ইন্টারভালকে বারবার অর্ধেক করে ভাগ করে। যদি সার্চ কী এর মান ইন্টারভালের মাঝখানে থাকা আইটেমের চেয়ে কম হয়, তাহলে ইন্টারভালকে নিচের অর্ধেকের দিকে সংকুচিত করুন। অন্যথায়, এটিকে উপরের অর্ধেকের দিকে সংকুচিত করুন। আপনি এটি ততক্ষণ পর্যন্ত করেন যতক্ষণ না মানটি পাওয়া যায় বা ইন্টারভালটি খালি হয়।

function binarySearch(sortedArray, key) { let start = 0; let end = sortedArray.length - 1; while (start <= end) { let middle = Math.floor((start + end) / 2); if (sortedArray[middle] === key) { return middle; // পাওয়া গেছে } else if (sortedArray[middle] < key) { start = middle + 1; // ডান অর্ধেক অনুসন্ধান করুন } else { end = middle - 1; // বাম অর্ধেক অনুসন্ধান করুন } } return -1; // পাওয়া যায়নি } console.log(binarySearch([1, 3, 5, 7, 9, 11], 7)); // 3 console.log(binarySearch([1, 3, 5, 7, 9, 11], 2)); // -1

মার্জ সর্ট

মার্জ সর্ট অ্যালগরিদম প্রয়োগ করুন।

ব্যাখ্যা: মার্জ সর্ট একটি ডিভাইড-অ্যান্ড-কনকার অ্যালগরিদম। এটি ইনপুট অ্যারেটিকে দুটি অর্ধে বিভক্ত করে, দুটি অর্ধেকের জন্য নিজেকে কল করে এবং তারপর দুটি সাজানো অর্ধেককে মার্জ করে। মার্জ ফাংশনটি অত্যন্ত গুরুত্বপূর্ণ; এটি দুটি সাজানো সাব-অ্যারেগুলিকে একটি সাজানো অ্যারেতে একত্রিত করে।

function mergeSort(arr) { if (arr.length <= 1) return arr; const mid = Math.floor(arr.length / 2); const left = mergeSort(arr.slice(0, mid)); const right = mergeSort(arr.slice(mid)); return merge(left, right); } function merge(left, right) { let result = []; let leftIndex = 0; let rightIndex = 0; while (leftIndex < left.length && rightIndex < right.length) { if (left[leftIndex] < right[rightIndex]) { result.push(left[leftIndex]); leftIndex++; } else { result.push(right[rightIndex]); rightIndex++; } } return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex)); } console.log(mergeSort([38, 27, 43, 3, 9, 82, 10])); // [3, 9, 10, 27, 38, 43, 82]

কুইক সর্ট

কুইক সর্ট অ্যালগরিদম প্রয়োগ করুন।

ব্যাখ্যা: কুইক সর্টও একটি ডিভাইড-অ্যান্ড-কনকার অ্যালগরিদম। এটি একটি এলিমেন্টকে পিভট হিসাবে নির্বাচন করে এবং প্রদত্ত অ্যারেটিকে নির্বাচিত পিভটের চারপাশে পার্টিশন করে। পিভটের চেয়ে ছোট উপাদানগুলি বাম দিকে যায় এবং বড় উপাদানগুলি ডান দিকে যায়। তারপর এটি সাব-অ্যারেগুলিকে রিকার্সিভলি সর্ট করে।

function quickSort(arr) { if (arr.length <= 1) return arr; const pivot = arr[arr.length - 1]; const left = []; const right = []; for (let i = 0; i < arr.length - 1; i++) { if (arr[i] < pivot) { left.push(arr[i]); } else { right.push(arr[i]); } } return [...quickSort(left), pivot, ...quickSort(right)]; } console.log(quickSort([10, 8, 2, 1, 6, 3, 9, 4, 7, 5])); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

বাবল সর্ট

বাবল সর্ট অ্যালগরিদম প্রয়োগ করুন।

ব্যাখ্যা: বাবল সর্ট একটি সরল সর্টিং অ্যালগরিদম যা বারবার তালিকার মধ্য দিয়ে যায়, সংলগ্ন উপাদানগুলির তুলনা করে এবং যদি তারা ভুল ক্রমে থাকে তবে তাদের অদলবদল করে। তালিকাটি সাজানো না হওয়া পর্যন্ত তালিকার মধ্য দিয়ে যাওয়া পুনরাবৃত্তি করা হয়।

function bubbleSort(arr) { let n = arr.length; let swapped; do { swapped = false; for (let i = 0; i < n - 1; i++) { if (arr[i] > arr[i + 1]) { [arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]; // অদলবদল swapped = true; } } n--; // অপ্টিমাইজেশন: শেষ উপাদান ইতিমধ্যেই সঠিক স্থানে আছে } while (swapped); return arr; } console.log(bubbleSort([64, 34, 25, 12, 22, 11, 90])); // [11, 12, 22, 25, 34, 64, 90]

পুনরাবৃত্তি অক্ষর ছাড়া দীর্ঘতম সাবস্ট্রিং

একটি স্ট্রিং দেওয়া হলে, পুনরাবৃত্তি অক্ষর ছাড়া দীর্ঘতম সাবস্ট্রিংয়ের দৈর্ঘ্য খুঁজুন।

ব্যাখ্যা: স্লাইডিং উইন্ডো কৌশল ব্যবহার করুন। একটি উইন্ডো (সাবস্ট্রিং) এবং সেই উইন্ডোতে অক্ষরগুলির একটি সেট বজায় রাখুন। ডান পয়েন্টারটি সরিয়ে উইন্ডোটি প্রসারিত করুন। যদি একটি পুনরাবৃত্তি অক্ষর পাওয়া যায়, পুনরাবৃত্তি অক্ষরটি সরানো না হওয়া পর্যন্ত বাম দিক থেকে উইন্ডোটি ছোট করুন।

function lengthOfLongestSubstring(s) { let maxLength = 0; let start = 0; const charMap = {}; for (let end = 0; end < s.length; end++) { const char = s[end]; if (charMap[char] >= start) { start = charMap[char] + 1; } charMap[char] = end; maxLength = Math.max(maxLength, end - start + 1); } return maxLength; } console.log(lengthOfLongestSubstring('abcabcbb')); // 3 ('abc') console.log(lengthOfLongestSubstring('bbbbb')); // 1 ('b') console.log(lengthOfLongestSubstring('pwwkew')); // 3 ('wke')

একটি লিঙ্কড লিস্ট প্রয়োগ করুন

add এবং print পদ্ধতি সহ একটি একক লিঙ্কড লিস্ট প্রয়োগ করুন।

ব্যাখ্যা: একটি লিঙ্কড লিস্ট হল একটি রৈখিক ডেটা স্ট্রাকচার যেখানে উপাদানগুলি সংলগ্ন মেমরি অবস্থানে সংরক্ষণ করা হয় না। প্রতিটি উপাদান (নোড) পরেরটিকে নির্দেশ করে। আপনার একটি নোড ক্লাস এবং একটি লিঙ্কডলিস্ট ক্লাস প্রয়োজন হেড পরিচালনা করতে এবং নতুন নোড যুক্ত করতে।

class Node { constructor(data, next = null) { this.data = data; this.next = next; } } class LinkedList { constructor() { this.head = null; } add(data) { const newNode = new Node(data); if (!this.head) { this.head = newNode; } else { let current = this.head; while (current.next) { current = current.next; } current.next = newNode; } } print() { let current = this.head; let list = ''; while (current) { list += current.data + ' -> '; current = current.next; } console.log(list + 'null'); } } const list = new LinkedList(); list.add(10); list.add(20); list.add(30); list.print(); // 10 -> 20 -> 30 -> null

একটি বাইনারি সার্চ ট্রি (BST) প্রয়োগ করুন

insert এবং find পদ্ধতি সহ একটি বাইনারি সার্চ ট্রি প্রয়োগ করুন।

ব্যাখ্যা: একটি BST হল একটি নোড-ভিত্তিক বাইনারি ট্রি ডেটা স্ট্রাকচার যার নিম্নলিখিত বৈশিষ্ট্যগুলি রয়েছে: একটি নোডের বাম সাবট্রিটিতে কেবল সেই নোডগুলি থাকে যাদের কী নোডের কী এর চেয়ে কম। একটি নোডের ডান সাবট্রিটিতে কেবল সেই নোডগুলি থাকে যাদের কী নোডের কী এর চেয়ে বেশি। উভয় সাবট্রি অবশ্যই বাইনারি সার্চ ট্রি হতে হবে।

class Node { constructor(data) { this.data = data; this.left = null; this.right = null; } } class BST { constructor() { this.root = null; } insert(data) { const newNode = new Node(data); if (!this.root) { this.root = newNode; return; } this._insertNode(this.root, newNode); } _insertNode(node, newNode) { if (newNode.data < node.data) { if (!node.left) node.left = newNode; else this._insertNode(node.left, newNode); } else { if (!node.right) node.right = newNode; else this._insertNode(node.right, newNode); } } find(data) { return this._findNode(this.root, data); } _findNode(node, data) { if (!node) return null; if (data < node.data) return this._findNode(node.left, data); else if (data > node.data) return this._findNode(node.right, data); else return node; } } const bst = new BST(); bst.insert(10); bst.insert(5); bst.insert(15); bst.insert(7); console.log(bst.find(7)); // Node { data: 7, left: null, right: null } console.log(bst.find(12)); // null

একটি অ্যারে ঘোরান

একটি অ্যারে ডানদিকে k ধাপ ঘোরানোর জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: একটি অ্যারে ঘোরানোর অর্থ হল তার উপাদানগুলিকে স্থানান্তরিত করা। ডান ঘূর্ণনের জন্য, শেষ উপাদানটি প্রথম হয়। k বার এটি পুনরাবৃত্তি করলে কাজ করে কিন্তু অদক্ষ। একটি ভালো উপায় হল অ্যারে ম্যানিপুলেশন ব্যবহার করা বা নতুন অবস্থানগুলি গণনা করা।

function rotateArray(nums, k) { k = k % nums.length; // k > দৈর্ঘ্যের ক্ষেত্রে হ্যান্ডেল করুন if (k === 0) return nums; const partToMove = nums.splice(nums.length - k); nums.unshift(...partToMove); return nums; } console.log(rotateArray([1, 2, 3, 4, 5, 6, 7], 3)); // [5, 6, 7, 1, 2, 3, 4]

দুটি অ্যারের ছেদ খুঁজুন

দুটি অ্যারে দেওয়া হলে, তাদের ছেদ (উভয় ক্ষেত্রে সাধারণ উপাদান) গণনা করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: একটি ভালো পদ্ধতি হল একটি অ্যারেটিকে O(1) গড় সময় লুকআপের জন্য একটি সেট-এ রূপান্তর করা। তারপর, দ্বিতীয় অ্যারেটির মধ্য দিয়ে পুনরাবৃত্তি করুন এবং প্রতিটি উপাদান সেটে বিদ্যমান কিনা তা পরীক্ষা করুন। মিলগুলি সংগ্রহ করুন।

function intersection(nums1, nums2) { const set1 = new Set(nums1); const resultSet = new Set(); for (const num of nums2) { if (set1.has(num)) { resultSet.add(num); } } return [...resultSet]; } console.log(intersection([1, 2, 2, 1], [2, 2])); // [2] console.log(intersection([4, 9, 5], [9, 4, 9, 8, 4])); // [9, 4]

অ্যানাগ্রামগুলি গ্রুপ করুন

স্ট্রিংগুলির একটি অ্যারে দেওয়া হলে, অ্যানাগ্রামগুলি একসাথে গ্রুপ করুন।

ব্যাখ্যা: প্রতিটি অ্যানাগ্রাম গ্রুপের জন্য একটি অনন্য স্বাক্ষর খুঁজে বের করাই মূল বিষয়। একটি সাধারণ উপায় হল প্রতিটি শব্দকে বর্ণানুক্রমিকভাবে সাজানো। যে শব্দগুলির একই সাজানো স্ট্রিং হয় সেগুলি অ্যানাগ্রাম। একটি হ্যাশ ম্যাপ ব্যবহার করুন যেখানে কীগুলি সাজানো শব্দ এবং মানগুলি হল মূল শব্দগুলির অ্যারে।

function groupAnagrams(strs) { const map = {}; for (const str of strs) { const sortedStr = str.split('').sort().join(''); if (!map[sortedStr]) { map[sortedStr] = []; } map[sortedStr].push(str); } return Object.values(map); } console.log(groupAnagrams(['eat', 'tea', 'tan', 'ate', 'nat', 'bat'])); // আউটপুট: [['eat', 'tea', 'ate'], ['tan', 'nat'], ['bat']]

শূন্যকে শেষে নিয়ে যান

একটি অ্যারে nums দেওয়া হলে, নন-জিরো উপাদানগুলির আপেক্ষিক ক্রম বজায় রেখে সমস্ত 0 কে শেষে নিয়ে যাওয়ার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: একটি 'টু-পয়েন্টার' বা 'স্নোবল' পদ্ধতি ব্যবহার করুন। একটি পয়েন্টার পরবর্তী নন-জিরো উপাদানটি কোথায় যাবে তার অবস্থান ট্র্যাক রাখে। অ্যারেটির মধ্য দিয়ে পুনরাবৃত্তি করুন; যদি একটি উপাদান নন-জিরো হয়, তবে এটিকে পয়েন্টারের অবস্থানে রাখুন এবং পয়েন্টারটি বাড়ান। অবশেষে, বাকি স্থানগুলি শূন্য দিয়ে পূরণ করুন।

function moveZeroes(nums) { let nonZeroIndex = 0; // সমস্ত নন-জিরো উপাদান সামনে নিয়ে যান for (let i = 0; i < nums.length; i++) { if (nums[i] !== 0) { nums[nonZeroIndex] = nums[i]; nonZeroIndex++; } } // বাকি স্থানগুলি শূন্য দিয়ে পূরণ করুন for (let i = nonZeroIndex; i < nums.length; i++) { nums[i] = 0; } return nums; } console.log(moveZeroes([0, 1, 0, 3, 12])); // [1, 3, 12, 0, 0]

সর্বোচ্চ সাবঅ্যারে (ক্যাডানের অ্যালগরিদম)

একটি ইন্টিজার অ্যারে nums দেওয়া হলে, সংযুক্ত সাবঅ্যারে (কমপক্ষে একটি সংখ্যা ধারণকারী) খুঁজুন যার যোগফল সবচেয়ে বড় এবং তার যোগফল ফেরত দিন।

ব্যাখ্যা: ক্যাডানের অ্যালগরিদম এটি সমাধান করার একটি দক্ষ উপায়। অ্যারেটির মধ্য দিয়ে পুনরাবৃত্তি করুন, বর্তমান অবস্থানে শেষ হওয়া currentMax যোগফল এবং এখন পর্যন্ত পাওয়া globalMax যোগফল ট্র্যাক করুন। যদি currentMax ঋণাত্মক হয়ে যায়, তবে এটিকে 0 তে রিসেট করুন (বা বরং, বর্তমান উপাদান)।

function maxSubArray(nums) { let globalMax = -Infinity; let currentMax = 0; for (let i = 0; i < nums.length; i++) { currentMax = Math.max(nums[i], currentMax + nums[i]); if (currentMax > globalMax) { globalMax = currentMax; } } return globalMax; } console.log(maxSubArray([-2, 1, -3, 4, -1, 2, 1, -5, 4])); // 6 ([4, -1, 2, 1] থেকে)

একটি স্ট্রিং এর পারমুটেশন

একটি প্রদত্ত স্ট্রিং এর সমস্ত পারমুটেশন তৈরি করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: এটি সাধারণত রিকার্সন এবং ব্যাকট্র্যাকিং ব্যবহার করে সমাধান করা হয়। প্রতিটি অক্ষরের জন্য, এটিকে স্থির করুন এবং স্ট্রিং এর বাকি অংশের জন্য রিকার্সিভলি পারমুটেশন তৈরি করুন। বেস কেস: যখন স্ট্রিং এ শুধুমাত্র একটি অক্ষর থাকে, তখন সেটি ফেরত দিন।

function stringPermutations(str) { if (str.length === 0) return ['']; if (str.length === 1) return [str]; const results = []; for (let i = 0; i < str.length; i++) { const char = str[i]; const remainingChars = str.slice(0, i) + str.slice(i + 1); const perms = stringPermutations(remainingChars); for (const perm of perms) { results.push(char + perm); } } return [...new Set(results)]; // প্রয়োজনে নকল অক্ষর হ্যান্ডেল করতে সেট ব্যবহার করুন } console.log(stringPermutations('abc')); // ['abc', 'acb', 'bac', 'bca', 'cab', 'cba'] console.log(stringPermutations('aab')); // ['aab', 'aba', 'baa']

সর্বোচ্চ সাধারণ গুণনীয়ক (GCD)

দুটি সংখ্যার সর্বোচ্চ সাধারণ গুণনীয়ক (GCD) খুঁজে বের করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: ইউক্লিডীয় অ্যালগরিদম একটি কার্যকর পদ্ধতি। যদি b 0 হয়, তাহলে a হল GCD। অন্যথায়, a এবং b এর GCD হল b এবং a % b (a কে b দ্বারা ভাগ করার পর অবশিষ্ট) এর GCD এর সমান।

function gcd(a, b) { while (b !== 0) { let temp = b; b = a % b; a = temp; } return a; } console.log(gcd(48, 18)); // 6 console.log(gcd(101, 103)); // 1

সর্বনিম্ন সাধারণ গুণিতক (LCM)

দুটি সংখ্যার সর্বনিম্ন সাধারণ গুণিতক (LCM) খুঁজে বের করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: LCM GCD ব্যবহার করে নিম্নলিখিত সূত্র দ্বারা গণনা করা যেতে পারে: LCM(a, b) = |a * b| / GCD(a, b)।

function gcd(a, b) { // পূর্ববর্তী সমস্যা থেকে সাহায্যকারী while (b !== 0) { let temp = b; b = a % b; a = temp; } return a; } function lcm(a, b) { if (a === 0 || b === 0) return 0; return Math.abs(a * b) / gcd(a, b); } console.log(lcm(15, 20)); // 60 console.log(lcm(7, 5)); // 35

প্রমিস ডট অল (Promise.all) প্রয়োগ করুন

Promise.all এর মতো আচরণ করে এমন একটি ফাংশন প্রয়োগ করুন।

ব্যাখ্যা: Promise.all প্রমিসগুলির একটি অ্যারে নেয় এবং একটি একক প্রমিস প্রদান করে যা সমস্ত ইনপুট প্রমিস সফলভাবে সমাধান হলে সমাধান হয়, অথবা যদি কোনও ইনপুট প্রমিস ব্যর্থ হয় তবে প্রত্যাখ্যান হয়। সমাধান করা মানগুলি হল সমাধান করা মানগুলির একটি অ্যারে।

function myPromiseAll(promises) { return new Promise((resolve, reject) => { const results = []; let completedCount = 0; const numPromises = promises.length; if (numPromises === 0) { resolve([]); return; } promises.forEach((promise, index) => { Promise.resolve(promise) .then(value => { results[index] = value; completedCount++; if (completedCount === numPromises) { resolve(results); } }) .catch(reject); // যেকোনো ত্রুটিতে অবিলম্বে প্রত্যাখ্যান করুন }); }); } // উদাহরণ ব্যবহার: const p1 = Promise.resolve(3); const p2 = 42; const p3 = new Promise((resolve) => setTimeout(resolve, 100, 'foo')); myPromiseAll([p1, p2, p3]).then(values => console.log(values)); // [3, 42, 'foo']

বাইনারি ট্রি উল্টান

একটি বাইনারি ট্রি উল্টানোর জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: একটি বাইনারি ট্রি উল্টানোর জন্য, আপনাকে প্রতিটি নোডের বাম এবং ডান চিলড্রেন অদলবদল করতে হবে। এটি রিকার্সিভলি বা ইটারেটিভলি (একটি কিউ বা স্ট্যাক ব্যবহার করে) করা যেতে পারে।

class Node { constructor(val, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } function invertTree(root) { if (root === null) { return null; } // চিলড্রেন অদলবদল করুন [root.left, root.right] = [root.right, root.left]; // বাম এবং ডান চিলড্রেনদের জন্য রিকার্স করুন invertTree(root.left); invertTree(root.right); return root; } // উদাহরণ: 4 -> [2, 7] -> [1, 3, 6, 9] // হয়ে যায়: 4 -> [7, 2] -> [9, 6, 3, 1]

বাইনারি ট্রির সর্বোচ্চ গভীরতা

একটি বাইনারি ট্রি দেওয়া হলে, তার সর্বোচ্চ গভীরতা খুঁজুন।

ব্যাখ্যা: সর্বোচ্চ গভীরতা হল রুট নোড থেকে সবচেয়ে দূরের লিফ নোড পর্যন্ত দীর্ঘতম পথের নোডের সংখ্যা। এটি রিকার্সিভলি খুঁজে পাওয়া যেতে পারে: MaxDepth = 1 + max(MaxDepth(বাম), MaxDepth(ডান))। বেস কেস হল যখন একটি নোড নাল হয়, তার গভীরতা 0 হয়।

class Node { constructor(val, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } function maxDepth(root) { if (root === null) { return 0; } const leftDepth = maxDepth(root.left); const rightDepth = maxDepth(root.right); return Math.max(leftDepth, rightDepth) + 1; } // উদাহরণ: 3 -> [9, 20] -> [null, null, 15, 7] const tree = new Node(3, new Node(9), new Node(20, new Node(15), new Node(7))); console.log(maxDepth(tree)); // 3

স্টক কেনা/বেচার সেরা সময়

আপনাকে একটি অ্যারে prices দেওয়া হয়েছে যেখানে prices[i] হল i তম দিনে একটি নির্দিষ্ট স্টকের মূল্য। আপনি একটি স্টক কেনার জন্য একটি একক দিন নির্বাচন করে এবং ভবিষ্যতে সেই স্টকটি বিক্রি করার জন্য একটি ভিন্ন দিন নির্বাচন করে আপনার লাভ সর্বাধিক করতে চান। সর্বাধিক লাভ ফেরত দিন।

ব্যাখ্যা: দামের মধ্য দিয়ে পুনরাবৃত্তি করুন, এখন পর্যন্ত পাওয়া সর্বনিম্ন মূল্য (minPrice) এবং এখন পর্যন্ত পাওয়া সর্বাধিক লাভ (maxProfit) ট্র্যাক রাখুন। প্রতিটি দিনের জন্য, আজ বিক্রি করলে সম্ভাব্য লাভ (বর্তমান মূল্য - minPrice) গণনা করুন এবং যদি এটি বেশি হয় তবে maxProfit আপডেট করুন।

function maxProfit(prices) { let minPrice = Infinity; let maxProfit = 0; for (let i = 0; i < prices.length; i++) { if (prices[i] < minPrice) { minPrice = prices[i]; } else if (prices[i] - minPrice > maxProfit) { maxProfit = prices[i] - minPrice; } } return maxProfit; } console.log(maxProfit([7, 1, 5, 3, 6, 4])); // 5 (1 এ কিনুন, 6 এ বিক্রি করুন) console.log(maxProfit([7, 6, 4, 3, 1])); // 0 (কোন লাভ সম্ভব নয়)

একক সংখ্যা

অপূর্ণ সংখ্যার একটি অ্যারে nums দেওয়া হলে, প্রতিটি উপাদান দুবার উপস্থিত হয় একটি ব্যতীত। সেই একক সংখ্যাটি খুঁজুন।

ব্যাখ্যা: এটি সমাধানের একটি অত্যন্ত কার্যকর উপায় হল XOR বিটওয়াইজ অপারেটর (^) ব্যবহার করা। একটি সংখ্যাকে নিজের সাথে XOR করলে ফলাফল 0 হয়। একটি সংখ্যাকে 0 এর সাথে XOR করলে সেই সংখ্যাটি নিজেই হয়। যদি আপনি অ্যারের সমস্ত সংখ্যাকে XOR করেন, তাহলে জোড়াগুলি বাতিল হয়ে যাবে (0 হয়ে যাবে), শুধুমাত্র একক সংখ্যাটি বাকি থাকবে।

function singleNumber(nums) { let result = 0; for (const num of nums) { result ^= num; } return result; } console.log(singleNumber([2, 2, 1])); // 1 console.log(singleNumber([4, 1, 2, 1, 2])); // 4

মেজরিটি এলিমেন্ট

n আকারের একটি অ্যারে nums দেওয়া হলে, মেজরিটি এলিমেন্ট ফেরত দিন। মেজরিটি এলিমেন্ট হল সেই উপাদান যা ⌊n / 2⌋ বারের বেশি উপস্থিত হয়।

ব্যাখ্যা: বোয়র-মুর ভোটিং অ্যালগরিদম একটি কার্যকর উপায়। একটি candidate এবং একটি count শুরু করুন। অ্যারেটির মধ্য দিয়ে পুনরাবৃত্তি করুন। যদি count 0 হয়, তবে বর্তমান উপাদানটিকে candidate হিসাবে সেট করুন। যদি বর্তমান উপাদান candidate এর সাথে মিলে যায়, তবে count বাড়ান; অন্যথায়, count কমান।

function majorityElement(nums) { let candidate = null; let count = 0; for (const num of nums) { if (count === 0) { candidate = num; } count += (num === candidate) ? 1 : -1; } return candidate; } console.log(majorityElement([3, 2, 3])); // 3 console.log(majorityElement([2, 2, 1, 1, 1, 2, 2])); // 2

সিঁড়ি বেয়ে ওঠা

আপনি একটি সিঁড়ি বেয়ে উঠছেন। শীর্ষে পৌঁছতে n ধাপ লাগে। প্রতিবার আপনি 1 বা 2 ধাপ উঠতে পারেন। আপনি কতটি ভিন্ন উপায়ে শীর্ষে উঠতে পারেন?

ব্যাখ্যা: এটি একটি ক্লাসিক ডাইনামিক প্রোগ্রামিং সমস্যা, যা ফিবোনাচ্চি অনুক্রমের সাথে খুব মিল। n ধাপে পৌঁছানোর উপায়গুলির সংখ্যা হল n-1 ধাপে পৌঁছানোর উপায়গুলির যোগফল (1 ধাপ নিয়ে) এবং n-2 ধাপে পৌঁছানোর উপায়গুলির যোগফল (2 ধাপ নিয়ে)। dp[n] = dp[n-1] + dp[n-2]

function climbStairs(n) { if (n <= 2) return n; let oneStepBefore = 2; let twoStepsBefore = 1; let allWays = 0; for (let i = 3; i <= n; i++) { allWays = oneStepBefore + twoStepsBefore; twoStepsBefore = oneStepBefore; oneStepBefore = allWays; } return allWays; } console.log(climbStairs(2)); // 2 (1+1, 2) console.log(climbStairs(3)); // 3 (1+1+1, 1+2, 2+1) console.log(climbStairs(4)); // 5

নিজেকে ব্যতীত অ্যারের পণ্য

একটি পূর্ণসংখ্যার অ্যারে nums দেওয়া হলে, একটি অ্যারে answer ফেরত দিন যেখানে answer[i] হবে nums[i] ব্যতীত nums এর সমস্ত উপাদানের গুণফল। ভাগ অপারেটর ব্যবহার করবেন না।

ব্যাখ্যা: আপনি এটি প্রিফিক্স পণ্য এবং সাফিক্স পণ্য গণনা করে সমাধান করতে পারেন। সূচক i এ ফলাফল হল i এর আগের সমস্ত উপাদানগুলির গুণফল এবং i এর পরের সমস্ত উপাদানগুলির গুণফল।

function productExceptSelf(nums) { const n = nums.length; const answer = new Array(n).fill(1); // প্রিফিক্স পণ্য গণনা করুন let prefix = 1; for (let i = 0; i < n; i++) { answer[i] = prefix; prefix *= nums[i]; } // সাফিক্স পণ্য গণনা করুন এবং প্রিফিক্স দিয়ে গুণ করুন let suffix = 1; for (let i = n - 1; i >= 0; i--) { answer[i] *= suffix; suffix *= nums[i]; } return answer; } console.log(productExceptSelf([1, 2, 3, 4])); // [24, 12, 8, 6]

দ্বীপের সংখ্যা

1s (ভূমি) এবং 0s (জল) এর একটি 2D গ্রিড ম্যাপ দেওয়া হলে, দ্বীপের সংখ্যা গণনা করুন। একটি দ্বীপ জল দ্বারা বেষ্টিত এবং সংলগ্ন ভূমিগুলিকে অনুভূমিকভাবে বা উল্লম্বভাবে সংযুক্ত করে গঠিত হয়।

ব্যাখ্যা: গ্রিডের প্রতিটি কোষের মধ্য দিয়ে পুনরাবৃত্তি করুন। যদি আপনি একটি 1 (ভূমি) খুঁজে পান, দ্বীপের সংখ্যা বাড়ান এবং সেই কোষ থেকে ডেপথ ফার্স্ট সার্চ (DFS) বা ব্রেডথ ফার্স্ট সার্চ (BFS) শুরু করুন। অনুসন্ধানের সময়, সমস্ত সংযুক্ত 1s কে 0 (বা ভিজিট করা হয়েছে) হিসাবে চিহ্নিত করুন যাতে সেগুলিকে আবার গণনা করা এড়ানো যায়।

function numIslands(grid) { if (!grid || grid.length === 0) return 0; let count = 0; const rows = grid.length; const cols = grid[0].length; function dfs(r, c) { if (r < 0 || c < 0 || r >= rows || c >= cols || grid[r][c] === '0') { return; } grid[r][c] = '0'; // ভিজিট করা হিসাবে চিহ্নিত করুন dfs(r + 1, c); dfs(r - 1, c); dfs(r, c + 1); dfs(r, c - 1); } for (let r = 0; r < rows; r++) { for (let c = 0; c < cols; c++) { if (grid[r][c] === '1') { count++; dfs(r, c); } } } return count; } const grid1 = [ ['1', '1', '1', '1', '0'], ['1', '1', '0', '1', '0'], ['1', '1', '0', '0', '0'], ['0', '0', '0', '0', '0'] ]; // console.log(numIslands(grid1)); // 1 (একটি কপি বা গ্রিড পুনরুদ্ধার করতে হবে)

LRU ক্যাশে

সর্বনিম্ন সম্প্রতি ব্যবহৃত (LRU) ক্যাশের জন্য একটি ডেটা স্ট্রাকচার ডিজাইন এবং প্রয়োগ করুন। এটি get এবং put অপারেশন সমর্থন করবে।

ব্যাখ্যা: একটি LRU ক্যাশে ক্ষমতা পৌঁছালে সর্বনিম্ন সম্প্রতি ব্যবহৃত আইটেমটি বাতিল করে। একটি সাধারণ প্রয়োগে O(1) লুকআপের জন্য একটি Map (বা একটি হ্যাশ ম্যাপ) এবং 'সম্প্রতি ব্যবহৃত' স্ট্যাটাসের O(1) আপডেটের জন্য একটি দ্বিগুণ লিঙ্কড লিস্ট ব্যবহার করা হয়। জাভাস্ক্রিপ্টের Map সন্নিবেশ ক্রম বজায় রাখে, যা একটি মৌলিক প্রয়োগকে সহজ করতে পারে।

class LRUCache { constructor(capacity) { this.capacity = capacity; this.cache = new Map(); } get(key) { if (!this.cache.has(key)) return -1; const value = this.cache.get(key); this.cache.delete(key); // পুনরায় সন্নিবেশ করতে 'শেষ' (সবচেয়ে সাম্প্রতিক) থেকে সরান this.cache.set(key, value); return value; } put(key, value) { if (this.cache.has(key)) { this.cache.delete(key); } else if (this.cache.size >= this.capacity) { const oldestKey = this.cache.keys().next().value; this.cache.delete(oldestKey); } this.cache.set(key, value); } } const cache = new LRUCache(2); cache.put(1, 1); cache.put(2, 2); console.log(cache.get(1)); // 1 cache.put(3, 3); // 2 কে বাতিল করে console.log(cache.get(2)); // -1

বন্ধনী তৈরি করুন

n জোড়া বন্ধনী দেওয়া হলে, সুগঠিত বন্ধনীগুলির সমস্ত সমন্বয় তৈরি করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: এটি একটি ক্লাসিক ব্যাকট্র্যাকিং সমস্যা। খোলা এবং বন্ধ বন্ধনীর জন্য গণনা বজায় রাখুন। আপনি একটি খোলা বন্ধনী যোগ করতে পারেন যদি open < n হয়। আপনি একটি বন্ধ বন্ধনী যোগ করতে পারেন যদি close < open হয়। বেস কেস হল যখন স্ট্রিং এর দৈর্ঘ্য 2 * n এ পৌঁছায়।

function generateParenthesis(n) { const results = []; function backtrack(currentString, openCount, closeCount) { if (currentString.length === n * 2) { results.push(currentString); return; } if (openCount < n) { backtrack(currentString + '(', openCount + 1, closeCount); } if (closeCount < openCount) { backtrack(currentString + ')', openCount, closeCount + 1); } } backtrack('', 0, 0); return results; } console.log(generateParenthesis(3)); // ['((()))', '(()())', '(())()', '()(())', '()()()']

সর্বাধিক জল সহ ধারক

n টি অ-নেতিবাচক পূর্ণসংখ্যা a1, a2, ..., an দেওয়া হলে, যেখানে প্রতিটি (i, ai) স্থানাঙ্কে একটি বিন্দুকে উপস্থাপন করে। n টি উল্লম্ব রেখা আঁকা হয় যাতে লাইন i এর দুটি শেষবিন্দু (i, ai) এবং (i, 0) এ থাকে। দুটি রেখা খুঁজুন, যা x-অক্ষের সাথে একসাথে একটি ধারক গঠন করে, যাতে ধারকটিতে সর্বাধিক জল থাকে।

ব্যাখ্যা: টু-পয়েন্টার পদ্ধতি ব্যবহার করুন। একটি পয়েন্টার শুরুতে এবং একটি শেষে রাখুন। ক্ষেত্রফল গণনা করুন। ক্ষেত্রফল ছোট রেখা দ্বারা সীমিত। সম্ভবত একটি বড় ক্ষেত্রফল খুঁজে পেতে, ছোট রেখা নির্দেশকারী পয়েন্টারটিকে ভেতরের দিকে সরান।

function maxArea(height) { let max = 0; let left = 0; let right = height.length - 1; while (left < right) { const h = Math.min(height[left], height[right]); const w = right - left; max = Math.max(max, h * w); if (height[left] < height[right]) { left++; } else { right--; } } return max; } console.log(maxArea([1, 8, 6, 2, 5, 4, 8, 3, 7])); // 49

3সাম

n পূর্ণসংখ্যার একটি অ্যারে nums দেওয়া হলে, nums এ এমন উপাদান a, b, c আছে কি যাতে a + b + c = 0 হয়? অ্যারেতে শূন্যের যোগফল দেয় এমন সমস্ত অনন্য ট্রিপলেট খুঁজুন।

ব্যাখ্যা: প্রথমে, অ্যারেটি সাজান। তারপর, একটি পয়েন্টার i দিয়ে অ্যারেটির মধ্য দিয়ে পুনরাবৃত্তি করুন। প্রতিটি i এর জন্য, আরও দুটি পয়েন্টার, left (i+1 এ শুরু) এবং right (শেষে শুরু) ব্যবহার করুন, দুটি সংখ্যা খুঁজে বের করার জন্য যা -nums[i] এর যোগফল দেয়। অনন্য ট্রিপলেট নিশ্চিত করতে নকলগুলি হ্যান্ডেল করুন।

function threeSum(nums) { nums.sort((a, b) => a - b); const results = []; for (let i = 0; i < nums.length - 2; i++) { if (i > 0 && nums[i] === nums[i - 1]) continue; // i এর জন্য নকলগুলি এড়িয়ে যান let left = i + 1; let right = nums.length - 1; let target = -nums[i]; while (left < right) { let sum = nums[left] + nums[right]; if (sum === target) { results.push([nums[i], nums[left], nums[right]]); while (left < right && nums[left] === nums[left + 1]) left++; // নকলগুলি এড়িয়ে যান while (left < right && nums[right] === nums[right - 1]) right--; // নকলগুলি এড়িয়ে যান left++; right--; } else if (sum < target) { left++; } else { right--; } } } return results; } console.log(threeSum([-1, 0, 1, 2, -1, -4])); // [[-1, -1, 2], [-1, 0, 1]]

অনুসন্ধান সন্নিবেশ অবস্থান

ভিন্ন পূর্ণসংখ্যার একটি সাজানো অ্যারে এবং একটি টার্গেট মান দেওয়া হলে, যদি টার্গেটটি পাওয়া যায় তবে সূচকটি ফেরত দিন। যদি না পাওয়া যায়, তবে এটি যদি ক্রমানুসারে সন্নিবেশিত হয় তবে কোন সূচকে থাকত তা ফেরত দিন।

ব্যাখ্যা: এটি বাইনারি সার্চের একটি ভিন্নতা। বাইনারি সার্চ করুন, তবে যদি উপাদানটি পাওয়া না যায়, তাহলে start পয়েন্টারটি সেই অবস্থানে শেষ হবে যেখানে উপাদানটি সন্নিবেশিত হওয়া উচিত।

function searchInsert(nums, target) { let start = 0; let end = nums.length - 1; while (start <= end) { let mid = Math.floor((start + end) / 2); if (nums[mid] === target) { return mid; } else if (nums[mid] < target) { start = mid + 1; } else { end = mid - 1; } } return start; // যদি না পাওয়া যায়, start হল সন্নিবেশ বিন্দু } console.log(searchInsert([1, 3, 5, 6], 5)); // 2 console.log(searchInsert([1, 3, 5, 6], 2)); // 1 console.log(searchInsert([1, 3, 5, 6], 7)); // 4

দুটি সাজানো তালিকা মার্জ করুন (লিঙ্কড লিস্ট)

দুটি সাজানো লিঙ্কড লিস্ট মার্জ করুন এবং এটিকে একটি নতুন সাজানো তালিকা হিসাবে ফেরত দিন। নতুন তালিকাটি প্রথম দুটি তালিকার নোডগুলি একসাথে স্প্লাইস করে তৈরি করা উচিত।

ব্যাখ্যা: প্রক্রিয়াটিকে সহজ করার জন্য একটি ডামি হেড নোড ব্যবহার করুন। নতুন তালিকা তৈরি করতে একটি পয়েন্টার ব্যবহার করুন। উভয় ইনপুট তালিকার বর্তমান নোডগুলির তুলনা করুন এবং ছোটটিকে নতুন তালিকায় যুক্ত করুন, সেই তালিকার পয়েন্টারটি এগিয়ে নিন। একটি তালিকা নিঃশেষ না হওয়া পর্যন্ত পুনরাবৃত্তি করুন, তারপর অন্য তালিকার বাকি অংশ যুক্ত করুন।

class ListNode { constructor(val = 0, next = null) { this.val = val; this.next = next; } } function mergeTwoLists(l1, l2) { let dummyHead = new ListNode(); let current = dummyHead; while (l1 !== null && l2 !== null) { if (l1.val < l2.val) { current.next = l1; l1 = l1.next; } else { current.next = l2; l2 = l2.next; } current = current.next; } current.next = l1 !== null ? l1 : l2; return dummyHead.next; } // উদাহরণ: 1->2->4 এবং 1->3->4 => 1->1->2->3->4->4

প্রতিসম বৃক্ষ

একটি বাইনারি ট্রি দেওয়া হলে, এটি নিজের আয়না (যেমন, তার কেন্দ্রের চারপাশে প্রতিসম) কিনা তা পরীক্ষা করুন।

ব্যাখ্যা: এটি রিকার্সিভলি সমাধান করা যেতে পারে। একটি ট্রি প্রতিসম হয় যদি বাম সাবট্রি ডান সাবট্রির একটি আয়না ছবি হয়। দুটি ট্রি আয়না কিনা তা পরীক্ষা করার জন্য একটি সহায়ক ফাংশন isMirror(t1, t2) তৈরি করুন। এটি যাচাই করবে: 1. t1.val === t2.val। 2. t1.left হল t2.right এর একটি আয়না। 3. t1.right হল t2.left এর একটি আয়না।

class Node { constructor(val, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } function isSymmetric(root) { if (!root) return true; function isMirror(t1, t2) { if (!t1 && !t2) return true; if (!t1 || !t2 || t1.val !== t2.val) return false; return isMirror(t1.left, t2.right) && isMirror(t1.right, t2.left); } return isMirror(root.left, root.right); } // উদাহরণ: 1 -> [2, 2] -> [3, 4, 4, 3] প্রতিসম।

লেভেল অর্ডার ট্র্যাভার্সাল (BST/ট্রি)

একটি বাইনারি ট্রি দেওয়া হলে, তার নোডগুলির মানগুলির লেভেল অর্ডার ট্র্যাভার্সাল ফেরত দিন। (যেমন, বাম থেকে ডানে, স্তর দ্বারা স্তর)।

ব্যাখ্যা: এটি একটি ব্রেডথ-ফার্স্ট সার্চ (BFS)। একটি কিউ ব্যবহার করুন। রুটকে কিউতে যুক্ত করে শুরু করুন। কিউ খালি না হওয়া পর্যন্ত, বর্তমান স্তরের সমস্ত নোড প্রক্রিয়া করুন। প্রতিটি প্রক্রিয়াকৃত নোডের জন্য, তার চিলড্রেনদের (যদি থাকে) পরবর্তী স্তরের জন্য কিউতে যুক্ত করুন।

class Node { constructor(val, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } function levelOrder(root) { if (!root) return []; const result = []; const queue = [root]; while (queue.length > 0) { const levelSize = queue.length; const currentLevel = []; for (let i = 0; i < levelSize; i++) { const node = queue.shift(); currentLevel.push(node.val); if (node.left) queue.push(node.left); if (node.right) queue.push(node.right); } result.push(currentLevel); } return result; } // উদাহরণ: 3 -> [9, 20] -> [null, null, 15, 7] // আউটপুট: [[3], [9, 20], [15, 7]]

সাজানো অ্যারে থেকে উচ্চতা-ভারসাম্যপূর্ণ BST রূপান্তর করুন

ক্রমবর্ধমান ক্রমে সাজানো উপাদানগুলির একটি অ্যারে দেওয়া হলে, এটিকে একটি উচ্চতা-ভারসাম্যপূর্ণ বাইনারি সার্চ ট্রি (BST) তে রূপান্তর করুন।

ব্যাখ্যা: একটি উচ্চতা-ভারসাম্যপূর্ণ BST তৈরি করতে, আপনাকে অ্যারেটির মধ্যম উপাদানটিকে রুট হিসাবে নির্বাচন করতে হবে। তারপর, অ্যারেটির বাম অর্ধেক থেকে রিকার্সিভলি বাম সাবট্রি এবং ডান অর্ধেক থেকে ডান সাবট্রি তৈরি করুন।

class TreeNode { constructor(val = 0, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } function sortedArrayToBST(nums) { if (!nums || nums.length === 0) return null; function buildBST(start, end) { if (start > end) return null; const mid = Math.floor((start + end) / 2); const node = new TreeNode(nums[mid]); node.left = buildBST(start, mid - 1); node.right = buildBST(mid + 1, end); return node; } return buildBST(0, nums.length - 1); } // উদাহরণ: [-10, -3, 0, 5, 9] // আউটপুট: [0, -3, 9, -10, null, 5, null] এর মতো একটি ট্রি

`bind` প্রয়োগ করুন

Function.prototype.bind এর আপনার নিজস্ব সংস্করণ প্রয়োগ করুন।

ব্যাখ্যা: bind একটি নতুন ফাংশন তৈরি করে যা, যখন কল করা হয়, তখন তার this কীওয়ার্ডটি প্রদত্ত মানটিতে সেট করা থাকে, একটি প্রদত্ত আর্গুমেন্টের ক্রম সহ যা নতুন ফাংশনটি কল করার সময় প্রদত্ত যেকোনো আর্গুমেন্টের আগে থাকে। একটি ফেরত ফাংশনের মধ্যে apply বা call ব্যবহার করুন, আংশিক প্রয়োগ (পূর্ব-নির্ধারিত আর্গুমেন্ট) হ্যান্ডেল করুন।

Function.prototype.myBind = function(context, ...bindArgs) { const originalFunc = this; return function(...callArgs) { return originalFunc.apply(context, [...bindArgs, ...callArgs]); }; } const module = { x: 42, getX: function() { return this.x; } }; const unboundGetX = module.getX; console.log(unboundGetX()); // undefined (এটি গ্লোবাল/উইন্ডো) const boundGetX = unboundGetX.myBind(module); console.log(boundGetX()); // 42

K-তম বৃহত্তম উপাদান খুঁজুন

একটি অ-সাজানো অ্যারেতে K-তম বৃহত্তম উপাদান খুঁজুন। মনে রাখবেন এটি সাজানো ক্রমে K-তম বৃহত্তম উপাদান, K-তম স্বতন্ত্র উপাদান নয়।

ব্যাখ্যা: একটি সরল পদ্ধতি হল অ্যারেটি সাজিয়ে তারপর n - k সূচকে উপাদানটি নির্বাচন করা। বড় অ্যারেগুলির জন্য আরও কার্যকর পদ্ধতি হল একটি মিন-হিপ বা কুইকসিলেক্টের মতো একটি নির্বাচন অ্যালগরিদম ব্যবহার করা।

function findKthLargest(nums, k) { // সরল পদ্ধতি: সাজান nums.sort((a, b) => b - a); // অবরোহী ক্রমে সাজান return nums[k - 1]; // দ্রষ্টব্য: একটি ইন্টারভিউতে কুইকসিলেক্ট আরও কার্যকর হবে // তবে সাজানো দ্রুত প্রয়োগ করা সহজ। } console.log(findKthLargest([3, 2, 1, 5, 6, 4], 2)); // 5 console.log(findKthLargest([3, 2, 3, 1, 2, 4, 5, 5, 6], 4)); // 4

বস্তুর সম্পত্তি আছে কিনা পরীক্ষা করুন

একটি বস্তুর একটি নির্দিষ্ট সম্পত্তি আছে কিনা তা আপনি কীভাবে পরীক্ষা করতে পারেন?

ব্যাখ্যা: আপনি in অপারেটর (নিজের এবং উত্তরাধিকারসূত্রে প্রাপ্ত বৈশিষ্ট্যগুলি পরীক্ষা করে), Object.prototype.hasOwnProperty.call(obj, prop) (শুধুমাত্র নিজের বৈশিষ্ট্যগুলি পরীক্ষা করে), অথবা সহজভাবে obj.prop !== undefined (undefined মানগুলির সাথে জটিল হতে পারে) ব্যবহার করতে পারেন।

const person = { name: 'ইভ', age: 28 }; function hasProp(obj, prop) { console.log(`'in' ব্যবহার করে: ${prop in obj}`); console.log(`'hasOwnProperty' ব্যবহার করে: ${Object.prototype.hasOwnProperty.call(obj, prop)}`); } hasProp(person, 'name'); // true, true hasProp(person, 'toString'); // true, false (toString উত্তরাধিকারসূত্রে প্রাপ্ত)

পূর্ণসংখ্যা থেকে রোমান

একটি পূর্ণসংখ্যাকে তার রোমান সংখ্যায় রূপান্তর করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: রোমান সংখ্যা এবং তাদের সংশ্লিষ্ট মানগুলির একটি ম্যাপিং তৈরি করুন, বৃহত্তম থেকে ক্ষুদ্রতম পর্যন্ত সাজানো। এই ম্যাপের মধ্য দিয়ে পুনরাবৃত্তি করুন। প্রতিটি মানের জন্য, এটিকে ইনপুট সংখ্যা থেকে যতবার সম্ভব বিয়োগ করুন, প্রতিবার রোমান সংখ্যাটি যুক্ত করুন।

function intToRoman(num) { const map = { M: 1000, CM: 900, D: 500, CD: 400, C: 100, XC: 90, L: 50, XL: 40, X: 10, IX: 9, V: 5, IV: 4, I: 1 }; let result = ''; for (let key in map) { while (num >= map[key]) { result += key; num -= map[key]; } } return result; } console.log(intToRoman(3)); // III console.log(intToRoman(58)); // LVIII console.log(intToRoman(1994)); // MCMXCIV

রোমান থেকে পূর্ণসংখ্যা

একটি রোমান সংখ্যাকে পূর্ণসংখ্যায় রূপান্তর করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: রোমান চিহ্ন থেকে মানগুলির একটি মানচিত্র তৈরি করুন। স্ট্রিংটির মধ্য দিয়ে পুনরাবৃত্তি করুন। যদি বর্তমান চিহ্নের মান পরবর্তী চিহ্নের মানের চেয়ে কম হয় (যেমন 'IV' বা 'IX'), তবে বর্তমান মানটি বিয়োগ করুন; অন্যথায়, এটি যোগ করুন।

function romanToInt(s) { const map = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 }; let result = 0; for (let i = 0; i < s.length; i++) { const currentVal = map[s[i]]; const nextVal = map[s[i + 1]]; if (nextVal > currentVal) { result -= currentVal; } else { result += currentVal; } } return result; } console.log(romanToInt('III')); // 3 console.log(romanToInt('LVIII')); // 58 console.log(romanToInt('MCMXCIV')); // 1994

একটি সেট প্রয়োগ করুন

add, has, delete এবং size পদ্ধতি সহ একটি মৌলিক সেট ডেটা স্ট্রাকচার (বিল্ট-ইন সেট ব্যবহার না করে) প্রয়োগ করুন।

ব্যাখ্যা: আপনি একটি জাভাস্ক্রিপ্ট অবজেক্ট (হ্যাশ ম্যাপ) অন্তর্নিহিত স্টোরেজ হিসাবে ব্যবহার করতে পারেন। কীগুলি সেট উপাদান হবে (বিভিন্ন প্রকার সংরক্ষণ এবং কী হিসাবে অনন্যতা নিশ্চিত করতে আপনার হ্যান্ডেল করার প্রয়োজন হতে পারে)।

class MySet { constructor() { this.items = {}; this._size = 0; } add(element) { if (!this.has(element)) { this.items[element] = element; // উপাদান সংরক্ষণ করুন this._size++; return true; } return false; } delete(element) { if (this.has(element)) { delete this.items[element]; this._size--; return true; } return false; } has(element) { return Object.prototype.hasOwnProperty.call(this.items, element); } get size() { return this._size; } } const set = new MySet(); set.add(1); set.add(2); console.log(set.has(1)); // true console.log(set.size); // 2 set.delete(1); console.log(set.has(1)); // false

প্যাসকেলের ত্রিভুজ

একটি পূর্ণসংখ্যা numRows দেওয়া হলে, প্যাসকেলের ত্রিভুজের প্রথম numRows তৈরি করুন।

ব্যাখ্যা: প্যাসকেলের ত্রিভুজে, প্রতিটি সংখ্যা তার সরাসরি উপরের দুটি সংখ্যার যোগফল। [[1]] দিয়ে শুরু করুন। প্রতিটি পরবর্তী সারির জন্য, 1 দিয়ে শুরু এবং শেষ করুন। প্রতিটি মধ্যম উপাদান হল উপরের সারি থেকে একই সূচক এবং পূর্ববর্তী সূচকের উপাদানের যোগফল।

function generatePascalsTriangle(numRows) { if (numRows === 0) return []; const triangle = [[1]]; for (let i = 1; i < numRows; i++) { const prevRow = triangle[i - 1]; const newRow = [1]; for (let j = 1; j < i; j++) { newRow.push(prevRow[j - 1] + prevRow[j]); } newRow.push(1); triangle.push(newRow); } return triangle; } console.log(generatePascalsTriangle(5)); // [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]

শব্দ অনুসন্ধান

একটি 2D বোর্ড এবং একটি শব্দ দেওয়া হলে, শব্দটি গ্রিডে বিদ্যমান কিনা তা খুঁজুন। শব্দটি ক্রমানুসারে সংলগ্ন কোষগুলির অক্ষর থেকে তৈরি করা যেতে পারে, যেখানে 'সংলগ্ন' কোষগুলি অনুভূমিকভাবে বা উল্লম্বভাবে প্রতিবেশী।

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

function exist(board, word) { const rows = board.length; const cols = board[0].length; function dfs(r, c, index) { if (index === word.length) return true; // শব্দ পাওয়া গেছে if (r < 0 || c < 0 || r >= rows || c >= cols || board[r][c] !== word[index]) { return false; } const temp = board[r][c]; board[r][c] = '#'; // ভিজিট করা হিসাবে চিহ্নিত করুন const found = dfs(r + 1, c, index + 1) || dfs(r - 1, c, index + 1) || dfs(r, c + 1, index + 1) || dfs(r, c - 1, index + 1); board[r][c] = temp; // ব্যাকট্র্যাক return found; } for (let r = 0; r < rows; r++) { for (let c = 0; c < cols; c++) { if (board[r][c] === word[0] && dfs(r, c, 0)) { return true; } } } return false; } const board = [['A','B','C','E'],['S','F','C','S'],['A','D','E','E']]; console.log(exist(board, 'ABCCED')); // true console.log(exist(board, 'SEE')); // true console.log(exist(board, 'ABCB')); // false

ন্যূনতম উইন্ডো সাবস্ট্রিং

দুটি স্ট্রিং s এবং t দেওয়া হলে, s এ ন্যূনতম উইন্ডো খুঁজুন যা t এর সমস্ত অক্ষর ধারণ করবে। যদি s এ এমন কোন উইন্ডো না থাকে যা t এর সমস্ত অক্ষর কভার করে, তাহলে খালি স্ট্রিং "" ফেরত দিন।

ব্যাখ্যা: দুটি পয়েন্টার (left এবং right) এবং হ্যাশ ম্যাপ সহ একটি স্লাইডিং উইন্ডো পদ্ধতি ব্যবহার করুন। একটি ম্যাপ t থেকে প্রয়োজনীয় অক্ষরের সংখ্যা সংরক্ষণ করে। অন্য ম্যাপ বর্তমান উইন্ডোতে সংখ্যা সংরক্ষণ করে। right দিয়ে উইন্ডোটি প্রসারিত করুন। একবার উইন্ডোতে সমস্ত প্রয়োজনীয় অক্ষর থাকলে, ন্যূনতম সম্ভাব্য উইন্ডো খুঁজে পেতে left দিয়ে এটিকে ছোট করার চেষ্টা করুন।

function minWindow(s, t) { if (!t || !s || s.length < t.length) return ""; const tMap = {}; for (const char of t) tMap[char] = (tMap[char] || 0) + 1; let required = Object.keys(tMap).length; let formed = 0; const windowMap = {}; let left = 0; let minLen = Infinity; let result = ""; for (let right = 0; right < s.length; right++) { const char = s[right]; windowMap[char] = (windowMap[char] || 0) + 1; if (tMap[char] && windowMap[char] === tMap[char]) { formed++; } while (left <= right && formed === required) { if (right - left + 1 < minLen) { minLen = right - left + 1; result = s.substring(left, right + 1); } const leftChar = s[left]; windowMap[leftChar]--; if (tMap[leftChar] && windowMap[leftChar] < tMap[leftChar]) { formed--; } left++; } } return result; } console.log(minWindow('ADOBECODEBANC', 'ABC')); // 'BANC'

লিঙ্কড লিস্ট উল্টান

একক লিঙ্কড লিস্টের head দেওয়া হলে, তালিকাটি উল্টান এবং উল্টানো তালিকা ফেরত দিন।

ব্যাখ্যা: আপনাকে তালিকার মধ্য দিয়ে পুনরাবৃত্তি করতে হবে, প্রতিটি নোডের next পয়েন্টারকে পূর্ববর্তী নোডের দিকে নির্দেশ করার জন্য পরিবর্তন করতে হবে। পুনরাবৃত্তির সময় previous, current এবং next নোডগুলির ট্র্যাক রাখুন।

class ListNode { constructor(val = 0, next = null) { this.val = val; this.next = next; } } function reverseList(head) { let prev = null; let current = head; let next = null; while (current !== null) { next = current.next; // পরবর্তী নোড সংরক্ষণ করুন current.next = prev; // বর্তমান নোডের পয়েন্টার উল্টান prev = current; // prev কে এক ধাপ এগিয়ে নিয়ে যান current = next; // current কে এক ধাপ এগিয়ে নিয়ে যান } return prev; // নতুন হেড হল শেষ 'prev' } // উদাহরণ: 1->2->3->4->5 হয়ে যায় 5->4->3->2->1

লিঙ্কড লিস্টে চক্র সনাক্ত করুন

লিঙ্কড লিস্টের head দেওয়া হলে, লিঙ্কড লিস্টে একটি চক্র আছে কিনা তা নির্ধারণ করুন।

ব্যাখ্যা: 'ফ্লয়েডের টর্টোয়িজ এবং হেয়ার' অ্যালগরিদম ব্যবহার করুন। দুটি পয়েন্টার রাখুন, একটি একবারে এক ধাপ করে চলে (slow) এবং একটি একবারে দুই ধাপ করে চলে (fast)। যদি একটি চক্র থাকে, তবে fast পয়েন্টারটি শেষ পর্যন্ত slow পয়েন্টারের সাথে মিলিত হবে।

class ListNode { constructor(val = 0, next = null) { this.val = val; this.next = next; } } function hasCycle(head) { if (!head || !head.next) return false; let slow = head; let fast = head.next; while (slow !== fast) { if (!fast || !fast.next) return false; // শেষ হয়েছে, কোন চক্র নেই slow = slow.next; fast = fast.next.next; } return true; // পয়েন্টারগুলি মিলিত হয়েছে, চক্র বিদ্যমান } // উদাহরণ: 3->2->0->-4 যেখানে -4 আবার 2 কে নির্দেশ করছে। hasCycle সত্য ফেরত দেয়।

`Object.create` প্রয়োগ করুন

Object.create(proto) এর আচরণের অনুকরণ করে এমন একটি ফাংশন প্রয়োগ করুন।

ব্যাখ্যা: Object.create একটি নতুন অবজেক্ট তৈরি করে, একটি বিদ্যমান অবজেক্টকে নতুন তৈরি করা অবজেক্টের প্রোটোটাইপ হিসাবে ব্যবহার করে। আপনি একটি অস্থায়ী কনস্ট্রাক্টর ফাংশন তৈরি করে, তার প্রোটোটাইপকে ইনপুট proto তে সেট করে, এবং তারপর তার একটি নতুন উদাহরণ ফেরত দিয়ে এটি অর্জন করতে পারেন।

function myObjectCreate(proto) { if (typeof proto !== 'object' && typeof proto !== 'function') { if (proto !== null) { throw new TypeError('Object prototype may only be an Object or null: ' + proto); } } function F() {} F.prototype = proto; return new F(); } const person = { isHuman: false, printIntroduction: function() { console.log(`আমার নাম ${this.name}। আমি কি মানুষ? ${this.isHuman}`); } }; const me = myObjectCreate(person); me.name = 'ম্যাথিউ'; me.isHuman = true; me.printIntroduction(); // আমার নাম ম্যাথিউ। আমি কি মানুষ? true console.log(Object.getPrototypeOf(me) === person); // true

হোইস্টিং কি?

জাভাস্ক্রিপ্টে হোইস্টিং ব্যাখ্যা করুন এবং একটি উদাহরণ দিন।

ব্যাখ্যা: হোইস্টিং হল জাভাস্ক্রিপ্টের ডিফল্ট আচরণ যা কোড এক্সিকিউশনের আগে ডিক্লারেশনগুলিকে বর্তমান স্কোপের (গ্লোবাল বা ফাংশন) শীর্ষে নিয়ে যায়। ভেরিয়েবল ডিক্লারেশন (var) হোইস্ট করা হয় এবং undefined দিয়ে ইনিশিয়ালাইজ করা হয়। ফাংশন ডিক্লারেশনগুলি সম্পূর্ণরূপে হোইস্ট করা হয় (নাম এবং বডি উভয়ই)। let এবং const হোইস্ট করা হয় কিন্তু ইনিশিয়ালাইজ করা হয় না, যার ফলে একটি টেম্পোরাল ডেড জোন তৈরি হয়।

console.log(myVar); // undefined (var হোইস্ট করা হয় এবং undefined দিয়ে ইনিশিয়ালাইজ করা হয়) // console.log(myLet); // ReferenceError: ইনিশিয়ালাইজেশনের আগে 'myLet' অ্যাক্সেস করা যাবে না (TDZ) myFunc(); // 'Hello!' (ফাংশন ডিক্লারেশন সম্পূর্ণরূপে হোইস্ট করা হয়) var myVar = 'আমি একটি var'; let myLet = 'আমি একটি let'; function myFunc() { console.log('Hello!'); }

ইভেন্ট বাবলিং এবং ক্যাপচারিং ব্যাখ্যা করুন

DOM এর প্রসঙ্গে ইভেন্ট বাবলিং এবং ক্যাপচারিং ব্যাখ্যা করুন।

ব্যাখ্যা: এগুলি HTML DOM এ ইভেন্ট প্রচারের দুটি পর্যায়। ক্যাপচারিং পর্যায়: ইভেন্টটি window থেকে টার্গেট এলিমেন্টের দিকে নিচে চলে। বাবলিং পর্যায়: ইভেন্টটি টার্গেট এলিমেন্ট থেকে আবার window এর দিকে উপরে চলে। ডিফল্টরূপে, বেশিরভাগ ইভেন্ট হ্যান্ডলার বাবলিং পর্যায়ে নিবন্ধিত হয়। ক্যাপচারিং পর্যায়ে ইভেন্টগুলি হ্যান্ডেল করতে আপনি addEventListener(type, listener, useCapture) ব্যবহার করতে পারেন useCapture = true সহ।

// একটি HTML কাঠামোতে: <div><p><span>এখানে ক্লিক করুন</span></p></div> // যদি আপনি <span> এ ক্লিক করেন: // ক্যাপচারিং: window -> document -> html -> body -> div -> p -> span // বাবলিং: span -> p -> div -> body -> html -> document -> window /* JS উদাহরণ div.addEventListener('click', () => console.log('Div ক্লিক হয়েছে'), true); // ক্যাপচারিং p.addEventListener('click', () => console.log('P ক্লিক হয়েছে'), false); // বাবলিং span.addEventListener('click', () => console.log('Span ক্লিক হয়েছে'), false); // বাবলিং // আউটপুট হবে: Div ক্লিক হয়েছে, Span ক্লিক হয়েছে, P ক্লিক হয়েছে */

ম্যানুয়ালি `JSON.parse` প্রয়োগ করুন (মৌলিক)

JSON.parse এর একটি খুব মৌলিক সংস্করণ (সাধারণ অবজেক্ট, অ্যারে, স্ট্রিং, সংখ্যাগুলি হ্যান্ডেল করুন) প্রয়োগ করার চেষ্টা করুন।

ব্যাখ্যা: এটি সম্পূর্ণভাবে একটি খুব জটিল কাজ, তবে একটি লাইভ কোডিং সেটিং এর জন্য, আপনাকে একটি খুব সরলীকৃত উপসেট হ্যান্ডেল করতে বলা হতে পারে। আপনাকে স্ট্রিংটি পার্স করতে হবে, অবজেক্ট {} এবং অ্যারে [] সীমানা, কী-মান জোড়া ("key": value), এবং মৌলিক ডেটা প্রকারগুলি সনাক্ত করতে হবে। eval বা new Function এটি প্রতারণা করতে পারে তবে বিপজ্জনক। একটি বাস্তব পার্সার একটি লেক্সার/টোকেটাইজার এবং পার্সার ব্যবহার করবে।

function basicJsonParse(jsonString) { // সতর্কতা: new Function ব্যবহার করা eval এর মতো অনিরাপদ। // এটি শুধুমাত্র প্রদর্শনের জন্য একটি সরলীকৃত, অনিরাপদ উদাহরণ। // একটি বাস্তব প্রয়োগের জন্য একটি সঠিক পার্সার প্রয়োজন। try { return (new Function('return ' + jsonString))(); } catch (e) { throw new SyntaxError('অবৈধ JSON: ' + e.message); } } console.log(basicJsonParse('{"a": 1, "b": ["x", "y"]}')); // { a: 1, b: ['x', 'y'] }

গভীরভাবে নেস্টেড অ্যারে সমতল করুন

একটি গভীরভাবে নেস্টেড অ্যারে সমতল করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: পূর্ববর্তী সমতলকরণের (এক স্তর) বিপরীতে, এটি যেকোনো স্তরের নেস্টিং হ্যান্ডেল করতে হবে। রিকার্সন একটি প্রাকৃতিক ফিট। অ্যারেটির মধ্য দিয়ে পুনরাবৃত্তি করুন। যদি একটি উপাদান একটি অ্যারে হয়, তবে এটিকে রিকার্সিভলি সমতল করুন এবং ফলাফলটি সংযুক্ত করুন। অন্যথায়, উপাদানটি যুক্ত করুন।

function deepFlatten(arr) { let flattened = []; arr.forEach(item => { if (Array.isArray(item)) { flattened = flattened.concat(deepFlatten(item)); } else { flattened.push(item); } }); return flattened; // ES2019+ একটি অনেক সহজ উপায় প্রদান করে: // return arr.flat(Infinity); } console.log(deepFlatten([1, [2, [3, 4], 5], 6])); // [1, 2, 3, 4, 5, 6]

একটি ট্রাই (প্রিফিক্স ট্রি) প্রয়োগ করুন

insert, search, এবং startsWith পদ্ধতি সহ একটি ট্রাই ডেটা স্ট্রাকচার প্রয়োগ করুন।

ব্যাখ্যা: একটি ট্রাই হল একটি ট্রি-এর মতো ডেটা স্ট্রাকচার যা স্ট্রিংগুলির একটি ডেটাসেটে কীগুলি দক্ষতার সাথে সংরক্ষণ এবং পুনরুদ্ধার করতে ব্যবহৃত হয়। প্রতিটি নোড একটি অক্ষরকে প্রতিনিধিত্ব করে এবং রুট থেকে পথগুলি শব্দ বা প্রিফিক্সকে প্রতিনিধিত্ব করে।

class TrieNode { constructor() { this.children = {}; this.isEndOfWord = false; } } class Trie { constructor() { this.root = new TrieNode(); } insert(word) { let node = this.root; for (const char of word) { if (!node.children[char]) { node.children[char] = new TrieNode(); } node = node.children[char]; } node.isEndOfWord = true; } search(word) { let node = this.root; for (const char of word) { if (!node.children[char]) return false; node = node.children[char]; } return node.isEndOfWord; } startsWith(prefix) { let node = this.root; for (const char of prefix) { if (!node.children[char]) return false; node = node.children[char]; } return true; } } const trie = new Trie(); trie.insert('apple'); console.log(trie.search('apple')); // true console.log(trie.search('app')); // false console.log(trie.startsWith('app')); // true

একটি অ্যারে শাফেল করুন (ফিশার-ইয়েটস)

ফিশার-ইয়েটস (বা নুথ) অ্যালগরিদম ব্যবহার করে একটি অ্যারে ইন-প্লেসে শাফেল করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: ফিশার-ইয়েটস অ্যালগরিদম একটি অ্যারে শেষ উপাদান থেকে প্রথম উপাদান পর্যন্ত পুনরাবৃত্তি করে। প্রতিটি পুনরাবৃত্তিতে, এটি বর্তমান উপাদানকে অ্যারের শুরু থেকে বর্তমান উপাদান পর্যন্ত (অন্তর্ভুক্ত) একটি এলোমেলোভাবে নির্বাচিত উপাদানের সাথে অদলবদল করে।

function shuffleArray(arr) { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; // উপাদানগুলি অদলবদল করুন } return arr; } console.log(shuffleArray([1, 2, 3, 4, 5])); // যেমন, [3, 5, 1, 2, 4]

ফাংশনগুলি কম্পোজ করুন

একাধিক ফাংশন গ্রহণ করে এবং ডান থেকে বামে তাদের প্রয়োগ করে এমন একটি নতুন ফাংশন ফেরত দেয় এমন একটি compose ফাংশন প্রয়োগ করুন।

ব্যাখ্যা: ফাংশন কম্পোজিশন (f ∘ g)(x) = f(g(x)) একটি ফাংশনকে অন্যটির ফলাফলে প্রয়োগ করে। একটি সাধারণ compose(f, g, h) এর অর্থ হবে f(g(h(x)))। একটি মার্জিত প্রয়োগের জন্য reduceRight ব্যবহার করুন।

function compose(...funcs) { return function(initialArg) { return funcs.reduceRight((acc, func) => func(acc), initialArg); }; } const add5 = x => x + 5; const multiply3 = x => x * 3; const subtract2 = x => x - 2; const composedFunc = compose(subtract2, multiply3, add5); console.log(composedFunc(10)); // (10 + 5) * 3 - 2 = 15 * 3 - 2 = 45 - 2 = 43

ফাংশনগুলি পাইপ করুন

একাধিক ফাংশন গ্রহণ করে এবং বাম থেকে ডানে তাদের প্রয়োগ করে এমন একটি নতুন ফাংশন ফেরত দেয় এমন একটি pipe ফাংশন প্রয়োগ করুন।

ব্যাখ্যা: compose এর মতো, তবে প্রয়োগের ক্রম উল্টানো হয়: pipe(f, g, h) এর অর্থ h(g(f(x)))। প্রয়োগের জন্য reduce ব্যবহার করুন।

function pipe(...funcs) { return function(initialArg) { return funcs.reduce((acc, func) => func(acc), initialArg); }; } const add5 = x => x + 5; const multiply3 = x => x * 3; const subtract2 = x => x - 2; const pipedFunc = pipe(add5, multiply3, subtract2); console.log(pipedFunc(10)); // (10 + 5) * 3 - 2 = 15 * 3 - 2 = 45 - 2 = 43

কয়েন পরিবর্তন সমস্যা

কয়েন মূল্যবোধ এবং একটি পরিমাণ দেওয়া হলে, সেই পরিমাণ তৈরি করতে প্রয়োজনীয় সর্বনিম্ন সংখ্যক কয়েন খুঁজুন। প্রতিটি কয়েনের অসীম সরবরাহ অনুমান করুন।

ব্যাখ্যা: এটি একটি ক্লাসিক ডাইনামিক প্রোগ্রামিং সমস্যা। একটি অ্যারে dp তৈরি করুন যেখানে dp[i] পরিমাণ i এর জন্য প্রয়োজনীয় সর্বনিম্ন কয়েন সংরক্ষণ করে। dp[i] = min(dp[i - coin]) + 1 সমস্ত কয়েনের জন্য।

function coinChange(coins, amount) { const dp = new Array(amount + 1).fill(Infinity); dp[0] = 0; for (let i = 1; i <= amount; i++) { for (const coin of coins) { if (i - coin >= 0) { dp[i] = Math.min(dp[i], dp[i - coin] + 1); } } } return dp[amount] === Infinity ? -1 : dp[amount]; } console.log(coinChange([1, 2, 5], 11)); // 3 (5 + 5 + 1) console.log(coinChange([2], 3)); // -1

সর্বনিম্ন সাধারণ পূর্বপুরুষ (BST)

একটি বাইনারি সার্চ ট্রি (BST) দেওয়া হলে, BST-এর দুটি প্রদত্ত নোডের সর্বনিম্ন সাধারণ পূর্বপুরুষ (LCA) খুঁজুন।

ব্যাখ্যা: LCA হল সবচেয়ে গভীর নোড যা উভয় প্রদত্ত নোডকে বংশধর হিসাবে ধারণ করে। একটি BST তে, আপনি রুট থেকে ট্র্যাভার্স করে এটি খুঁজে পেতে পারেন। যদি উভয় নোড বর্তমান নোডের চেয়ে ছোট হয়, বাম দিকে যান। যদি উভয়ই বড় হয়, ডান দিকে যান। যদি একটি ছোট এবং একটি বড় হয় (বা একটি বর্তমান নোড হয়), তবে বর্তমান নোড হল LCA।

class Node { constructor(val) { this.val = val; this.left = this.right = null; } } function lowestCommonAncestor(root, p, q) { let current = root; while (current) { if (p.val > current.val && q.val > current.val) { current = current.right; } else if (p.val < current.val && q.val < current.val) { current = current.left; } else { return current; // LCA পাওয়া গেছে } } return null; // p এবং q সহ একটি বৈধ BST তে এটি ঘটা উচিত নয় } // উদাহরণ: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 => LCA হল 6

বাইনারি ট্রি সিরিয়ালাইজ এবং ডিসিরিয়ালাইজ করুন

একটি বাইনারি ট্রি সিরিয়ালাইজ এবং ডিসিরিয়ালাইজ করার জন্য একটি অ্যালগরিদম ডিজাইন করুন।

ব্যাখ্যা: সিরিয়ালাইজেশন একটি ট্রিকে স্ট্রিং বা অ্যারেতে রূপান্তর করে। ডিসিরিয়ালাইজেশন ট্রিটিকে পুনরায় গঠন করে। একটি সাধারণ উপায় হল প্রি-অর্ডার ট্র্যাভার্সাল (DFS)। কাঠামো বজায় রাখার জন্য নাল নোডগুলির জন্য একটি বিশেষ মার্কার (যেমন, '#') ব্যবহার করুন।

class Node { constructor(val) { this.val = val; this.left = this.right = null; } } function serialize(root) { const values = []; function dfs(node) { if (!node) { values.push('#'); return; } values.push(node.val); dfs(node.left); dfs(node.right); } dfs(root); return values.join(','); } function deserialize(data) { const values = data.split(','); let index = 0; function buildTree() { if (values[index] === '#') { index++; return null; } const node = new Node(parseInt(values[index])); index++; node.left = buildTree(); node.right = buildTree(); return node; } return buildTree(); } // উদাহরণ: 1 -> [2, 3] -> [null, null, 4, 5] // সিরিয়ালাইজড: '1,2,#,#,3,4,#,#,5,#,#'

`setTimeout` সহ `setInterval` প্রয়োগ করুন

setInterval এর অনুকরণ করে এমন একটি ফাংশন mySetInterval প্রয়োগ করুন যা রিকার্সিভলি setTimeout ব্যবহার করে।

ব্যাখ্যা: setInterval একটি ফাংশনকে প্রতি N মিলিসেকেন্ডে বারবার চালায়। আপনি প্রতিটি এক্সিকিউশনের পরে setTimeout দিয়ে একটি ফাংশন নিজেকে কল করে এটি অর্জন করতে পারেন। এটি পরিষ্কার করার একটি উপায়ও আপনার প্রয়োজন (myClearInterval)।

function mySetInterval(callback, delay, ...args) { const interval = { timerId: null }; function run() { interval.timerId = setTimeout(() => { callback.apply(this, args); run(); // পরবর্তী কল শিডিউল করুন }, delay); } run(); return interval; // পরিষ্কার করার অনুমতি দেওয়ার জন্য একটি অবজেক্ট ফেরত দিন } function myClearInterval(interval) { clearTimeout(interval.timerId); } // উদাহরণ ব্যবহার: let count = 0; const intervalId = mySetInterval(() => { console.log(`হ্যালো: ${++count}`); if (count === 3) myClearInterval(intervalId); }, 500);

গ্রাফ ট্র্যাভার্সাল (BFS এবং DFS)

একটি প্রদত্ত গ্রাফের জন্য (সংলগ্ন তালিকা উপস্থাপন) ব্রেডথ-ফার্স্ট সার্চ (BFS) এবং ডেপথ-ফার্স্ট সার্চ (DFS) প্রয়োগ করুন।

ব্যাখ্যা: BFS প্রথমে প্রতিবেশীদের অন্বেষণ করে (একটি কিউ ব্যবহার করে), যখন DFS প্রতিটি শাখায় যতদূর সম্ভব অন্বেষণ করে (একটি স্ট্যাক বা রিকার্সন ব্যবহার করে)। চক্র এবং অপ্রয়োজনীয় কাজ এড়াতে পরিদর্শন করা নোডগুলির ট্র্যাক রাখুন।

const graph = { A: ['B', 'C'], B: ['D'], C: ['E'], D: [], E: ['F'], F: [] }; function bfs(graph, startNode) { const queue = [startNode]; const visited = new Set(); const result = []; visited.add(startNode); while (queue.length > 0) { const node = queue.shift(); result.push(node); for (const neighbor of graph[node]) { if (!visited.has(neighbor)) { visited.add(neighbor); queue.push(neighbor); } } } return result; } function dfs(graph, startNode) { const stack = [startNode]; const visited = new Set(); const result = []; while (stack.length > 0) { const node = stack.pop(); if (!visited.has(node)) { visited.add(node); result.push(node); // পরে তাদের ক্রমে প্রক্রিয়া করার জন্য প্রতিবেশীদের উল্টো ক্রমে যুক্ত করুন (ঐচ্ছিক) for (let i = graph[node].length - 1; i >= 0; i--) { stack.push(graph[node][i]); } } } return result; } console.log('BFS:', bfs(graph, 'A')); // ['A', 'B', 'C', 'D', 'E', 'F'] console.log('DFS:', dfs(graph, 'A')); // ['A', 'B', 'D', 'C', 'E', 'F']

ছবি ঘোরান (ম্যাট্রিক্স)

আপনাকে একটি n x n 2D ম্যাট্রিক্স দেওয়া হয়েছে যা একটি ছবিকে উপস্থাপন করে। ছবিটি 90 ডিগ্রি (ঘড়ির কাঁটার দিকে) ইন-প্লেসে ঘোরান।

ব্যাখ্যা: এটি অর্জনের একটি সাধারণ উপায় হল প্রথমে ম্যাট্রিক্সকে ট্রান্সপোজ করা (matrix[i][j] কে matrix[j][i] দিয়ে অদলবদল করে) এবং তারপর প্রতিটি সারি উল্টানো।

function rotate(matrix) { const n = matrix.length; // ট্রান্সপোজ করুন for (let i = 0; i < n; i++) { for (let j = i; j < n; j++) { [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]]; } } // প্রতিটি সারি উল্টান for (let i = 0; i < n; i++) { matrix[i].reverse(); } return matrix; } const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; console.log(rotate(matrix)); // [[7, 4, 1], [8, 5, 2], [9, 6, 3]]

সর্পিল ম্যাট্রিক্স ট্রাভার্সাল

একটি m x n ম্যাট্রিক্স দেওয়া আছে, সর্পিল ক্রমে ম্যাট্রিক্সের সমস্ত উপাদান ফেরত দিন।

ব্যাখ্যা: সীমানা নির্ধারণ করতে চারটি পয়েন্টার ব্যবহার করুন: top, bottom, left, right। উপরের সারিটি অতিক্রম করুন, তারপর ডান কলাম, তারপর নীচের সারি, তারপর বাম কলাম, প্রতিটি অতিক্রমের পরে সীমানা সঙ্কুচিত করুন, যতক্ষণ না left ডানকে অতিক্রম করে বা top নিচকে অতিক্রম করে।

function spiralOrder(matrix) { if (!matrix || matrix.length === 0) return []; const rows = matrix.length, cols = matrix[0].length; const result = []; let top = 0, bottom = rows - 1, left = 0, right = cols - 1; while (top <= bottom && left <= right) { for (let i = left; i <= right; i++) result.push(matrix[top][i]); top++; for (let i = top; i <= bottom; i++) result.push(matrix[i][right]); right--; if (top <= bottom) { for (let i = right; i >= left; i--) result.push(matrix[bottom][i]); bottom--; } if (left <= right) { for (let i = bottom; i >= top; i--) result.push(matrix[i][left]); left++; } } return result; } const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; console.log(spiralOrder(matrix)); // [1, 2, 3, 6, 9, 8, 7, 4, 5]

ম্যাট্রিক্স শূন্য সেট করুন

একটি m x n ম্যাট্রিক্স দেওয়া আছে, যদি একটি উপাদান 0 হয়, তবে তার পুরো সারি এবং কলামকে 0 তে সেট করুন। এটি ইন-প্লেস করুন।

ব্যাখ্যা: একটি সরল পদ্ধতির জন্য O(m*n) অতিরিক্ত স্থান প্রয়োজন। O(1) স্থানে (বা O(m+n)) এটি করার জন্য, আপনি প্রথম সারি এবং প্রথম কলাম ব্যবহার করতে পারেন কোন সারি/কলাম শূন্য করতে হবে তার তথ্য সংরক্ষণ করতে। প্রথম সারি/কলামের নিজেদের শূন্য করার প্রয়োজন আছে কিনা তার জন্য আলাদা ফ্ল্যাগ দরকার।

function setZeroes(matrix) { const rows = matrix.length, cols = matrix[0].length; let firstColZero = false; for (let r = 0; r < rows; r++) { if (matrix[r][0] === 0) firstColZero = true; for (let c = 1; c < cols; c++) { if (matrix[r][c] === 0) { matrix[r][0] = 0; matrix[0][c] = 0; } } } for (let r = rows - 1; r >= 0; r--) { for (let c = cols - 1; c >= 1; c--) { if (matrix[r][0] === 0 || matrix[0][c] === 0) { matrix[r][c] = 0; } } if (firstColZero) matrix[r][0] = 0; } return matrix; } // Example: [[1,1,1],[1,0,1],[1,1,1]] => [[1,0,1],[0,0,0],[1,0,1]]

Promise.race প্রয়োগ করুন

একটি ফাংশন প্রয়োগ করুন যা Promise.race এর মতো আচরণ করে।

ব্যাখ্যা: Promise.race প্রতিশ্রুতির একটি অ্যারে নেয় এবং একটি একক প্রতিশ্রুতি ফেরত দেয়। এই ফেরত দেওয়া প্রতিশ্রুতি ইনপুট প্রতিশ্রুতিগুলির মধ্যে যেকোনও একটি নিষ্পত্তি হওয়ার সাথে সাথেই নিষ্পত্তি হয় (সমাধান বা প্রত্যাখ্যান), সেই প্রতিশ্রুতির মান বা কারণ সহ।

function myPromiseRace(promises) { return new Promise((resolve, reject) => { if (!promises || promises.length === 0) { return; // Or resolve/reject depending on spec } promises.forEach(promise => { Promise.resolve(promise).then(resolve, reject); }); }); } const p1 = new Promise((resolve) => setTimeout(resolve, 500, 'one')); const p2 = new Promise((resolve) => setTimeout(resolve, 100, 'two')); myPromiseRace([p1, p2]).then(value => console.log(value)); // 'two'

সিঙ্গেলটন প্যাটার্ন

জাভাস্ক্রিপ্টে সিঙ্গেলটন ডিজাইন প্যাটার্ন প্রয়োগ করুন।

ব্যাখ্যা: সিঙ্গেলটন প্যাটার্ন নিশ্চিত করে যে একটি ক্লাসের শুধুমাত্র একটি উদাহরণ রয়েছে এবং এটিতে বিশ্বব্যাপী অ্যাক্সেসের একটি বিন্দু সরবরাহ করে। একটি ক্লোজার ব্যবহার করে উদাহরণটি ধরে রাখা যেতে পারে।

const Singleton = (function() { let instance; function createInstance() { // Private methods and variables const privateVar = 'I am private'; function privateMethod() { console.log('Private'); } return { // Public methods and variables publicVar: 'I am public', publicMethod: function() { console.log('Public'); }, getPrivate: function() { return privateVar; } }; } return { getInstance: function() { if (!instance) { instance = createInstance(); } return instance; } }; })(); const instance1 = Singleton.getInstance(); const instance2 = Singleton.getInstance(); console.log(instance1 === instance2); // true console.log(instance1.getPrivate()); // 'I am private'

আইপি ঠিকানা যাচাই করুন

একটি দেওয়া স্ট্রিং একটি বৈধ IPv4 বা IPv6 ঠিকানা কিনা তা পরীক্ষা করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: IPv4 এর জন্য, ডট দ্বারা বিভক্ত 4টি সংখ্যা (0-255) পরীক্ষা করুন, কোন অগ্রণী শূন্য ছাড়া ('0' ছাড়া)। IPv6 এর জন্য, কোলন দ্বারা বিভক্ত 1-4 হেক্স ডিজিটের 8টি গ্রুপ পরীক্ষা করুন (যেমন '::' এর মতো ভিন্নতা পরিচালনা করুন)। রেগেক্স ব্যবহার করা যেতে পারে, তবে সাক্ষাত্কারের জন্য ম্যানুয়াল পার্সিং প্রায়শই স্পষ্ট হয়।

function validIPAddress(IP) { function isIPv4(s) { const parts = s.split('.'); if (parts.length !== 4) return false; for (const part of parts) { if (!/^[0-9]+$/.test(part)) return false; if (part.length > 1 && part.startsWith('0')) return false; const num = parseInt(part); if (num < 0 || num > 255) return false; } return true; } function isIPv6(s) { const parts = s.split(':'); if (parts.length !== 8) return false; // Simplified: No '::' for (const part of parts) { if (part.length < 1 || part.length > 4) return false; if (!/^[0-9a-fA-F]+$/.test(part)) return false; } return true; } if (IP.includes('.')) return isIPv4(IP) ? 'IPv4' : 'Neither'; if (IP.includes(':')) return isIPv6(IP) ? 'IPv6' : 'Neither'; return 'Neither'; } console.log(validIPAddress('172.16.254.1')); // IPv4 console.log(validIPAddress('2001:0db8:85a3:0000:0000:8a2e:0370:7334')); // IPv6 (Simplified) console.log(validIPAddress('256.256.256.256')); // Neither

শীর্ষ উপাদান খুঁজুন

একটি শীর্ষ উপাদান হল এমন একটি উপাদান যা তার প্রতিবেশীদের থেকে কঠোরভাবে বড়। একটি ইনপুট অ্যারে nums দেওয়া আছে, একটি শীর্ষ উপাদান খুঁজুন এবং তার সূচক ফেরত দিন।

ব্যাখ্যা: যেহেতু যেকোনো শীর্ষ কাজ করবে, এবং nums[-1] এবং nums[n] কে -Infinity হিসাবে বিবেচনা করা হয়, আপনি একটি সংশোধিত বাইনারি অনুসন্ধান ব্যবহার করতে পারেন। যদি nums[mid] nums[mid+1] এর চেয়ে কম হয়, তাহলে ডানদিকে একটি শীর্ষ অবশ্যই বিদ্যমান থাকবে। অন্যথায়, বামদিকে একটি শীর্ষ অবশ্যই বিদ্যমান থাকবে (অথবা mid নিজেই একটি শীর্ষ)।

function findPeakElement(nums) { let left = 0; let right = nums.length - 1; while (left < right) { let mid = Math.floor((left + right) / 2); if (nums[mid] < nums[mid + 1]) { left = mid + 1; // Peak is to the right } else { right = mid; // Peak is mid or to the left } } return left; // 'left' will be the index of a peak } console.log(findPeakElement([1, 2, 3, 1])); // 2 (index of 3) console.log(findPeakElement([1, 2, 1, 3, 5, 6, 4])); // 5 (index of 6) or 1 (index of 2)

বিটস গণনা করা হচ্ছে

একটি পূর্ণসংখ্যা n দেওয়া আছে, n + 1 দৈর্ঘ্যের একটি অ্যারে ans ফেরত দিন যাতে প্রতিটি i (0 <= i <= n) এর জন্য, ans[i] হল i এর বাইনারি উপস্থাপনায় 1 এর সংখ্যা।

ব্যাখ্যা: আপনি ডায়নামিক প্রোগ্রামিং ব্যবহার করে এটি সমাধান করতে পারেন। সম্পর্কটি লক্ষ্য করুন: dp[i] = dp[i >> 1] + (i & 1)। i এর 1s এর সংখ্যা হল i কে ডানে স্থানান্তরিত করার (অর্থাৎ, i/2) 1s এর সংখ্যা, যদি i বিজোড় হয় তবে 1 যোগ করুন।

function countBits(n) { const dp = new Array(n + 1).fill(0); for (let i = 1; i <= n; i++) { dp[i] = dp[i >> 1] + (i & 1); // Or: dp[i] = dp[i & (i - 1)] + 1; (Removes last set bit) } return dp; } console.log(countBits(5)); // [0, 1, 1, 2, 1, 2]

দুই এর শক্তি

একটি পূর্ণসংখ্যা n দেওয়া আছে, যদি এটি দুই এর শক্তি হয় তবে true ফেরত দিন। অন্যথায়, false ফেরত দিন।

ব্যাখ্যা: বাইনারি উপস্থাপনায় দুই এর শক্তির ঠিক একটি '1' বিট থাকে (যেমন, 1=1, 2=10, 4=100, 8=1000)। একটি চতুর বিটওয়াইজ কৌশল হল n > 0 এবং (n & (n - 1)) === 0 কিনা তা পরীক্ষা করা। যদি n দুই এর শক্তি হয়, তাহলে n-1 এর সেই '1' এর নিচের সমস্ত বিট '1' এ সেট করা থাকবে। সেগুলিকে AND করলে 0 হবে।

function isPowerOfTwo(n) { return n > 0 && (n & (n - 1)) === 0; } console.log(isPowerOfTwo(16)); // true console.log(isPowerOfTwo(1)); // true console.log(isPowerOfTwo(18)); // false

ব্যবধান মার্জ করুন

intervals[i] = [starti, endi] যেখানে ইন্টারভালগুলির একটি অ্যারে দেওয়া আছে, সমস্ত ওভারল্যাপিং ইন্টারভালগুলিকে মার্জ করুন এবং অ-ওভারল্যাপিং ইন্টারভালগুলির একটি অ্যারে ফেরত দিন।

ব্যাখ্যা: প্রথমে, তাদের শুরুর সময় অনুসারে ইন্টারভালগুলিকে সাজান। তারপর, সাজানো ইন্টারভালগুলির মধ্য দিয়ে পুনরাবৃত্তি করুন। যদি বর্তমান ইন্টারভালটি ফলাফল তালিকার শেষ ইন্টারভালের সাথে ওভারল্যাপ করে, তবে শেষ ইন্টারভালের শেষের সময় আপডেট করে সেগুলিকে মার্জ করুন। অন্যথায়, বর্তমান ইন্টারভালটি ফলাফল তালিকায় যোগ করুন।

function mergeIntervals(intervals) { if (intervals.length === 0) return []; intervals.sort((a, b) => a[0] - b[0]); const merged = [intervals[0]]; for (let i = 1; i < intervals.length; i++) { const last = merged[merged.length - 1]; const current = intervals[i]; if (current[0] <= last[1]) { // Overlap: merge last[1] = Math.max(last[1], current[1]); } else { // No overlap: add new interval merged.push(current); } } return merged; } console.log(mergeIntervals([[1, 3], [2, 6], [8, 10], [15, 18]])); // [[1, 6], [8, 10], [15, 18]]

শব্দ বিরতি

একটি স্ট্রিং s এবং স্ট্রিং wordDict এর একটি অভিধান দেওয়া আছে, যদি s একটি বা একাধিক অভিধান শব্দের একটি স্থান-বিভক্ত ক্রম-এ বিভক্ত করা যায় তবে true ফেরত দিন।

ব্যাখ্যা: ডায়নামিক প্রোগ্রামিং ব্যবহার করুন। একটি বুলিয়ান অ্যারে dp তৈরি করুন যেখানে dp[i] সত্য হবে যদি সাবস্ট্রিং s[0...i-1] বিভক্ত করা যায়। dp[i] সত্য হবে যদি একটি j < i বিদ্যমান থাকে যেখানে dp[j] সত্য হয় এবং সাবস্ট্রিং s[j...i-1] অভিধানে থাকে।

function wordBreak(s, wordDict) { const wordSet = new Set(wordDict); const n = s.length; const dp = new Array(n + 1).fill(false); dp[0] = true; // Base case: empty string for (let i = 1; i <= n; i++) { for (let j = 0; j < i; j++) { if (dp[j] && wordSet.has(s.substring(j, i))) { dp[i] = true; break; } } } return dp[n]; } console.log(wordBreak('leetcode', ['leet', 'code'])); // true console.log(wordBreak('applepenapple', ['apple', 'pen'])); // true console.log(wordBreak('catsandog', ['cats', 'dog', 'sand', 'and', 'cat'])); // false

Array.prototype.flat প্রয়োগ করুন

আপনার নিজের Array.prototype.flat সংস্করণ প্রয়োগ করুন, যা একটি নির্দিষ্ট গভীরতা পর্যন্ত সমস্ত সাব-অ্যারে উপাদানগুলিকে পুনরাবৃত্তিমূলকভাবে সংযুক্ত করে একটি নতুন অ্যারে তৈরি করে।

ব্যাখ্যা: পুনরাবৃত্তি ব্যবহার করুন। অ্যারের মধ্য দিয়ে পুনরাবৃত্তি করুন। যদি একটি উপাদান একটি অ্যারে হয় এবং বর্তমান গভীরতা নির্দিষ্ট গভীরতার চেয়ে কম হয়, তবে এটিতে ফ্ল্যাটেনকে পুনরাবৃত্তিমূলকভাবে কল করুন। অন্যথায়, উপাদানটি পুশ করুন। ডিফল্ট গভীরতা 1 পরিচালনা করুন।

function myFlat(arr, depth = 1) { let flattened = []; arr.forEach(item => { if (Array.isArray(item) && depth > 0) { flattened.push(...myFlat(item, depth - 1)); } else { flattened.push(item); } }); return flattened; } console.log(myFlat([1, [2, [3, 4], 5], 6])); // [2, [3, 4], 5] console.log(myFlat([1, [2, [3, 4], 5], 6], 2)); // [1, 2, 3, 4, 5, 6]

একটি স্ট্রিংয়ের শব্দ উল্টান

একটি ইনপুট স্ট্রিং s দেওয়া আছে, শব্দগুলির ক্রম উল্টান।

ব্যাখ্যা: একটি 'শব্দ' অ-স্থান অক্ষরগুলির একটি ক্রম হিসাবে সংজ্ঞায়িত করা হয়। স্ট্রিংটি ট্রিম করুন, এটিকে এক বা একাধিক স্থান দ্বারা বিভক্ত করুন, একাধিক স্থান থেকে উৎপন্ন যে কোনও খালি স্ট্রিং ফিল্টার করুন, অ্যারেটি উল্টান এবং একক স্থান দিয়ে এটিকে পুনরায় সংযুক্ত করুন।

function reverseWords(s) { return s.trim().split(/\s+/).reverse().join(' '); } console.log(reverseWords('the sky is blue')); // 'blue is sky the' console.log(reverseWords(' hello world ')); // 'world hello' console.log(reverseWords('a good example')); // 'example good a'

কোয়েরি স্ট্রিং পার্সার

একটি URL কোয়েরি স্ট্রিংকে একটি অবজেক্টে পার্স করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: স্ট্রিংটিকে & দ্বারা বিভক্ত করুন। প্রতিটি অংশের জন্য, কী এবং মান পেতে = দ্বারা বিভক্ত করুন। কী এবং মান উভয়ের জন্য URI উপাদানগুলি ডিকোড করুন। এমন কেসগুলি হ্যান্ডেল করুন যেখানে একটি কী একাধিকবার প্রদর্শিত হতে পারে (একটি অ্যারে তৈরি করুন) বা এর কোনও মান নেই।

function parseQueryString(query) { if (query.startsWith('?')) { query = query.substring(1); } const result = {}; if (!query) return result; query.split('&').forEach(pair => { const [key, value] = pair.split('='); const decodedKey = decodeURIComponent(key); const decodedValue = value !== undefined ? decodeURIComponent(value) : true; if (result.hasOwnProperty(decodedKey)) { if (Array.isArray(result[decodedKey])) { result[decodedKey].push(decodedValue); } else { result[decodedKey] = [result[decodedKey], decodedValue]; } } else { result[decodedKey] = decodedValue; } }); return result; } console.log(parseQueryString('?foo=bar&baz=qux&baz=quux&corge')); // { foo: 'bar', baz: ['qux', 'quux'], corge: true }

যাচাইয়ের জন্য Proxy ব্যবহার করুন

বস্তুর সম্পত্তি যাচাইয়ের জন্য কিভাবে একটি Proxy অবজেক্ট ব্যবহার করতে হয় তা দেখান।

ব্যাখ্যা: একটি Proxy আপনাকে একটি বস্তুর উপর সম্পাদিত অপারেশনগুলি আটকে দিতে এবং কাস্টমাইজ করতে দেয়। একটি বৈশিষ্ট্যে মান বরাদ্দ করার আগে সেগুলি যাচাই করতে set ট্র্যাপ ব্যবহার করুন। যদি যাচাই ব্যর্থ হয় তবে একটি ত্রুটি নিক্ষেপ করুন।

const validator = { set: function(obj, prop, value) { if (prop === 'age') { if (!Number.isInteger(value)) { throw new TypeError('The age is not an integer'); } if (value < 0 || value > 150) { throw new RangeError('The age seems invalid'); } } // Default behavior: Set the property obj[prop] = value; return true; } }; const person = {}; const personProxy = new Proxy(person, validator); personProxy.age = 30; // OK console.log(personProxy.age); // 30 // personProxy.age = 'thirty'; // Throws TypeError // personProxy.age = 200; // Throws RangeError

মিটিং রুম

মিটিং সময় ব্যবধান [[start1, end1], [start2, end2], ...] এর একটি অ্যারে দেওয়া আছে, একজন ব্যক্তি সমস্ত মিটিংয়ে উপস্থিত থাকতে পারে কিনা তা নির্ধারণ করুন।

ব্যাখ্যা: যদি একজন ব্যক্তি সমস্ত মিটিংয়ে উপস্থিত থাকতে পারে, তবে এর অর্থ হল কোনও দুটি মিটিং ওভারল্যাপ করে না। এটি পরীক্ষা করার জন্য, তাদের শুরুর সময় অনুসারে ব্যবধানগুলি সাজান। তারপর, সাজানো ব্যবধানগুলির মধ্য দিয়ে পুনরাবৃত্তি করুন এবং বর্তমান মিটিংয়ের শুরুর সময় পূর্ববর্তী মিটিংয়ের শেষ সময়ের আগে কিনা তা পরীক্ষা করুন। যদি এটি হয়, তবে একটি ওভারল্যাপ আছে, এবং ব্যক্তি সমস্ত মিটিংয়ে উপস্থিত থাকতে পারবে না।

function canAttendMeetings(intervals) { if (intervals.length < 2) return true; intervals.sort((a, b) => a[0] - b[0]); for (let i = 1; i < intervals.length; i++) { if (intervals[i][0] < intervals[i - 1][1]) { return false; // Overlap detected } } return true; } console.log(canAttendMeetings([[0, 30], [5, 10], [15, 20]])); // false (5<30) console.log(canAttendMeetings([[7, 10], [2, 4]])); // true

Promise.any প্রয়োগ করুন

একটি ফাংশন প্রয়োগ করুন যা Promise.any এর মতো আচরণ করে।

ব্যাখ্যা: Promise.any প্রতিশ্রুতির একটি অ্যারে নেয় এবং একটি একক প্রতিশ্রুতি ফেরত দেয়। এই প্রতিশ্রুতি ইনপুট প্রতিশ্রুতিগুলির মধ্যে যেকোনও একটি পূরণ হওয়ার সাথে সাথেই পূরণ হয়। যদি সমস্ত ইনপুট প্রতিশ্রুতি প্রত্যাখ্যান করে, তবে এটি সমস্ত প্রত্যাখ্যান কারণগুলি ধারণকারী একটি AggregateError সহ প্রত্যাখ্যান করে।

function myPromiseAny(promises) { return new Promise((resolve, reject) => { const numPromises = promises.length; if (numPromises === 0) { reject(new AggregateError([], 'All promises were rejected')); return; } let rejectionCount = 0; const errors = []; promises.forEach((promise, index) => { Promise.resolve(promise) .then(resolve) // Resolve as soon as one fulfills .catch(error => { errors[index] = error; rejectionCount++; if (rejectionCount === numPromises) { reject(new AggregateError(errors, 'All promises were rejected')); } }); }); }); } // Example: myPromiseAny([Promise.reject('err1'), Promise.resolve('ok')]) -> 'ok' // Example: myPromiseAny([Promise.reject('err1'), Promise.reject('err2')]) -> AggregateError

পর্যবেক্ষক প্যাটার্ন

জাভাস্ক্রিপ্টে পর্যবেক্ষক (Pub/Sub) ডিজাইন প্যাটার্ন প্রয়োগ করুন।

ব্যাখ্যা: পর্যবেক্ষক প্যাটার্ন বস্তুগুলির মধ্যে একটি থেকে একাধিক নির্ভরতা সংজ্ঞায়িত করে। যখন একটি বস্তু (বিষয়) অবস্থা পরিবর্তন করে, তখন তার সমস্ত নির্ভরশীল (পর্যবেক্ষক) স্বয়ংক্রিয়ভাবে বিজ্ঞপ্তি পায় এবং আপডেট হয়। বিষয় পর্যবেক্ষকদের একটি তালিকা বজায় রাখে এবং তাদের যোগ, অপসারণ এবং বিজ্ঞপ্তি দেওয়ার পদ্ধতি সরবরাহ করে।

class Subject { constructor() { this.observers = []; } subscribe(observer) { this.observers.push(observer); } unsubscribe(observer) { this.observers = this.observers.filter(obs => obs !== observer); } notify(data) { this.observers.forEach(observer => observer.update(data)); } } class Observer { constructor(name) { this.name = name; } update(data) { console.log(`${this.name} received: ${data}`); } } const subject = new Subject(); const obs1 = new Observer('Observer 1'); const obs2 = new Observer('Observer 2'); subject.subscribe(obs1); subject.subscribe(obs2); subject.notify('Something happened!'); // Observer 1 received: Something happened! // Observer 2 received: Something happened!

ডুপ্লিকেট নম্বর খুঁজুন

n + 1 পূর্ণসংখ্যা সমন্বিত nums পূর্ণসংখ্যাগুলির একটি অ্যারে দেওয়া আছে যেখানে প্রতিটি পূর্ণসংখ্যা [1, n] অন্তর্ভুক্তিতে রয়েছে, একটি পুনরাবৃত্ত সংখ্যা খুঁজুন।

ব্যাখ্যা: যেহেতু সংখ্যাগুলি [1, n] তে রয়েছে এবং অ্যারের আকার n+1, এটি কমপক্ষে একটি ডুপ্লিকেট নিশ্চিত করে। এটি 'লিঙ্কড লিস্টে সাইকেল খুঁজুন' সমস্যায় ম্যাপ করা যেতে পারে (ফ্লয়েডের টর্টোজ এবং হেয়ার)। অ্যারের মানগুলিকে পয়েন্টার হিসাবে বিবেচনা করুন: index -> nums[index]।

function findDuplicate(nums) { let tortoise = nums[0]; let hare = nums[0]; // Phase 1: Find the intersection point do { tortoise = nums[tortoise]; hare = nums[nums[hare]]; } while (tortoise !== hare); // Phase 2: Find the entrance to the cycle let ptr1 = nums[0]; let ptr2 = tortoise; while (ptr1 !== ptr2) { ptr1 = nums[ptr1]; ptr2 = nums[ptr2]; } return ptr1; } console.log(findDuplicate([1, 3, 4, 2, 2])); // 2 console.log(findDuplicate([3, 1, 3, 4, 2])); // 3

বেসিক HTML স্যানিটাইজার

একটি HTML স্ট্রিংকে স্যানিটাইজ করার জন্য একটি মৌলিক ফাংশন লিখুন, সম্ভাব্য ক্ষতিকারক ট্যাগগুলি (যেমন <script>) সরিয়ে ফেলুন যখন নিরাপদ ট্যাগগুলি (যেমন <p>, <b>) রেখে দিন।

ব্যাখ্যা: এটি একটি জটিল বিষয়, এবং বাস্তব-বিশ্বের স্যানিটাইজারগুলি পরিশীলিত। একটি সাক্ষাত্কারের জন্য, একটি মৌলিক পদ্ধতির মধ্যে নির্দিষ্ট ট্যাগগুলি সরাতে বা ট্যাগগুলির একটি শ্বেত তালিকা অনুমোদনের জন্য রেগেক্স ব্যবহার করা জড়িত থাকতে পারে। এটি উৎপাদনের জন্য নিরাপদ নয়।

function basicSanitize(html) { // WARNING: This is a very basic and insecure example. // Do NOT use this in production. Use a library like DOMPurify. // Remove script tags let sanitized = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, ''); // Example: Remove onclick attributes (very basic) sanitized = sanitized.replace(/\s(on\w+)=['"]?[^'"]*['"]?/gi, ''); return sanitized; } console.log(basicSanitize('<p>Hello <script>alert("XSS")</script> <b onclick="danger()">World</b></p>')); // <p>Hello <b >World</b></p>

দূরত্ব সম্পাদনা করুন

দুটি স্ট্রিং word1 এবং word2 দেওয়া আছে, word1 কে word2 তে রূপান্তর করার জন্য প্রয়োজনীয় সর্বনিম্ন সংখ্যক অপারেশন (সন্নিবেশ, মুছে ফেলা, বা প্রতিস্থাপন) ফেরত দিন।

ব্যাখ্যা: এটি একটি ক্লাসিক ডায়নামিক প্রোগ্রামিং সমস্যা (লেভেনস্টেইন দূরত্ব)। একটি 2D অ্যারে dp তৈরি করুন যেখানে dp[i][j] হল word1 এর প্রথম i অক্ষরের এবং word2 এর প্রথম j অক্ষরের মধ্যে সম্পাদনার দূরত্ব। পুনরাবৃত্তির সম্পর্কটিতে সন্নিবেশ, মুছে ফেলা এবং প্রতিস্থাপনের ব্যয় বিবেচনা করা জড়িত।

function minDistance(word1, word2) { const m = word1.length, n = word2.length; const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0)); for (let i = 0; i <= m; i++) dp[i][0] = i; for (let j = 0; j <= n; j++) dp[0][j] = j; for (let i = 1; i <= m; i++) { for (let j = 1; j <= n; j++) { const cost = word1[i - 1] === word2[j - 1] ? 0 : 1; dp[i][j] = Math.min( dp[i - 1][j] + 1, // Deletion dp[i][j - 1] + 1, // Insertion dp[i - 1][j - 1] + cost // Substitution/Match ); } } return dp[m][n]; } console.log(minDistance('horse', 'ros')); // 3 console.log(minDistance('intention', 'execution')); // 5

দীর্ঘতম ক্রমবর্ধমান সাবসিকোয়েন্স (LIS)

একটি পূর্ণসংখ্যা অ্যারে nums দেওয়া আছে, কঠোরভাবে ক্রমবর্ধমান সাবসিকোয়েন্সের দীর্ঘতম দৈর্ঘ্য ফেরত দিন।

ব্যাখ্যা: ডায়নামিক প্রোগ্রামিং ব্যবহার করুন। dp[i] কে সূচক i এ শেষ হওয়া LIS এর দৈর্ঘ্য হতে দিন। dp[i] গণনা করতে, সমস্ত j < i খুঁজুন যাতে nums[j] < nums[i] হয়, এবং dp[i] = 1 + max(dp[j]) নিন। চূড়ান্ত উত্তর হল dp অ্যারের সর্বোচ্চ মান।

function lengthOfLIS(nums) { if (nums.length === 0) return 0; const n = nums.length; const dp = new Array(n).fill(1); let maxLength = 1; for (let i = 1; i < n; i++) { for (let j = 0; j < i; j++) { if (nums[i] > nums[j]) { dp[i] = Math.max(dp[i], dp[j] + 1); } } maxLength = Math.max(maxLength, dp[i]); } return maxLength; } console.log(lengthOfLIS([10, 9, 2, 5, 3, 7, 101, 18])); // 4 (2, 3, 7, 101)

N-কুইনস সমস্যা

N-কুইনস ধাঁধা হল N×N দাবাবোর্ডে Nটি দাবা কুইন স্থাপন করার সমস্যা যাতে কোনও দুটি কুইন একে অপরকে হুমকি না দেয়। N দেওয়া আছে, একটি বৈধ সমাধান (বা সব) ফেরত দিন।

ব্যাখ্যা: ব্যাকট্র্যাকিং ব্যবহার করুন। সারি অনুসারে কুইন স্থাপন করুন। প্রতিটি সারির জন্য, প্রতিটি কলামে একটি কুইন স্থাপন করার চেষ্টা করুন। স্থাপনের আগে, প্রস্তাবিত অবস্থানটি নিরাপদ কিনা তা পরীক্ষা করুন (পূর্ববর্তী সারিগুলিতে কুইন দ্বারা আক্রান্ত নয়)। যদি নিরাপদ হয়, তবে এটি স্থাপন করুন এবং পরবর্তী সারির জন্য পুনরাবৃত্তি করুন। যদি পুনরাবৃত্তি ব্যর্থ হয়, তবে ব্যাকট্র্যাক করুন (কুইনটি সরান) এবং পরবর্তী কলাম চেষ্টা করুন।

function solveNQueens(n) { const results = []; const board = Array(n).fill('.').map(() => Array(n).fill('.')); function isSafe(row, col) { for (let i = 0; i < row; i++) if (board[i][col] === 'Q') return false; // Check col for (let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) if (board[i][j] === 'Q') return false; // Check diag up-left for (let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) if (board[i][j] === 'Q') return false; // Check diag up-right return true; } function backtrack(row) { if (row === n) { results.push(board.map(r => r.join(''))); return; } for (let col = 0; col < n; col++) { if (isSafe(row, col)) { board[row][col] = 'Q'; backtrack(row + 1); board[row][col] = '.'; // Backtrack } } } backtrack(0); return results; } console.log(solveNQueens(4)); // [ [ '.Q..', '...Q', 'Q...', '..Q.' ], [ '..Q.', 'Q...', '...Q', '.Q..' ] ]

ব্যক্তিগত ডেটার জন্য WeakMap ব্যবহার করুন

ক্লাস ইনস্ট্যান্সের জন্য ব্যক্তিগত ডেটা সংরক্ষণ করতে WeakMap কিভাবে ব্যবহার করতে হয় তা দেখান।

ব্যাখ্যা: WeakMap আপনাকে একটি বস্তুর সাথে ডেটা সংযুক্ত করার অনুমতি দেয় এমনভাবে যা বস্তুর আর উল্লেখ না থাকলে গার্বেজ সংগ্রহকে বাধা দেয় না। নেটিভ ব্যক্তিগত ক্ষেত্রগুলি ব্যাপকভাবে উপলব্ধ হওয়ার আগে বা নির্দিষ্ট ব্যবহারের ক্ষেত্রে জাভাস্ক্রিপ্ট ক্লাসগুলিতে 'ব্যক্তিগত' সদস্য তৈরি করার জন্য এটি দরকারী।

const privateData = new WeakMap(); class Person { constructor(name, age) { privateData.set(this, { name: name, age: age }); } getName() { return privateData.get(this).name; } getAge() { return privateData.get(this).age; } celebrateBirthday() { privateData.get(this).age++; } } const person = new Person('Alice', 30); console.log(person.getName()); // Alice person.celebrateBirthday(); console.log(person.getAge()); // 31 // console.log(person.name); // undefined - 'name' isn't a public property // console.log(privateData.get(person)); // Accessible, but not directly via 'person.'

Promise.allSettled প্রয়োগ করুন

একটি ফাংশন প্রয়োগ করুন যা Promise.allSettled এর মতো আচরণ করে।

ব্যাখ্যা: Promise.allSettled প্রতিশ্রুতির একটি অ্যারে নেয় এবং একটি একক প্রতিশ্রুতি ফেরত দেয়। এই প্রতিশ্রুতি পূরণ হয় যখন সমস্ত ইনপুট প্রতিশ্রুতি নিষ্পত্তি হয় (হয় পূরণ বা প্রত্যাখ্যান)। পূরণের মান হল বস্তুগুলির একটি অ্যারে, প্রতিটি একটি প্রতিশ্রুতির ফলাফল বর্ণনা করে ({status: 'fulfilled', value: ...} বা {status: 'rejected', reason: ...})।

function myPromiseAllSettled(promises) { return new Promise((resolve) => { const numPromises = promises.length; const results = []; let settledCount = 0; if (numPromises === 0) { resolve([]); return; } promises.forEach((promise, index) => { Promise.resolve(promise) .then(value => { results[index] = { status: 'fulfilled', value: value }; }) .catch(reason => { results[index] = { status: 'rejected', reason: reason }; }) .finally(() => { settledCount++; if (settledCount === numPromises) { resolve(results); } }); }); }); } // Example: myPromiseAllSettled([Promise.resolve(1), Promise.reject('err')]) // -> [{status: 'fulfilled', value: 1}, {status: 'rejected', reason: 'err'}]

দুটি সাজানো অ্যারের মধ্যক খুঁজুন

দুটি সাজানো অ্যারে nums1 এবং nums2 যথাক্রমে m এবং n আকারের দেওয়া আছে, দুটি সাজানো অ্যারের মধ্যক ফেরত দিন।

ব্যাখ্যা: এটি একটি কঠিন সমস্যা যা প্রায়শই ছোট অ্যারের উপর বাইনারি অনুসন্ধান পদ্ধতি ব্যবহার করে সমাধান করা হয়। লক্ষ্য হল উভয় অ্যারে পার্টিশন করা যাতে বাম দিকের সমস্ত উপাদান ডান দিকের সমস্ত উপাদানের চেয়ে কম বা সমান হয় এবং বাম দিকের উপাদানগুলির সংখ্যা ডানদিকের সমান (বা একটি বেশি)। মধ্যক তখন সীমানা উপাদানগুলি থেকে গণনা করা যেতে পারে।

function findMedianSortedArrays(nums1, nums2) { if (nums1.length > nums2.length) [nums1, nums2] = [nums2, nums1]; // Ensure nums1 is smaller const m = nums1.length, n = nums2.length; let low = 0, high = m; while (low <= high) { const partitionX = Math.floor((low + high) / 2); const partitionY = Math.floor((m + n + 1) / 2) - partitionX; const maxX = (partitionX === 0) ? -Infinity : nums1[partitionX - 1]; const minX = (partitionX === m) ? Infinity : nums1[partitionX]; const maxY = (partitionY === 0) ? -Infinity : nums2[partitionY - 1]; const minY = (partitionY === n) ? Infinity : nums2[partitionY]; if (maxX <= minY && maxY <= minX) { if ((m + n) % 2 === 0) { return (Math.max(maxX, maxY) + Math.min(minX, minY)) / 2; } else { return Math.max(maxX, maxY); } } else if (maxX > minY) { high = partitionX - 1; } else { low = partitionX + 1; } } throw new Error('Input arrays are not sorted'); } console.log(findMedianSortedArrays([1, 3], [2])); // 2.0 console.log(findMedianSortedArrays([1, 2], [3, 4])); // 2.5

সুডোকু সমাধানকারী

খালি ঘর পূরণ করে একটি সুডোকু ধাঁধা সমাধান করার জন্য একটি প্রোগ্রাম লিখুন।

ব্যাখ্যা: ব্যাকট্র্যাকিং ব্যবহার করুন। একটি খালি ঘর খুঁজুন। 1 থেকে 9 পর্যন্ত সংখ্যা দিয়ে এটি পূরণ করার চেষ্টা করুন। প্রতিটি সংখ্যার জন্য, এটি বৈধ কিনা তা পরীক্ষা করুন (সুডোকু নিয়ম লঙ্ঘন করে না)। যদি বৈধ হয়, পুনরাবৃত্তিমূলকভাবে সমাধানকারীকে কল করুন। যদি পুনরাবৃত্তি সত্য ফেরত দেয়, একটি সমাধান পাওয়া যায়। যদি না হয়, তবে ব্যাকট্র্যাক করুন (ঘরটি রিসেট করুন) এবং পরবর্তী সংখ্যা চেষ্টা করুন।

function solveSudoku(board) { function isValid(row, col, numStr) { for (let i = 0; i < 9; i++) { if (board[row][i] === numStr) return false; // Check row if (board[i][col] === numStr) return false; // Check col const boxRow = 3 * Math.floor(row / 3) + Math.floor(i / 3); const boxCol = 3 * Math.floor(col / 3) + i % 3; if (board[boxRow][boxCol] === numStr) return false; // Check box } return true; } function backtrack() { for (let r = 0; r < 9; r++) { for (let c = 0; c < 9; c++) { if (board[r][c] === '.') { for (let n = 1; n <= 9; n++) { const numStr = String(n); if (isValid(r, c, numStr)) { board[r][c] = numStr; if (backtrack()) return true; board[r][c] = '.'; // Backtrack } } return false; // No valid number found } } } return true; // Board solved } backtrack(); return board; } // Example requires a 9x9 board with '.' for empty cells.

একটি মৌলিক মিডলওয়্যার প্যাটার্ন প্রয়োগ করুন

ওয়েব ফ্রেমওয়ার্কগুলিতে প্রায়শই দেখা যায় এমন একটি সাধারণ মিডলওয়্যার প্যাটার্ন প্রয়োগ করুন।

ব্যাখ্যা: মিডলওয়্যার ফাংশনগুলি চূড়ান্ত হ্যান্ডলারে পৌঁছানোর আগে একটি অনুরোধ প্রক্রিয়া করে। প্রতিটি মিডলওয়্যার অনুরোধ/প্রতিক্রিয়া পরিবর্তন করতে পারে বা পরবর্তী মিডলওয়্যারে নিয়ন্ত্রণ পাস করতে পারে। একটি ক্লাস বা অবজেক্ট তৈরি করুন যা মিডলওয়্যার ফাংশনগুলির একটি তালিকা পরিচালনা করে এবং সেগুলিকে ক্রমানুসারে কার্যকর করে।

class App { constructor() { this.middlewares = []; } use(fn) { this.middlewares.push(fn); } handle(request) { let index = 0; const next = () => { if (index < this.middlewares.length) { const middleware = this.middlewares[index++]; middleware(request, next); } }; next(); } } const app = new App(); app.use((req, next) => { console.log('1: Logging...'); req.logged = true; next(); }); app.use((req, next) => { console.log('2: Authenticating...'); req.authed = true; next(); }); app.use((req, next) => { console.log('3: Final Handler:', req); }); app.handle({ data: 'some request' }); // 1: Logging... // 2: Authenticating... // 3: Final Handler: { data: 'some request', logged: true, authed: true }

নির্দেশিত গ্রাফে চক্র সনাক্ত করুন

একটি নির্দেশিত গ্রাফ দেওয়া আছে, এতে একটি চক্র আছে কিনা তা নির্ধারণ করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: গভীরতা-প্রথম অনুসন্ধান (DFS) ব্যবহার করুন। দুটি সেট বজায় রাখুন: visiting (বর্তমানে রিকার্সন স্ট্যাকে থাকা নোডগুলি) এবং visited (সম্পূর্ণরূপে অন্বেষণ করা নোডগুলি)। DFS চলাকালীন যদি আপনি visiting সেটে একটি নোডের সম্মুখীন হন, তবে আপনি একটি ব্যাক এজ খুঁজে পেয়েছেন, যার অর্থ একটি চক্র রয়েছে।

function hasCycleDirected(graph) { const visiting = new Set(); const visited = new Set(); const nodes = Object.keys(graph); function dfs(node) { visiting.add(node); for (const neighbor of graph[node]) { if (visiting.has(neighbor)) return true; // Cycle detected if (!visited.has(neighbor)) { if (dfs(neighbor)) return true; } } visiting.delete(node); visited.add(node); return false; } for (const node of nodes) { if (!visited.has(node)) { if (dfs(node)) return true; } } return false; } const cyclicGraph = { A: ['B'], B: ['C'], C: ['A'] }; const acyclicGraph = { A: ['B', 'C'], B: ['D'], C: ['E'], D: [], E: [] }; console.log(hasCycleDirected(cyclicGraph)); // true console.log(hasCycleDirected(acyclicGraph)); // false

Object.freeze আচরণ প্রয়োগ করুন

Object.freeze ব্যাখ্যা করুন এবং একটি (অগভীর) সংস্করণ প্রয়োগ করুন।

ব্যাখ্যা: Object.freeze নতুন বৈশিষ্ট্য যোগ করা, বিদ্যমান বৈশিষ্ট্য অপসারণ করা, এবং বিদ্যমান বৈশিষ্ট্য বা তাদের গণনাযোগ্যতা, কনফিগারযোগ্যতা, বা লেখযোগ্যতা পরিবর্তন করা থেকে বাধা দেয়। এটি একটি বস্তুকে অপরিবর্তনীয় (অগভীরভাবে) করে তোলে। আপনি Object.preventExtensions এবং Object.defineProperty ব্যবহার করে বিদ্যমান বৈশিষ্ট্যগুলিকে অ-লেখযোগ্য এবং অ-কনফিগারযোগ্য করে এটি প্রয়োগ করতে পারেন।

function myFreeze(obj) { Object.preventExtensions(obj); // Prevent adding new properties Object.keys(obj).forEach(key => { Object.defineProperty(obj, key, { writable: false, configurable: false }); }); return obj; } const obj = { a: 1, b: 2 }; myFreeze(obj); // obj.c = 3; // Fails silently (or throws in strict mode) // delete obj.a; // Fails silently (or throws in strict mode) // obj.a = 10; // Fails silently (or throws in strict mode) console.log(obj); // { a: 1, b: 2 }

মসৃণ অ্যানিমেশনের জন্য requestAnimationFrame ব্যবহার করুন

requestAnimationFrame ব্যাখ্যা করুন এবং একটি সাধারণ অ্যানিমেশন লুপের জন্য এটি কীভাবে ব্যবহার করবেন তা দেখান।

ব্যাখ্যা: requestAnimationFrame (rAF) ব্রাউজারকে বলে যে আপনি একটি অ্যানিমেশন সম্পাদন করতে চান এবং পরবর্তী রিপেইন্টের আগে একটি নির্দিষ্ট ফাংশনকে অ্যানিমেশন আপডেট করার জন্য কল করার জন্য ব্রাউজারকে অনুরোধ করে। এটি অ্যানিমেশনের জন্য setTimeout বা setInterval ব্যবহার করার চেয়ে বেশি দক্ষ এবং মসৃণ, কারণ এটি ব্রাউজারের রিফ্রেশ রেটের সাথে সিঙ্ক করে এবং ট্যাব দৃশ্যমান না হলে বিরতি দেয়।

// HTML: <div id='box' style='width: 50px; height: 50px; background: red; position: absolute; left: 0px;'></div> const box = document.getElementById('box'); let position = 0; let startTime = null; function animate(currentTime) { if (!startTime) startTime = currentTime; const elapsedTime = currentTime - startTime; // Move 100px in 2 seconds (50px/sec) position = (elapsedTime / 2000) * 100; if (position < 200) { // Keep animating until it reaches 200px box.style.left = position + 'px'; requestAnimationFrame(animate); } else { box.style.left = '200px'; } } // Start the animation // requestAnimationFrame(animate); // Uncomment to run in browser console.log('Use requestAnimationFrame for browser animations.');

Array.prototype.some প্রয়োগ করুন

আপনার নিজস্ব Array.prototype.some সংস্করণ প্রয়োগ করুন।

ব্যাখ্যা: some প্রদত্ত ফাংশন দ্বারা প্রয়োগ করা পরীক্ষায় অ্যারের কমপক্ষে একটি উপাদান পাস করে কিনা তা পরীক্ষা করে। যদি এটি এমন একটি উপাদান খুঁজে পায় যার জন্য কলব্যাক true ফেরত দেয়; অন্যথায়, এটি false ফেরত দেয়।

function mySome(arr, callback, thisArg) { for (let i = 0; i < arr.length; i++) { if (i in arr) { // Handle sparse arrays if (callback.call(thisArg, arr[i], i, arr)) { return true; } } } return false; } const arr = [1, 2, 3, 4, 5]; const hasEven = mySome(arr, x => x % 2 === 0); console.log(hasEven); // true

Array.prototype.every প্রয়োগ করুন

আপনার নিজস্ব Array.prototype.every সংস্করণ প্রয়োগ করুন।

ব্যাখ্যা: every প্রদত্ত ফাংশন দ্বারা প্রয়োগ করা পরীক্ষায় অ্যারের সমস্ত উপাদান পাস করে কিনা তা পরীক্ষা করে। যদি সমস্ত উপাদান পাস করে (বা অ্যারে খালি থাকে), তবে এটি true ফেরত দেয় এবং যদি কোনও উপাদান ব্যর্থ হয় তবে false ফেরত দেয়।

function myEvery(arr, callback, thisArg) { for (let i = 0; i < arr.length; i++) { if (i in arr) { if (!callback.call(thisArg, arr[i], i, arr)) { return false; } } } return true; } const arr1 = [1, 30, 39, 29, 10, 13]; const isBelow40 = myEvery(arr1, x => x < 40); console.log(isBelow40); // true const arr2 = [1, 30, 39, 29, 10, 45]; const isBelow40_2 = myEvery(arr2, x => x < 40); console.log(isBelow40_2); // false

Array.prototype.findIndex প্রয়োগ করুন

আপনার নিজস্ব Array.prototype.findIndex সংস্করণ প্রয়োগ করুন।

ব্যাখ্যা: findIndex প্রদত্ত টেস্টিং ফাংশনটি পূরণ করে এমন অ্যারের প্রথম উপাদানের সূচক ফেরত দেয়। অন্যথায়, এটি -1 ফেরত দেয়, যা নির্দেশ করে যে কোনও উপাদান পরীক্ষাটি পাস করেনি।

function myFindIndex(arr, callback, thisArg) { for (let i = 0; i < arr.length; i++) { if (i in arr) { if (callback.call(thisArg, arr[i], i, arr)) { return i; } } } return -1; } const arr = [5, 12, 8, 130, 44]; const isLargeNumber = (element) => element > 13; console.log(myFindIndex(arr, isLargeNumber)); // 3

ওয়েব ওয়ার্কার্স কি?

ওয়েব ওয়ার্কার্স কি এবং তাদের প্রাথমিক ব্যবহারের ক্ষেত্র ব্যাখ্যা করুন।

ব্যাখ্যা: ওয়েব ওয়ার্কার্স হল ওয়েব বিষয়বস্তু ব্যাকগ্রাউন্ড থ্রেডে স্ক্রিপ্ট চালানোর একটি মাধ্যম। প্রধান ব্যবহারের ক্ষেত্র হল প্রধান থ্রেড (যা UI আপডেট এবং ব্যবহারকারীর ইন্টারঅ্যাকশন পরিচালনা করে) থেকে দীর্ঘমেয়াদী বা গণনাগতভাবে নিবিড় কাজগুলি অফলোড করা, যার ফলে UI প্রতিক্রিয়াহীন বা 'ফ্রিজ' হওয়া থেকে রক্ষা পায়। ওয়ার্কার্স postMessage এবং onmessage এর মাধ্যমে প্রধান থ্রেডের সাথে যোগাযোগ করে।

// main.js /* if (window.Worker) { const myWorker = new Worker('worker.js'); myWorker.postMessage([5, 3]); // Send data to worker myWorker.onmessage = function(e) { console.log('Result from worker:', e.data); } } else { console.log('Your browser does not support Web Workers.'); } */ // worker.js /* self.onmessage = function(e) { console.log('Message received from main script'); const result = e.data[0] * e.data[1]; console.log('Posting result back to main script'); self.postMessage(result); } */ console.log('Web Workers run scripts in background threads.');

ডিকোড উপায়

A-Z থেকে অক্ষর ধারণকারী একটি বার্তা ম্যাপিং A -> 1, B -> 2, ..., Z -> 26 ব্যবহার করে সংখ্যায় এনকোড করা যেতে পারে। শুধুমাত্র সংখ্যা ধারণকারী একটি স্ট্রিং s দেওয়া আছে, এটি ডিকোড করার উপায়গুলির সংখ্যা ফেরত দিন।

ব্যাখ্যা: ডায়নামিক প্রোগ্রামিং ব্যবহার করুন। dp[i] কে s[0...i-1] ডিকোড করার উপায়গুলির সংখ্যা হতে দিন। dp[i] dp[i-1] (যদি s[i-1] একটি বৈধ 1-সংখ্যার কোড হয়) এবং dp[i-2] (যদি s[i-2...i-1] একটি বৈধ 2-সংখ্যার কোড হয়) এর উপর নির্ভর করে।

function numDecodings(s) { if (!s || s[0] === '0') return 0; const n = s.length; const dp = new Array(n + 1).fill(0); dp[0] = 1; dp[1] = 1; for (let i = 2; i <= n; i++) { const oneDigit = parseInt(s.substring(i - 1, i)); const twoDigits = parseInt(s.substring(i - 2, i)); if (oneDigit >= 1) { dp[i] += dp[i - 1]; } if (twoDigits >= 10 && twoDigits <= 26) { dp[i] += dp[i - 2]; } } return dp[n]; } console.log(numDecodings('12')); // 2 ('AB' or 'L') console.log(numDecodings('226')); // 3 ('BBF', 'BZ', 'VF') console.log(numDecodings('06')); // 0

বিটওয়াইজ সংযোজন (+ ছাড়া)

  • অপারেটর ব্যবহার না করে দুটি পূর্ণসংখ্যা যোগ করার জন্য একটি ফাংশন লিখুন।

ব্যাখ্যা: বিটওয়াইজ অপারেটর ব্যবহার করুন। যোগফল a ^ b (ক্যারি ছাড়া যোগফল) হিসাবে গণনা করা যেতে পারে, এবং ক্যারি (a & b) << 1 হিসাবে গণনা করা যেতে পারে। ক্যারি 0 না হওয়া পর্যন্ত এই প্রক্রিয়াটি পুনরাবৃত্তি করুন।

function getSum(a, b) { while (b !== 0) { const carry = (a & b) << 1; // Calculate carry a = a ^ b; // Calculate sum without carry b = carry; // Carry becomes the new 'b' } return a; } console.log(getSum(3, 5)); // 8 console.log(getSum(-2, 3)); // 1

প্যালিনড্রোম পরীক্ষা করুন (সংখ্যা)

একটি পূর্ণসংখ্যা x দেওয়া আছে, যদি x একটি প্যালিনড্রোম হয় তবে true ফেরত দিন, এবং অন্যথায় false ফেরত দিন।

ব্যাখ্যা: একটি ঋণাত্মক সংখ্যা প্যালিনড্রোম নয়। সংখ্যাটিকে একটি স্ট্রিং-এ রূপান্তর করুন এবং স্ট্রিংটি একটি প্যালিনড্রোম কিনা তা পরীক্ষা করুন (সামনে এবং পিছনে একই রকম পড়ে)। বিকল্পভাবে, সংখ্যাটিকে গাণিতিকভাবে উল্টান এবং তুলনা করুন।

function isPalindromeNumber(x) { if (x < 0) return false; // String approach // return String(x) === String(x).split('').reverse().join(''); // Mathematical approach let original = x; let reversed = 0; while (x > 0) { reversed = reversed * 10 + (x % 10); x = Math.floor(x / 10); } return original === reversed; } console.log(isPalindromeNumber(121)); // true console.log(isPalindromeNumber(-121)); // false console.log(isPalindromeNumber(10)); // false

ফ্যাক্টরি প্যাটার্ন

জাভাস্ক্রিপ্টে ফ্যাক্টরি ডিজাইন প্যাটার্ন প্রয়োগ করুন।

ব্যাখ্যা: ফ্যাক্টরি প্যাটার্ন একটি সুপারক্লাসে অবজেক্ট তৈরির জন্য একটি ইন্টারফেস সরবরাহ করে, তবে সাবক্লাসগুলিকে তৈরি করা অবজেক্টগুলির ধরন পরিবর্তন করতে দেয়। এটি সঠিক ক্লাস নির্দিষ্ট না করে অবজেক্ট তৈরির জন্য দরকারী।

class Car { constructor(options) { this.type = 'Car'; this.doors = options.doors || 4; } } class Truck { constructor(options) { this.type = 'Truck'; this.bedSize = options.bedSize || 'long'; } } class VehicleFactory { createVehicle(options) { if (options.vehicleType === 'car') { return new Car(options); } else if (options.vehicleType === 'truck') { return new Truck(options); } else { throw new Error('Unknown vehicle type'); } } } const factory = new VehicleFactory(); const car = factory.createVehicle({ vehicleType: 'car', doors: 2 }); const truck = factory.createVehicle({ vehicleType: 'truck', bedSize: 'short' }); console.log(car); // Car { type: 'Car', doors: 2 } console.log(truck); // Truck { type: 'Truck', bedSize: 'short' }

Symbol এবং একটি ব্যবহারের ক্ষেত্র ব্যাখ্যা করুন

জাভাস্ক্রিপ্টে Symbol কি তা ব্যাখ্যা করুন এবং একটি ব্যবহারের ক্ষেত্র সরবরাহ করুন, যেমন 'ব্যক্তিগত' বৈশিষ্ট্য বা অনন্য অবজেক্ট কী তৈরি করা।

ব্যাখ্যা: Symbol হল ES6-এ প্রবর্তিত একটি আদিম ডেটা টাইপ। এর ইনস্ট্যান্সগুলি অনন্য এবং অপরিবর্তনীয়। এগুলি প্রায়শই বিভিন্ন লাইব্রেরির মধ্যে নাম সংঘর্ষ এড়াতে বা ছদ্ম-ব্যক্তিগত বৈশিষ্ট্য তৈরি করতে (যদিও সত্যই ব্যক্তিগত নয়, এগুলি সাধারণ পুনরাবৃত্তি বা Object.keys এর মাধ্যমে অ্যাক্সেসযোগ্য নয়) অবজেক্ট বৈশিষ্ট্যগুলির জন্য কী হিসাবে ব্যবহৃত হয়।

const _privateName = Symbol('name'); const _privateMethod = Symbol('greet'); class Person { constructor(name) { this[_privateName] = name; } [_privateMethod]() { console.log(`Hello, my name is ${this[_privateName]}`); } introduce() { this[_privateMethod](); } } const p = new Person('Bob'); p.introduce(); // Hello, my name is Bob console.log(Object.keys(p)); // [] - Symbols are not included console.log(p[_privateName]); // Bob (Accessible if you have the Symbol)

arguments কে একটি বাস্তব অ্যারেতে রূপান্তর করুন

আপনি কিভাবে arguments অবজেক্টকে (অ-অ্যারো ফাংশনে উপলব্ধ) একটি বাস্তব জাভাস্ক্রিপ্ট অ্যারেতে রূপান্তর করতে পারেন?

ব্যাখ্যা: arguments অবজেক্টটি একটি অ্যারের মতো দেখায় তবে এটি একটি নয়; এটি map, filter ইত্যাদির মতো পদ্ধতিগুলির অভাব। আপনি এটি ব্যবহার করে রূপান্তর করতে পারেন:

  1. Array.from(arguments) (ES6)
  2. [...arguments] (ES6 স্প্রেড সিনট্যাক্স)
  3. Array.prototype.slice.call(arguments) (পুরানো উপায়)
function sumAll() { // 1. Array.from const args1 = Array.from(arguments); console.log('Using Array.from:', args1.reduce((a, b) => a + b, 0)); // 2. Spread Syntax const args2 = [...arguments]; console.log('Using Spread:', args2.reduce((a, b) => a + b, 0)); // 3. Slice const args3 = Array.prototype.slice.call(arguments); console.log('Using Slice:', args3.reduce((a, b) => a + b, 0)); } sumAll(1, 2, 3, 4); // Using Array.from: 10 // Using Spread: 10 // Using Slice: 10