Stack Exchange sohbet odaları için bir chatbot oluşturun


39

Meydan okuma

Bu zorluğun amacı, Stack Exchange'in sohbet odalarında yayınlanabilecek bir chatbot oluşturmaktır. Botunuzun belirli komutların bir kullanıcı tarafından ne zaman gönderileceğini algılaması ve ona cevap vermesi gerekir. Bu komutların listesi ve botunuzun yapması gerekenler:

  • !!newest: Bu sitede yayınlanan en yeni sorunun başlığını (bağlantı yok, ancak başlığı) yazınız (codegolf.SE).
  • !!metanewest: meta sitesinde yayınlanan en yeni sorunun başlığını çıkar (meta.codegolf.SE).
  • !!questioncount: mevcut soru sayısını gösterir.
  • !!metaquestioncount: güncel soru sayısını meta sitede yayınlar.
  • !!tag tagname: ilk parametre olarak verilen etiketin etiketini (kısa açıklaması) çıktı.
  • !!metatag tagname: yukarıdakiyle aynı, ancak meta site için.
  • !!featured: şu anda ödül alan soruların sayısını gösterir.
  • !!metafeatured: Meta'da [özellikli] etiketi olan soru sayısını gösterir .

kurallar

  1. Snippet veya fonksiyon değil, tam bir program yazmalısınız.
  2. Gerekirse, kullanıcı adı ve şifreyi giriş olarak isteyebilirsiniz (giriş soran, STDIN, komut satırı argümanları). Örneğin Python veya Ruby kullanıyorsanız, bu gerekli olacaktır, ancak JavaScript kullanıyorsanız ve komut dosyasını sohbet odası sayfasının kendisinde çalıştırıyorsanız, bu gerekli olmayacaktır.
  3. WebSockets gibi şeyler yapmak için harici kütüphaneleri kullanmanıza izin verilir. Bu kütüphanelerin karakter sayınız için sayması gerekmez.
  4. Sen edebilirsiniz karakter sayısı saymak zorunda olduğu daha sonra harici bir sohbet sarıcı kullanır (ama kendi yazma teşvik edilmektedir gerekmez) ve. Paketleyicinin kodunu değiştirmenize de izin verilmez. Kullanırsanız, herhangi bir değişiklik yapmadan kullanırsınız ve tüm karakterlerin sayılması gerekir (bu, kendi paketleyicinizi yazmamanın cezasıdır).

    Sadece ambalajın kodunun sayması gerekir. Örnekler gibi başka dosyalar varsa, bunların sayılması gerekmez.

  5. URL kısaltıcıları veya URL'leri kısaltabilecek başka yollar kullanmamak: Zorluk bir URL'yi golf oynamak değil, bir sohbetçi ile golf oynamaktır.
  6. Sohbet etmek ve komutlara cevap verebilmek için gerekli bilgileri almak için gerekli olanlar dışında hiçbir web isteği yoktur.
  7. Kullanımı Standardı "boşluklar" izin verilmez.
  8. Birisi mesajların bir komut varsa, bu biçimin bir sohbet mesajıyla yanıt verdiklerini gerekir: @user response. Eğer emri yazarsam !!featuredve 5 tane soru varsa, botunuz göndermelidir @ProgramFOX 5.
  9. Botunuzu test edersem, onu chatbot hesabımdan çalıştıracağım ve bu sohbet odasında çalıştıracağım . Botları her zaman o odada test edeceğim, bu yüzden oda kimliğini giriş olarak sağlamak gerekli değil, her zaman 14697 olacak. Bu kimlik giriş olarak verilmeyecek, kodlanmış olmalıdır.
  10. Komut bulunamazsa, çıktı @user The command [command] does not exist. [command]Var olmayan komutun adıyla değiştirin . Eğer argüman komuta verildiyse, argümanları değil, sadece komut adını çıkarmayın.
  11. Bir komutun birçok argümana sahip olması durumunda, gerekli olmayan argümanları dikkate almayın.
  12. Bir komutun yeterli argümanı yoksa, çıktı @user You have not provided enough arguments
  13. Sistem, tekrarlanan mesajların kısa bir zaman aralığında gönderilmesini önler. Bu yüzden, botunuzu test ederken, aynı çıktısını art arda veren iki komutu asla çalıştırmayacağım (bu, örneğin kopyalarsa, örneğin bir nokta ekleyerek mesajları farklı kılan bir sistemi uygulamak zorunda olmadığınız anlamına gelir).
  14. Sistem kısa sürede çok fazla mesajın gönderilmesini önler, bu nedenle test ederken kısa süre içinde çok fazla komut göndermeyeceğim, bu da botunuzun buna dikkat etmesi gerekmediği anlamına gelir (bir süre bekleyerek) örneğin göndermeden önce).
  15. Bu , programın en az bayt sayısına sahip kazanmasıdır.

