माइकल क्रिच्टन का मूसट्रैप


9

1984 में, माइकल क्रिच्टन ने BASIC में एक सुरक्षा कार्यक्रम लिखा जो क्रिएटिव कंप्यूटिंग पत्रिका में प्रकाशित हुआ था। कार्यक्रम उपयोगकर्ता को उसकी पसंद का एक वाक्यांश टाइप करने, कीस्ट्रोक्स के बीच अंतराल रिकॉर्ड करने के लिए कहेंगे, फिर उसे वाक्यांश को फिर से लिखने के लिए कहेंगे। यदि समय बहुत अधिक भिन्न होता है, तो प्रोग्राम उपयोगकर्ता को एक इम्पोर्टर के रूप में पहचानता है।

आपका असाइनमेंट: अपनी पसंद की भाषा में क्रिचटन के प्रोग्राम का एक संस्करण बनाएं।

नियम:

  1. उपयोगकर्ता के साथ संवाद करने के लिए वाक्यांश ("कृपया कुंजी वाक्यांश टाइप करें," "कृपया कुंजी वाक्यांश फिर से टाइप करें," आदि) वास्तविक लंबाई की परवाह किए बिना प्रत्येक बाइट को गिनें। यह केवल उपयोगकर्ता संचार के लिए है, स्ट्रिंग्स में प्रोग्राम कोड को छिपाने की कोशिश न करें।

  2. पास / असफल परीक्षा मूल अंतराल से प्रतिशत भिन्नताओं के औसत निरपेक्ष मूल्य पर आधारित होनी चाहिए। यदि तार मेल नहीं खाते हैं, तो या तो विफल हो जाते हैं या उपयोगकर्ता को आपके विवेक पर फिर से प्रयास करने की अनुमति देते हैं।

  3. मुख्य वाक्यांश को अशक्त स्ट्रिंग की अनुमति नहीं देनी चाहिए। इस घटना में कुंजी वाक्यांश आपके स्ट्रिंग डेटाटाइप के लिए बहुत लंबा है, या तो छंटनी या विघटित करें और अपने विवेक पर शुरू करें।

  4. परीक्षण की संवेदनशीलता (पास / असफल परीक्षा के लिए सीमा) स्रोत कोड में समायोज्य होनी चाहिए।

  5. मैंने मूल बाइट गिनती का मूल रूप से 20% का बोनस प्रदान किया है, यदि आपके स्रोत कोड को डायनासोर के समान रूप से स्वरूपित किया जा सकता है। यह इंगित किया गया है कि यह अत्यधिक व्यक्तिपरक है और शायद एक लोकप्रियता प्रतियोगिता के लिए अधिक उपयुक्त है, इसलिए मैंने इस बोनस को हटा दिया है। हालाँकि मैं अभी भी दिल से डायनासोर प्रारूपण को प्रोत्साहित करता हूं, और यदि आप एक डायनासोर की तरह दिखने के लिए अपने कोड को प्रारूपित करते हैं, तो आप अपने बाइट कुल से किसी भी शुद्ध कॉस्मेटिक टिप्पणियों, लाइनब्रेक या व्हाट्सएप पात्रों को काट सकते हैं।

  6. सबसे छोटी बाइट गिनती जीत, स्ट्रिंग-लंबाई और डायनासोर प्रारूपण समायोजन के अधीन है।

ध्यान दें कि ऊपर दिया गया मेरा विनिर्देश क्रिच्टन के कोड के संचालन से बिल्कुल मेल नहीं खाता है, जिसकी प्रतियां ऑनलाइन मिल सकती हैं। कल्पना का पालन करें, मूल क्लोन करने की कोशिश मत करो।


5
"यह माइकल क्रिक्टन है, इसलिए कुल बाइट गिनती से 20% घटाएं यदि आपके स्रोत कोड को डायनासोर के समान रूप से स्वरूपित किया जा सकता है।" - ओम्म् ... नहीं। यह नियम बहुत व्यक्तिपरक है। कृपया निकालें। इसके अलावा, कृपया आगे बढ़ें।
जॉन ड्वोरक

4
@JanDvorak मुझे नहीं लगता कि इसकी "बहुत" व्यक्तिपरक है। कुछ ASCII कला को डिनो या नहीं के रूप में कॉल करने के लिए एक काफी आसान कॉल
ऑप्टिमाइज़र

3
@ ऑप्टिमाइज़र सभी मामलों में नहीं। क्या ग्रीक अक्षर लैम्ब्डा डायनासोर की तरह दिखता है? मुझे पूरा यकीन है कि यह करता है।
जॉन ड्वोरक

