स्टैक एक्सचेंज चैटरूम के लिए एक चैटबॉट बनाएं


39

चुनौती

इस चुनौती का लक्ष्य एक चैटबॉट बनाना है जो स्टैक एक्सचेंज के चैटरूम में चल सकता है। आपके बॉट को यह पता लगाने में सक्षम होने की आवश्यकता होती है कि किसी उपयोगकर्ता द्वारा विशिष्ट कमांड पोस्ट किए गए हैं और उसका जवाब दें। यह आदेशों की सूची है, और आपके बॉट को क्या करना चाहिए:

  • !!newest: इस साइट (codegolf.SE) पर पोस्ट किए गए सबसे नए सवाल का शीर्षक (कोई लिंक नहीं, बल्कि शीर्षक) का उत्पादन।
  • !!metanewest: मेटा साइट (meta.codegolf.SE) पर पोस्ट किए गए नवीनतम प्रश्न का शीर्षक आउटपुट।
  • !!questioncount: वर्तमान प्रश्न गणना आउटपुट।
  • !!metaquestioncount: मेटा साइट पर वर्तमान प्रश्न गणना को आउटपुट करता है।
  • !!tag tagname: पहले पैरामीटर के रूप में दिए गए टैग के टैग अंश (संक्षिप्त विवरण) को आउटपुट करें।
  • !!metatag tagname: ऊपर के समान, लेकिन मेटा साइट के लिए।
  • !!featured: वर्तमान में एक इनाम है कि सवालों की गिनती का उत्पादन।
  • !!metafeatured: मेटा पर [फ़ीचर्ड] टैग वाले प्रश्नों की गिनती को आउटपुट करें ।

नियम

  1. आपको एक संपूर्ण कार्यक्रम लिखना चाहिए, न कि स्निपेट या फ़ंक्शन।
  2. यदि यह आवश्यक है, तो आप इनपुट के रूप में उपयोगकर्ता नाम और पासवर्ड का अनुरोध कर सकते हैं (इनपुट, STDIN, कमांड लाइन तर्क के लिए संकेत देना)। यह आवश्यक होगा यदि आप उपयोग करते हैं, उदाहरण के लिए, पायथन या रूबी, लेकिन यह आवश्यक नहीं होगा यदि आप जावास्क्रिप्ट का उपयोग करते हैं और चैट रूम पेज पर ही स्क्रिप्ट चलाते हैं।
  3. आपको WebSockets जैसे सामान करने के लिए बाहरी पुस्तकालयों का उपयोग करने की अनुमति है। इन पुस्तकालयों को आपके चरित्र की गिनती के लिए गणना करने की आवश्यकता नहीं है।
  4. आप एक बाहरी चैट आवरण का उपयोग कर सकते हैं (लेकिन आपको ऐसा नहीं करना है, अपना खुद का लेखन प्रोत्साहित किया जाता है), और फिर उसे वर्ण गणना के लिए गिनना होगा। आपको रैपर कोड बदलने की भी अनुमति नहीं है। यदि आप इसका उपयोग करते हैं, तो आप इसे बिना किसी संशोधन के उपयोग करते हैं और सभी वर्णों को गिना जाना है (यह आपके स्वयं के आवरण को नहीं लिखने के लिए दंड के रूप में है)।

    केवल रैपर के कोड को ही गिनना होगा। यदि उदाहरण के रूप में अन्य फाइलें हैं, तो इन्हें गिनना नहीं है।

  5. URL शॉर्टर्स या अन्य तरीकों का कोई उपयोग नहीं है जो URL को छोटा बना सकते हैं: चुनौती एक चैटबॉट को गोल्फ करना है, न कि एक URL को गोल्फ करना।
  6. कोई वेब अनुरोध नहीं, सिवाय उन चैट के और आदेशों का जवाब देने के लिए आवश्यक जानकारी प्राप्त करने के लिए।
  7. मानक "कमियां" के उपयोग की अनुमति नहीं है।
  8. यदि कोई कमांड पोस्ट करता है, तो आपको इस प्रारूप के चैट संदेश के साथ जवाब देना होगा @user response:। इसलिए, अगर मैं कमांड लिखता हूं !!featuredऔर 5 विशेष प्रश्न हैं, तो आपके बॉट को पोस्ट करना चाहिए @ProgramFOX 5
  9. अगर मैं आपके बॉट का परीक्षण करता हूं, तो मैं इसे अपने चैटबॉट खाते से चलाऊंगा और मैं इसे इस चैट रूम में चलाऊंगा । मैं हमेशा उस कमरे में बॉट्स का परीक्षण करूंगा, इसलिए इनपुट के रूप में रूम आईडी प्रदान करना आवश्यक नहीं है, यह हमेशा 14697 होगा। इस आईडी को इनपुट के रूप में नहीं दिया जाएगा, इसे हार्ड-कोड किया जाना चाहिए।
  10. यदि कमांड नहीं मिली है, आउटपुट @user The command [command] does not exist[command]गैर-मौजूदा आदेश के नाम से प्रतिस्थापित करें । यदि तर्क को कमांड प्रदान की जाती है, तो तर्कों को आउटपुट न करें, केवल कमांड नाम।
  11. यदि किसी आदेश में कई तर्क हैं, तो उन तर्कों को अनदेखा करें जो आवश्यक नहीं हैं।
  12. यदि किसी कमांड में पर्याप्त तर्क, आउटपुट नहीं है @user You have not provided enough arguments
  13. सिस्टम रोकता है कि कुछ समय के भीतर डुप्लिकेट संदेश पोस्ट किए जाते हैं। इसलिए, आपके बॉट का परीक्षण करते समय, मैं कभी भी दो कमांड नहीं चलाऊंगा जो समान आउटपुट को क्रमिक रूप से देते हैं (जिसका अर्थ है कि आपको एक प्रणाली लागू करने की आवश्यकता नहीं है जो संदेशों को अलग-अलग बनाता है यदि वे डुप्लिकेट हैं, उदाहरण के लिए एक डॉट जोड़कर)।
  14. सिस्टम रोकता है कि बहुत सारे संदेश थोड़े समय सीमा के भीतर पोस्ट हो जाते हैं, इसलिए परीक्षण करते समय, मैं बहुत कम समय के भीतर कई कमांड नहीं भेजूंगा, जिसका अर्थ है कि आपके बॉट को इस बात का ध्यान नहीं रखना है (कुछ समय प्रतीक्षा करके पोस्ट करने से पहले, उदाहरण के लिए)।
  15. यह , कम से कम बाइट्स जीतने वाला कार्यक्रम।