Başlamak

Botunuzu yazmaya başlamak için bazı bilgiler. Bunu kullanmak zorunda değilsin, ama bir rehber olabilir.

  • Giriş yapmak için önce bir OpenID sağlayıcısına giriş yapın. Bu her zaman Yığın Değişim OpenID ( https://openid.stackexchange.com) olacaktır. Giriş formu bulunur https://openid.stackexchange.com/account/loginve orada kullanıcı adı ve şifreyi girin.
  • Ardından, giriş yapın stackexchange.com. Giriş formu adresinde bulunur https://stackexchange.com/users/login. OpenID sağlayıcısı olarak Exchange Değişimi'ni seçin.
  • Bunu yaptıktan sonra sohbet etmek için giriş yapın. Bunun için giriş formu adresinde bulunur http://stackexchange.com/users/chat-login. OpenID sağlayıcısı olarak Exchange Değişimi'ni seçin.
  • Öyleyse seninkini almalısın fkey. Bunun için gizli bir giriş alanına gidin http://chat.stackexchange.com/chats/join/favoriteve alın fkey.
  • Bir mesaj göndermek için bir istek gönderin http://chat.stackexchange.com/chats/14697/messages/newve iki POST parametresi sağlayın: textmesaj metnini fkeyiçeren bir parametre ve fkey.
  • Yeni bir mesajın ne zaman yayınlandığını görmek için WebSockets kullanabilirsiniz (ancak, daha kısa ise başka bir şey kullanmaktan çekinmeyin). Lütfen şu Meta Stack Exchange cevabına bakınız :

    Sohbet

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

    Oda kimliği ve fkey ile POST gönderilerek karma alınabilir. http://chat.stackexchange.com/ws-auth

    Zaman, geri dönen json'un zaman anahtarı /chats/<roomno>/events.

    Bir mesaj gönderildiğinde olay kimliği 1.

  • Tam olarak nasıl çalıştığını görmek için Doorknob'un StackExchange -Chatty ve Manishearth's ChatExchange gibi mevcut sohbet paketlerine bakmak faydalı olacaktır .

3
Başlığı gördüğüm an, hemen "ah, ProgramFOX" diye düşündüm.
seequ

metafeaturedMeta ile ilgili sorular sormayı umuyordum , ama ... teşekkürler :-)
John Dvorak

@JanDvorak Site başına düşen meranın ödülleri yoktur, bu yüzden bunu kullanamam. Bu meydan okumayı yazdığımda, Meta’nın [özellikli] bir etiketi olduğunu unuttum, bu yüzden öneriniz için teşekkürler!
ProgramFOX

Yeni bir mesajın yayınlanıp yayınlanmadığını görmek için yaptığım, son mesajın yanımda olmadığı durumlarda (sınıftaki son madde) JS yoluyla her 2 saniyede bir kontrol edilmesi
Cilan

Zaten burada bir tane var
Bay Alien

Yanıtlar:


14

JavaScript + jQuery, 1362 1258 bayt

Bir minifier kullanarak golf oynadı:

$(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})})

Komut dosyasını doğrudan tarayıcıda çalıştırmanız gerekir (Stack Exchange'in jQuery çalışmalarını kullanarak):

  1. Açık http://chat.stackexchange.com/rooms/14697/chatbot-challenge-on-programming-puzzles-code-golf
  2. Yukarıdaki kodu konsola yapıştırın
  3. Sohbete bazı komutları girin

Daha çok golf oynayabilirdi, ama canını sıkmadı.


Un-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});
});

Güzel, buraya cevap yazdığın için teşekkürler! Şimdi odadaki testleri yapacağım. Neyse, daha tek harfli değişkenler kullanarak ve kaçınarak bazı karakterler kurtarabilir miyiz updateve latestMessage.
ProgramFOX

Harika! Tüm sınavları geçtin . Fark ettiğim tek garip şey, botunuzun ana sayfadakinden farklı bir soru sayımı döndürmesiydi, ancak API'nin bu numarayı döndürdüğünü gördüm, bu yüzden bunu Meta'da bildirdim ve test vakasını doğru olarak işaretledim. Aferin! +1
ProgramFOX

Botu kısalttığını gördüm. Güzel! :) Tekrar test ettim ve hala tüm sınavlardan geçtin.
ProgramFOX

Aksine geç, ama sadece tek karakter iyileşme bulundu: Eğer yerini alabilir 0==e.items.lengthile 1>e.items.lengthuzunluk sıfırın altında hiç gitmeyecek çünkü.
ProgramFOX
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.