3
कुछ अन्य छोटी टिप्पणियाँ: "Please type the key phrase"1 बाइट के रूप में गिना जाता है, या केवल वाक्यांश गिनती और उद्धृत वाक्यांश 3 बाइट्स ( ", वाक्यांश, ") के रूप में गिना जाता है ? क्या यह जानबूझकर किया जाता है कि एक बहुत लंबा अंतराल और एक बहुत छोटा अंतराल "रद्द" हो जाएगा और फिर से बन जाएगा? क्या कार्यक्रम को सत्यापित करना है कि दो प्रमुख वाक्यांश मेल खाते हैं?
दरवाज़े

जवाबों:


9

माणिक, 171 167 157 बाइट्स

require'io/console';t=Time;f=->a{loop{x=t.now;STDIN.getch==?\r?break: a<<t.now-x};a};p"Please type the key phrase";f[r=[]];p"Please type the key phrase again";p r.zip(f[[]]).map{|x,y|(1-x/y).abs}.reduce(:+)/r.size>0.2

आउटपुट trueयदि औसत विचरण 20% से ऊपर है, अन्यथा आउटपुट false

डायनासोर ASCII कला का प्रयास:

(_=/\
  \ \
   \ \
    \ \              _...---..__
     \ \          .∕` #{t=Time} `\._
      \ \      .∕ #{z='io/console'} `\.
       \ \.__.∕  #{require z;s=STDIN} `\.
        \ #{p'1:';f=->a{loop{x=t.now;#   \.
         s.getch==?\r?break: a<<t.now-x;# `\.
          };a};f[r=[]];p'2:';p r.zip(f[[]])#\  
           .map{|x,y|(1-x/y).abs}.reduce(:+)#|
            .fdiv(r.size)>0.2}###########\   \
            `-._    ,___...----...__,   ,__\  \
                |   |_|           |_|   |    \ \
                |___|               |___|      \\/)

Ungolfed:

require 'io/console' # so we can read one char at a time

t = Time

f = ->(a) {
  loop {
    x = t.now # record start time
    break if STDIN.getch == ?\r
    a << t.now - x # push (start time - end time) into array
  }
  a
}

puts "Please type the key phrase"
f[r = []] 

puts "Please type the key phrase again"

# interweave timing arrays, compute variances, sum elements
# then divide by array length. Check to see if average
# is greater than threshold (0.2)
p r.zip(f[[]]).map { |x,y| (1-x/y).abs }.reduce(:+) / r.size > 0.2

require 'io/console' कुछ रूबी REPLs में चलाने पर हटाया जा सकता है, क्योंकि पुस्तकालय पहले से ही लोड है।


4

जावा 768 बाइट्स

क्या? जावा? कोड गोल्फ के लिए?

यह शायद करने के लिए सबसे बुरी बात है, लेकिन मैंने इसे वैसे भी आजमाया।

यह कंसोल विंडो में कोई भी संदेश प्रदर्शित करता है, लेकिन वास्तविक टाइपिंग JTextField में होती है। दिखने में बिल्कुल ठीक नहीं है। ओह, और 5 बाइट्स को बचाने के लिए, आपको स्वयं JFrame का आकार बदलना होगा। इसके अलावा, यह दूसरी बार स्ट्रिंग शुद्धता के लिए जाँच नहीं करता है। यकीन नहीं है कि अगर चश्मा के खिलाफ है।

उपयोग करने के लिए:

टेक्स्ट फ़ील्ड में अपनी कुंजी टाइप करें।

एन्टर प्रेस न करें, कंसोल पर जाएँ और कुछ टाइप करें। यह एक अन्य संदेश प्रदर्शित करेगा

टेक्स्टफ़ील्ड में वही चीज़ टाइप करें (जो अब क्लियर होनी चाहिए)।

कंसोल पर जाएं और फिर से कुछ दबाएं। यह प्रदर्शित करेगा कि आप घुसपैठिया हैं या नहीं।

ungolfed:

import java.util.*;
import javax.swing.*;
import javax.swing.event.*;

public class CrichtonsMousetrap {
    public static void main(String[]a){
        new CrichtonsMousetrap();
    }
    long start;
    List<Long>elapsed = new ArrayList<>();
    List<Long>e2;
    public CrichtonsMousetrap(){
        JFrame f = new JFrame();
        f.setSize(199,70);
        f.setVisible(true);
        JTextField t = new JTextField();
        System.out.println("please type in the key phrase.");
        f.add(t);
        t.getDocument().addDocumentListener(new DocumentListener(){
            @Override
            public void changedUpdate(DocumentEvent e) {}
            @Override
            public void insertUpdate(DocumentEvent e) {
                long r = System.nanoTime();
                if(start!=0){elapsed.add(r-start);}
                start=r;}
            @Override
            public void removeUpdate(DocumentEvent e) {}            
        });
        Scanner s = new Scanner(System.in);
        s.next();
        System.out.println("please type that again!");
        e2=elapsed;
        elapsed=new ArrayList<>();
        start=0;
        t.setText("");
        s.next();
        double sum=0;
        for(int i=0;i<e2.size();i++){
            sum+=Math.abs(1-elapsed.get(i)/(double)e2.get(i));
        }
        System.out.println("your average percent error was " + sum/e2.size());
        double okLimit = .2;
        System.out.println(sum/e2.size() < okLimit ? "you're ok":"INTRUDER!");
    }
}

golfed:

import java.util.*;import javax.swing.*;import javax.swing.event.*;class q{static long p;static List<Long>y=new ArrayList<>(),o;public static void main(String[]a){JFrame f=new JFrame();f.setSize(0,0);f.setVisible(true);JTextField t=new JTextField();System.out.println("please type in the key phrase.");f.add(t);t.getDocument().addDocumentListener(new DocumentListener(){public void changedUpdate(DocumentEvent e){}public void insertUpdate(DocumentEvent e){long r=System.nanoTime();if(p!=0){y.add(r-p);}p=r;}public void removeUpdate(DocumentEvent e){}});Scanner s = new Scanner(System.in);s.next();System.out.println("please type that again!");o=y;y=new ArrayList<>();p=0;t.setText("");s.next();double b=0;for(int i=0;i<o.size();b+=Math.abs(1-y.get(i)/(double)o.get(i++)));System.out.print(b/o.size() < .25 ? "you're ok":"INTRUDER!");}}

जावा से कच्चे मोड में TTY सेट करने का कोई तरीका नहीं है (जब तक कि आप JNI का उपयोग करने के लिए तैयार न हों)। तो मैं समझता हूं कि आपको JFrame की आवश्यकता क्यों है। लेकिन वास्तव में, यह कम से कम उपयोगकर्ता के अनुकूल कार्यक्रम है जिसे मैंने उम्र में देखा है :-) मुझे यकीन नहीं है कि मैं इस उत्तर को अपवोट या डाउनवोट करना चाहता हूं।
coredump

मैं उपयोगकर्ता की अमित्र राशि (जो कि एक शब्द भी है?) के लिए बढ़ा। यह मूल रूप से कला है।
इंगो बुर्क

मेरा मानना ​​है कि यह वर्ग का विस्तार करके अधिक गोल्फ हो सकता है JFrame, इसलिए आपको इसकी आवश्यकता नहीं होगी f
पुरकाकूदरी

3

HTML, जावास्क्रिप्ट (ES6), 328

कोड की कुल बाइट्स संख्या 402 बाइट्स और उपयोगकर्ता के साथ बातचीत करने के लिए संदेश हैं:

"Valid User"
"Imposter alert!!"
"Please Enter the Key again"
Please Enter the Key

कुल 78 बाइट्स हैं, इसलिए कुल स्कोर => 402 - 78 + 4 = 328

स्निपेट को नीचे एक नवीनतम फ़ायरफ़ॉक्स में चलाएं और इनपुट बॉक्स में कुंजी दर्ज करें और उसके बाद एंटर कुंजी दर्ज करें।

कोड यह जांचता है कि दर्ज की गई और फिर से दर्ज की गई कुंजी दोनों समान हैं, (यदि नहीं तो फिर से प्रवेश करने के लिए संकेत देता है), औसत निरपेक्ष अंतर प्रतिशत की गणना करता है और जाँचता है कि यह चर के मान से कम है या नहीं V

<a id=t >Please Enter the Key</a><input id=f /><script>V=.3,a=[],i=0,s=b="",q=0
c=_=>(j=0,_.slice(1).map(v=>j+=Math.abs(v)/i),alert(j<V?"Valid User":"Imposter alert!!"))
r=_=>(a=[],i=0,t.textContent="Please Enter the Key again",f.value="")
f.onkeyup=_=>_.keyCode==13?q++?s==f.value?(A=a,B=b,A=a.map((v,i)=>v-A[i-1]),c(b.map((v,i)=>(v-B[i-1]-A[i])/A[i]))):r():r(b=a,s=f.value):a[i++]=Date.now()</script>


3

सी, 154 (झंडे के लिए 86 + 68)

d[99],i,a,b;main(x,y){P"Please type the key phrase"W(E-13)U,x=y;U;P"Please type 
the key phrase again"W(a<i)E,b+=abs(Y-Z)*99/Z,++a,x=y;b<a*9||P"No cake for imposters");}

संकलित साथ -DY=(y=clock())-x, -DZ=a[d], -DE=getch(), -DW=);while, -DU=i++[d]=Yऔर-DP=puts( । प्रस्तुति उद्देश्यों के लिए जोड़े गए नए लिंक और हटाए जा सकते हैं (बाइट की गिनती बिना है)।

Ungolfed + टिप्पणियाँ:

d[99],i,a,b;
main(x,y,z){
    puts("Please type the key phrase");
    do
        z = getch(),
        i++[d] = (y = clock()) - x, // save amount of time from last key. first value is garbage.
        x = y;
    while((z = getch())-13); // read until carriage return. 
    for(;a < i && getch(); ++a) // don't check for validity, just get a char
        b += abs((y = clock())- x - d[a])*99/d[a], // (y=clock())-x is time from last key.
                                                     // subtract from original time, *99, divide by new
                                                     // then get sum of these
        x = y;
    b < i*9  // check that the average difference is less than 9/99
    || puts("No cake for imposters"); // identify as imposter if greater/equal
    // don't output anything if not an imposter
}

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

यह भी पहले कीस्ट्रोक से पहले संकेत देने के बाद लिया गया समय नहीं मानता है।


getchशर्त नहीं करनी चाहिए getcया getchar? मेरे पास 'getch' के लिए एक अपरिभाषित संदर्भ है, जिसे यदि मैं सही ढंग से याद करता हूं तो उसे हटा दिया गया है?
coredump

मेरे पास "file.c: 1: 1: चेतावनी: डेटा परिभाषा का कोई प्रकार या भंडारण वर्ग नहीं है" (gcc)। मैंने charवैश्विक घोषणाओं से पहले जोड़ा , और अब, यह रनटाइम पर एक विभाजन दोष देता है। क्या आप इसका निर्माण करने के बारे में विवरण दे सकते हैं? आप किस कंपाइलर का उपयोग कर रहे हैं? धन्यवाद।
coredump

@coredump चेतावनी हानिरहित हैं; हालाँकि यदि आप चेतावनियाँ निकालना चाहते हैं, तो इसे टाइप किया जाना चाहिए int, और इसे इनिशियलाइज़ किया जाना चाहिए 0। मैंने इसे विंडोज पर (विंडो के उपयोग से getch) जीसीसी का उपयोग करके परीक्षण किया है । getchके बजाय प्रयोग किया जाता है getcया getcharक्योंकि getchकिसी भी वर्ण को संसाधित करने से पहले दबाए जाने के लिए रिटर्न कुंजी की आवश्यकता नहीं होती है ( getchयह वास्तव में विंडोज पर पदावनत है, हालांकि यहां पदावनत कार्यों का उपयोग करने में कुछ भी गलत नहीं है)।
es1024

मैं लिनक्स पर परीक्षण कर रहा हूं और इसे बनाने के लिए stackoverflow.com/questions/7469139/… का सहारा लिया है । धन्यवाद।
coredump

2

स्काला आरईपीएल 233

def l:Stream[(Int,Long)]=(Console.in.read,System.nanoTime)#::l    
def m={
    println("Enter");     
    l.takeWhile(_._1!=13).map(_._2).toList.sliding(2).map(a=>a(1)-a(0))
}
val k=m.zip(m)     
k.map(a=>Math.abs(a._2-a._1)/(a._1.toDouble*k.length)).sum<0.2

सभी रिक्ति को हटाने के साथ, आपके पास:

def l:Stream[(Int,Long)]=(Console.in.read,System.nanoTime)#::l;def m={println("Enter");l.takeWhile(_._1!=13).map(_._2).toList.sliding(2).map(a=>a(1)-a(0))};val k=m.zip(m);k.map(a=>Math.abs(a._2-a._1)/(a._1.toDouble*k.length)).sum<0.2

मुझे यकीन है कि मैं किसी और से अधिक प्रतिभाशाली हूं जो मैं एक डायनासोर में बना सकता हूं!

संक्षिप्त विवरण:

lविधि वर्णों को पढ़ने और के पथ रहता है nanoTimeजब हर किरदार लिखे गए वर्णों की।

mविधि प्रिंट "Enter", टूट जाता है lमें प्रवेश से टकराने पर विधि (चरित्र 13), तो यह सिर्फ करने के लिए नक्शे nanoTimes, और फिर प्रत्येक चरित्र के बीच समय अंतराल हो जाता है।

अगली 2 लाइनें 2 स्ट्रिंग्स में पढ़ती हैं, उन्हें ज़िप करती हैं, फिर दूसरे अंतराल और पहले के बीच प्रतिशत अंतर का औसत निरपेक्ष मान पाता है, और अंत में प्रिंट करता है कि यह औसत से कम था या नहीं 0.2


1

आम लिस्प: 660

(ql:quickload'(cl-charms alexandria))(defun m(&key(ok 0.2))(labels((^(s)(fresh-line)(princ s)(return-from m))(d(a b)(abs(/ (- b a) b)))($(x)(princ x)(force-output))(?(m)(charms:with-curses()($ m)(clear-input)(charms:enable-raw-input)(loop for c = (read-char)for n = (get-internal-real-time)for x = nil then (/(- n b)internal-time-units-per-second)for b = n when (eql c #\Esc)do (^"QUIT")when x collect x into % until (eql c #\Newline) collect c into ! finally(progn(terpri)(return(cons(coerce !'string)%)))))))(let*((ip(?"INIT PASSWORD: "))(ps(car ip))(sp(if(equal""ps)(^"NO EMPTY PASSWORD ALLOWED")(?"ENTER PASSWORD: ")))(r(if(equal ps(car sp))(alexandria:mean(mapcar #'d(cdr sp)(cdr ip)))(^"YOU DIDN'T SAY THE MAGIC WORD!"))))(if(> r ok)($"YOU ARE A FAKE!")($"IDENTITY CONFIRMED")))))(m)

Ungolfed

(ql:quickload'(cl-charms alexandria))
(defun m(&key(ok 0.2))
  (labels
      ((^(s)(fresh-line)(princ s)(return-from m))
       (d(a b)(abs(/ (- b a) b)))
       ($(x)(princ x)(force-output))
       (?(m)(charms:with-curses()
              (clear-input)
              ($ m)
              (charms:enable-raw-input)
              (loop for c = (read-char)
                    for n = (get-internal-real-time)
                    for x = nil then (/ (- n b)
                                        internal-time-units-per-second)
                    for b = n
                    when (eql c #\Esc)
                      do (^"QUIT")
                    when x
                      collect x into %
                    until (eql c #\Newline)
                    collect c into !
                    finally (progn
                              (terpri)
                              (return
                                (cons (coerce !'string) %)))))))
    (let* ((ip (?"INIT PASSWORD: "))
           (ps (car ip))
           (sp (if (equal "" ps)
                 (^"NO EMPTY PASSWORD ALLOWED")
                 (?"ENTER PASSWORD: ")))
           (r (if (equal ps (car sp))
                (alexandria:mean(mapcar #'d(cdr sp)(cdr ip)))
                (^"YOU DIDN'T SAY THE MAGIC WORD!"))))
      (if (> r ok)
        ($"YOU ARE A FAKE!")
        ($"IDENTITY CONFIRMED")))))

(m) ;; call function

अतिरिक्त टिप्पणी

  • सभी नियमों के साथ शिकायत करता है
  • जब उपयोगकर्ता पहली बार एक खाली पासवर्ड देता है, तो प्रोग्राम सफाई से गर्भपात करता है
  • टाइप करते समय Escape, प्रोग्राम साफ़ सुथरा हो जाता है।
  • हाल ही में SBCL और CCL कार्यान्वयन पर परीक्षण किया गया
  • Cl-charms की आवश्यकता है, जो Ncurses के आसपास एक आवरण है। कच्चे इनपुट को पकड़ने का यह सबसे आसान तरीका है।
  • यह स्क्विश-ओसिफेरेज द्वारा पाया गया मूल संस्करण से प्रेरित (लेकिन इससे कॉपी नहीं किया गया) है

डायनासोर का बोनस

मेरे पास एक बोनस होना चाहिए क्योंकि हर कोई जानता है कि " कॉमन लिस्प एक नैतिकतापूर्ण डायनासोर है "।


क्या आप उद्धरण ब्लॉक के बजाय कोड ब्लॉक पर स्विच कर सकते हैं? (अपने कोड के लिए)
ऑप्टिमाइज़र

@Optimizer किया
coredump
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.