शुरू करना

अपने बॉट को लिखने के साथ आरंभ करने के लिए यहां कुछ जानकारी दी गई है। आपको इसका उपयोग नहीं करना है, लेकिन यह एक मार्गदर्शन हो सकता है।

  • लॉग इन करने के लिए, पहले एक OpenID प्रदाता में लॉग इन करें। यह हमेशा स्टैक एक्सचेंज ओपनआईडी ( https://openid.stackexchange.com) होगा। लॉगिन फ़ॉर्म पर स्थित है https://openid.stackexchange.com/account/login, और वहां उपयोगकर्ता नाम और पासवर्ड प्रदान करें।
  • फिर, लॉगिन करें stackexchange.com। लॉगिन फॉर्म पर स्थित है https://stackexchange.com/users/login। OpenID प्रदाता के रूप में स्टैक एक्सचेंज चुनें।
  • ऐसा करने के बाद, चैट में लॉग इन करें। उस के लिए लॉगिन फ़ॉर्म में स्थित है http://stackexchange.com/users/chat-login। OpenID प्रदाता के रूप में स्टैक एक्सचेंज चुनें।
  • फिर आपको अपना प्राप्त करने की आवश्यकता है fkey। उसके लिए, एक छिपे हुए इनपुट फ़ील्ड से जाएं http://chat.stackexchange.com/chats/join/favoriteऔर प्राप्त करें fkey
  • संदेश पोस्ट करने के लिए http://chat.stackexchange.com/chats/14697/messages/new, एक अनुरोध भेजें और दो POST पैरामीटर प्रदान करें: textसंदेश पाठ वाला एक fkeyपैरामीटर और एक पैरामीटर जिसमें fkey
  • यह देखने के लिए कि कोई नया संदेश कब पोस्ट किया गया है, आप वेबस्केट्स का उपयोग कर सकते हैं (लेकिन ऐसा नहीं है, अगर यह छोटा है तो कुछ और उपयोग करने के लिए स्वतंत्र महसूस करें)। कृपया इस मेटा स्टैक एक्सचेंज का उत्तर देखें :

    चैट

    (wss://chat.sockets.stackexchange.com/events/<roomnumber>/<somehash>?l=<timethingy>)

    कमरा आईडी और fkey को पोस्ट करके हैश प्राप्त किया जा सकता है http://chat.stackexchange.com/ws-auth

    टाइमस्टाइल समय के द्वारा लौटाए गए जौन की कुंजी है /chats/<roomno>/events

    जब संदेश पोस्ट किया जाता है तो ई-मेल आईडी 1

  • मौजूदा चैट-रैपर को देखने के लिए उपयोगी है, जैसे कि Doorknob's StackExchange- Chatty और Manishearth's ChatExchange , यह देखने के लिए कि यह वास्तव में कैसे काम करता है।

3
जिस क्षण मैंने शीर्षक देखा, मैंने तुरंत "आह, प्रोग्रामफ़ॉक्स" सोचा।
देखिए

मैं उम्मीद कर रहा था कि metafeaturedइसका मतलब मेटा पर पूछे गए सवालों से होगा, लेकिन ... धन्यवाद :-)
जॉन ड्वोरक

@JanDvorak प्रति-साइट मेटा में बाउंटी नहीं हैं, इसलिए मैं इसका उपयोग नहीं कर सकता। जब मैंने यह चुनौती लिखी, तो मैं यह भूल गया कि मेटा में एक [फ़ीचर्ड] टैग था, इसलिए आपके सुझाव के लिए धन्यवाद!
प्रोग्रामफॉक्स

अगर एक नया संदेश पोस्ट किया गया था, तो मुझे यह देखने के लिए क्या किया गया था कि जेएस के माध्यम से हर 2 सेकंड की जांच की गई थी यदि अंतिम संदेश मेरे द्वारा नहीं था (कक्षा में अंतिम आइटम)
Cilan

हम पहले से ही खत्म हो गया एक है यहाँ
श्री विदेशी

जवाबों:


14

जावास्क्रिप्ट + jQuery, 1362 1258 बाइट्स

एक minifier का उपयोग करके गोल्फिंग:

$(function(){function e(){function e(e,t){$("#input").val("@"+$(e).parents(".user-container").find(".username").eq(0).text()+" "+t),$("#sayit-button").click()}var i,a=$(t),s=a.map(function(e,t){return t.id}),r=s.slice(-1)[0]
n!=r&&(i=a.slice($.inArray(n,s)+1),n=r,i.map(function(t,n){var i,a,s,r,o,u,c,f=n.textContent.match(/!!(\S+)(?:\s+(\S+))?/)
if(f){switch(i=f[1],a=f[2],s="codegolf",0==i.indexOf("meta")&&(s="meta."+s,i=i.slice(4)),r="?site="+s,c=0,i){case"newest":o=["questions","&order=desc&sort=creation"],u=function(e){return e.items[0].title}
break
case"questioncount":o=["info",""],u=function(e){return e.items[0].total_questions}
break
case"tag":if(!a){c=1
break}o=["tags/"+a+"/wikis",""],u=function(e){return 0==e.items.length?"Tag not found":e.items[0].excerpt}
break
case"featured":o=0==s.indexOf("meta.")?["questions","&tagged=featured"]:["questions/featured",""],u=function(e){var t=e.items.length
return(e.items.has_more?"more than ":"")+t}}c?e(n,"You have not provided enough arguments"):o?$.get("http://api.stackexchange.com/2.2/"+o[0]+r+o[1],function(t){e(n,u(t))}):e(n,"The command "+i+" does not exist")}}))}var t="[id^=message-]",n=$(t).eq(-1).attr("id")
new MutationObserver(e).observe($("#chat").get(0),{childList:!0,subtree:!0})})

आपको स्क्रिप्ट को सीधे ब्राउज़र में चलाना होगा (Stack Exchange के jQuery कार्यों का उपयोग करके):

  1. Http://chat.stackexchange.com/rooms/14697/chatbot-challenge-on-programming-patalog-code-golf खोलें
  2. कंसोल में उपरोक्त कोड पेस्ट करें
  3. चैट में कुछ कमांड दर्ज करें

यह बहुत अधिक गोल्फ हो सकता है, लेकिन परेशान नहीं किया जा सकता है।


संयुक्त राष्ट्र के golfed:

$(function() {
    var sel = '[id^=message-]';
    var latestMessage = $(sel).eq(-1).attr('id');
    function update() {
        var messages = $(sel);
        var ids = messages.map(function(i, x) { return x.id; });
        var newest = ids.slice(-1)[0];
        if(latestMessage == newest) {
            return;
        }
        var newMessages = messages.slice($.inArray(latestMessage, ids) + 1);
        latestMessage = newest;
        newMessages.map(function(i, x) {
            var m = x.textContent.match(/!!(\S+)(?:\s+(\S+))?/);
            if(!m) {
                return;
            }
            var c = m[1];
            var a = m[2];
            var s = 'codegolf';
            if(c.indexOf('meta') == 0) {
                s = 'meta.' + s;
                c = c.slice(4);
            }
            var site = '?site=' + s;
            var url;
            var extractor;
            var too_few_args = 0;
            switch(c) {
                case 'newest':
                    var url = ['questions', '&order=desc&sort=creation'];
                    extractor = function(data) {
                        return data.items[0].title;
                    };
                    break;
                case 'questioncount':
                    url = ['info', ''];
                    extractor = function(data) {
                        return data.items[0].total_questions;
                    };
                    break;
                case 'tag':
                    if(!a) {
                        too_few_args = 1;
                        break;
                    }
                    url = ['tags/' + a + '/wikis', ''];
                    extractor = function(data) {
                        if(data.items.length == 0) {
                            return 'Tag not found';
                        }
                        return data.items[0].excerpt;
                    };
                    break;
                case 'featured':
                    url = s.indexOf('meta.') == 0? ['questions', '&tagged=featured']: ['questions/featured', ''];
                    extractor = function(data) {
                        var l = data.items.length;
                        return (data.items.has_more? 'more than ': '') + l;
                    }
                    break;
            }
            if(too_few_args) {
                write(x, 'You have not provided enough arguments');
            } else if(!url) {
                write(x, 'The command ' + c + ' does not exist');
            } else {
                $.get('http://api.stackexchange.com/2.2/' + url[0] + site + url[1], function(data) {
                    write(x, extractor(data));
                });
            }
        });

        function write(x, m) {
            $('#input').val('@' + $(x).parents('.user-container').find('.username').eq(0).text() + ' ' + m);
            $('#sayit-button').click();
        }
    }
    new MutationObserver(update).observe($('#chat').get(0), {childList: true, subtree: true});
});

अच्छा, यहाँ एक उत्तर पोस्ट करने के लिए धन्यवाद! मैं अब कमरे में परीक्षण चलाने जा रहा हूं। वैसे भी, मुझे लगता है कि आप और अधिक एक अक्षर वेरिएबल का उपयोग करके और से बचने के कुछ पात्रों को बचा सकता है updateऔर latestMessage
प्रोग्रामफॉक्स

महान! आपने सभी टेस्ट पास कर लिए । केवल एक अजीब बात मैंने देखी कि आपके बॉट ने मुखपृष्ठ पर की तुलना में एक अलग प्रश्न गणना की थी, लेकिन मैंने देखा कि एपीआई ने उस नंबर को वापस कर दिया, इसलिए मैंने मेटा पर इसकी सूचना दी और परीक्षण मामले को सही बताया। बहुत बढ़िया! +1
प्रोग्रामफ़ॉक्स

मैंने देखा कि आपने बॉट को छोटा कर दिया है। अच्छा! :) मैंने इसे फिर से परीक्षण किया और आप अभी भी सभी परीक्षण पास करते हैं।
प्रोग्राम फॉक्स

बल्कि देर से, लेकिन मैं केवल एक चार सुधार पाया: आप की जगह ले सकता 0==e.items.lengthसाथ 1>e.items.lengthक्योंकि लंबाई शून्य से नीचे जाना कभी नहीं होगा।
प्रोग्रामफॉक्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.