আমি একটি শাখা লেখার চেষ্টা করছি এবং সমস্ত ফাংশনের সেটে অনুসন্ধান সীমাবদ্ধ করব: ডি -> আর, যেখানে ডোমেনের আকার ছোট (| ডি | ~ 20) এবং পরিসরটি অনেক বড় (| আর | ~ 2 ^ 20) )। প্রাথমিকভাবে, আমি নিম্নলিখিত সমাধান নিয়ে এসেছি।
(builder (domain range condlist partial-map)
(let ((passed? (check condlist partial-map)))
(cond
((not passed?) nil)
(domain (recur-on-first domain range condlist partial-map '()))
(t partial-map))))
(recur-on-first (domain range condlist partial-map ignored)
(cond
((null range) nil)
(t (let ((first-to-first
(builder (cdr domain)
(append ignored (cdr range))
condlist
(cons (cons (car domain) (car range)) partial-map))))
(or first-to-first
(recur-on-first domain
(cdr range)
condlist
partial-map
(cons (car range) ignored))))))))
এখানে condlist
ফাংশনের পরামিতি builder
শর্তগুলির একটি তালিকা যা কোনও সমাধান দ্বারা সন্তুষ্ট হওয়া উচিত। check
শর্তগুলির তালিকার কোনও উপাদান যদি লঙ্ঘন করে তবে ফাংশনটি শূন্য করে partial-map
। ফাংশনটি recur-on-first
ডোমেনের প্রথম উপাদানটিকে ব্যাপ্তির প্রথম উপাদানকে নির্ধারণ করে এবং সেখান থেকে একটি সমাধান তৈরির চেষ্টা করে। এটি ব্যর্থ হওয়া recur-on-first
নিজেকে চেষ্টা করে এমন একটি সমাধান তৈরি করতে অনুরোধ করে যা ডোমেনের প্রথম উপাদানটিকে প্রথম শ্রেণীর মধ্যে ব্যয় ছাড়া অন্য কোনও উপাদানকে নির্ধারণ করে। তবে, এটি এমন একটি তালিকা বজায় রাখতে হবে ignored
যা এই ফেলে দেওয়া উপাদানগুলিকে (পরিসরের প্রথম উপাদানটির মতো) সংরক্ষণ করে কারণ তারা ডোমেনের কিছু অন্যান্য উপাদানের চিত্র হতে পারে।
এই সমাধানের সাথে দুটি সমস্যা দেখতে পাচ্ছি। প্রথমটি হ'ল তালিকাগুলি ignored
এবং range
ফাংশনটি recur-on-first
বেশ বড় এবং append
সেগুলি একটি ব্যয়বহুল অপারেশন। দ্বিতীয় সমস্যাটি হ'ল সমাধানটির পুনরাবৃত্তির গভীরতা ব্যাপ্তির আকারের উপর নির্ভর করে।
সুতরাং আমি নীচের সমাধানটি নিয়ে এসেছি যা উপাদানগুলিকে ব্যাপ্তিতে সংরক্ষণ করতে দ্বিগুণ লিঙ্কযুক্ত তালিকাগুলি ব্যবহার করে। ফাংশন start
, next
এবং end
দ্বিগুণ লিঙ্কযুক্ত তালিকার পুনরাবৃত্তি করার সুবিধাদি সরবরাহ করে।
(builder (domain range condlist &optional (partial-map nil))
(block builder
(let ((passed? (check condlist partial-map)))
(cond
((not passed?) nil)
(domain (let* ((cur (start range))
(prev (dbl-node-prev cur)))
(loop
(if (not (end cur))
(progn
(splice-out range cur)
(let ((sol (builder (cdr domain)
range
condlist
(cons (cons (car domain) (data cur)) partial-map))))
(splice-in range prev cur)
(if sol (return-from builder sol)))
(setq prev cur)
(setq cur (next cur)))
(return-from builder nil)))))
(t partial-map))))))
দ্বিতীয় সমাধানের রানটাইম প্রথম সমাধানের রানটাইমের চেয়ে অনেক ভাল। append
প্রথম দ্রবণে অপারেশন এবং একটি দোকর লিঙ্ক তালিকা থেকে বের স্প্লাইসিং উপাদান দ্বারা প্রতিস্থাপিত হয় (এই অপারেশন ধ্রুবক সময় হয়) এবং পুনরাবৃত্তির গভীরতা কেবলমাত্র ডোমেনে আকারের উপর নির্ভর করে। তবে এই সমাধানটির সাথে আমার সমস্যাটি হ'ল এটি C
স্টাইল কোড ব্যবহার করে । তাই আমার প্রশ্ন হল এটি।
এমন কোনও সমাধান আছে যা দ্বিতীয় সমাধানের মতো দক্ষ তবে setf
এর ও মিউটেটেবল ডেটা স্ট্রাকচার ব্যবহার করে না ? অন্য কথায়, এই সমস্যার কার্যকর ফাংশনাল প্রোগ্রামিং সমাধান কি আছে?