पासवर्ड का पता लगाएं


12

एक साधारण N- अंकीय संयोजन लॉक में N घूर्णन डिस्क होती है। प्रत्येक डिस्क में 0-9 अंक अंकित होते हैं, और इसे खोलने के लिए आपको उन्हें सही पासवर्ड की ओर मोड़ना होगा। जाहिर है, यदि आप पासवर्ड नहीं जानते हैं, तो आपको इसे अनलॉक करने से पहले अधिकतम 10 N बार कोशिश करनी होगी । यह दिलचस्प नहीं है।

संयोजन ताला

तो चलो संयोजन लॉक के एक संस्करण पर विचार करें, इसे दूरी-खुलासा ताला नाम दें।

दूरी-खुलासा ताला खोलने के हर असफल प्रयास में, यह अनलॉक करने के लिए न्यूनतम आंदोलनों का जवाब देगा।

एक आंदोलन उदाहरण के लिए इसे से 1 आंदोलन की जरूरत है, एक स्थान से एक रोटेशन के रूप में परिभाषित किया गया है 890करने के लिए 899, और से 9 आंदोलनों 137के लिए 952

चुनौती

अपने पासवर्ड अज्ञात के साथ एक दूरी-खुलासा ताला को देखते हुए, प्रोग्राम को बहुत लंबे समय तक रखने से कम से कम प्रयासों (आंदोलनों नहीं) के साथ लॉक को खोलने का प्रयास करें

नियम और स्कोरिंग

  • आपको एक पूर्ण कार्यक्रम लिखना चाहिए जो स्टड से इनपुट करता है और स्टडआउट को आउटपुट करता है। कार्यक्रम को निम्नानुसार इनपुट / आउटपुट करना चाहिए:
Start
    Input an integer N (number of digits) from stdin
    Do
        Output a line containing decimal string of length N (your attempt) to stdout
        Input an integer K (response of the lock) from stdin
    While K not equal 0
End
  • आपके प्रोग्राम को N = 200 तक संभालना चाहिए, और किसी भी इनपुट पर 5 सेकंड से कम चलना चाहिए।

  • उत्पादन में अग्रणी शून्य को छोड़ा नहीं जाना चाहिए।

  • हर लंबाई के लिए 5 टेस्टडेटा हैं, इसलिए टेस्टडेटा की कुल संख्या 1000 है। टेस्टडेटा यादृच्छिक रूप से उत्पन्न होता है।

  • अंतिम स्कोर होगा (सभी टेस्टडेटा में अनुमानों की कुल संख्या) * ln (बाइट्स में कोड की लंबाई + 50)। सबसे कम स्कोर जीतता है। (ln प्राकृतिक लॉग है)

  • मैं आपके लिए कार्यक्रम बनाऊंगा। यदि आप जानना चाहते हैं कि मैं आपका कार्यक्रम कैसे बनाऊंगा, या आप इसे खुद से स्कोर करना चाहते हैं, तो इस पोस्ट पर पिछले संस्करणों पर एक नज़र डालें ।

  • यह चुनौती 2017/12/07 14:00 UTC पर समाप्त होगी। मैं तब अपना समाधान पोस्ट करूंगा।

चल रहा उदाहरण

रेखाएँ >इनपुट से शुरू होती हैं , और अन्य प्रोग्राम आउटपुट का प्रतिनिधित्व करती हैं।

आपके दिमाग में एक पासवर्ड हो सकता है और इसे परीक्षण करने के लिए अपने कार्यक्रम के साथ बातचीत कर सकते हैं।

> 3   # 3-digit lock. The hidden password is 746
000   # 1st guess (by program)
> 11  # response to the 1st guess
555   # 2nd guess
> 4   # ...
755
> 2
735
> 2
744
> 2
746   # finally the correct answer! The program attempts 6 times.
> 0   # this is not necessary

नमूना कार्यक्रम

संपादित करें: शायद ऊपर इनपुट / आउटपुट प्रारूप स्पष्ट नहीं था। यहां पाइथन में एक नमूना कार्यक्रम है।

पायथन, 369 बाइट्स, कुल प्रयासों की संख्या = 1005973, स्कोर = 6073935

import sys

N = int(input()) # get the lock size

ans = ''
for i in range(N): # for each digit
    lst = []
    for j in range(10): # try all numbers
        print('0' * i + str(j) + '0' * (N - i - 1)) # make a guess
        result = int(input()) # receive the response
        lst.append(result)
    ans += str(lst.index(min(lst)))
print(ans) # output the final answer

चुनौती को आसान बनाने के लिए जोनाह को धन्यवाद ।

जवाबों:


3

सी, 388 374 368 बाइट्स, कुल प्रयास = 162751, स्कोर = 982280

char s[999];i;G;H;t;n;h;e;R(x){scanf("%d",x);}W(i,x,a){printf((i-n?0:4)+"%0*d%0*d\n",i,x,n-i,0);R(a);}S(k,i){if(!(t=e=k>4?s[i]=48:k<1?s[i]=53:!G?H=k,G=i:0)){for(;t++<n;)putchar(48|t==i|t==G);puts("");R(&t);t==h?W(G,e=1,&t):0;s[G]=t>h?53+H:53-H,s[i]=t>h^e?53+k:53-k;G=0;}}main(){R(&n);for(W(n,0,&h);i++<n;S(t-h+5>>1,i))W(i,5,&t);s[G]=53+H,puts(s+1),s[G]=53-H,puts(s+1);}

PPCG में आपका स्वागत है! आपको अच्छा स्कोर मिला 162751*ln(388+50)=989887
कोलेरा सु

3

सी # (.NET कोर) , 617 बाइट्स, कुल प्रयास = 182255, स्कोर = 1185166

using System;namespace p{class C{static void Main(){var l=Console.ReadLine();int L=int.Parse(l);var g=new int[L];var p=n(g);for(int i=0;i<L;i++){g[i]=5;var d=n(g);var f=d-p;var s=f;switch(s){case 5:g[i]=0;d-=5;break;case-5:break;case 3:g[i]=1;d=n(g);f=d-p;if(f>0){g[i]=9;d-=2;}break;case 1:g[i]=2;d=n(g);f=d-p;if(f>0){g[i]=8;d-=4;}break;case-1:g[i]=3;d=n(g);f=d-p;if(f>0){g[i]=7;d-=4;}break;case-3:g[i]=4;d=n(g);f=d-p;if(f>-3){g[i]=6;d-=2;}break;}p=d;}n(g);}static int n(int[] g){foreach(var i in g){Console.Write(i);}Console.WriteLine();var s=Console.ReadLine();var d=int.Parse(s);if(d<1) Environment.Exit(0);return d;}}}

उम्मीद है कि इस प्रारूप में C # आपके लिए काम करता है। यह एक संपूर्ण कार्यक्रम के रूप में है, इसलिए एक निष्पादन योग्य को संकलित करने का एक तरीका होना चाहिए। मुझे बताएं कि क्या कुछ है जो मैं इसे आसान बनाने के लिए कर सकता हूं। बाइट्स स्कोरिंग का हिस्सा होते हुए भी कोड गोल्फ टैग को हटा दिया जाता है इसलिए मेरा आधिकारिक सबमिशन सभी अनावश्यक व्हाट्सएप और उपयोगी नामों को हटा देता है। नीचे दिए गए मेरे विवरण में अनलग्ड कोड के टुकड़े का उपयोग किया जाएगा:

व्याख्या

यह कार्यक्रम केवल एक सहायक विधि का उपयोग करता है:

static int newGuess(IEnumerable<int> guess)
        {
            foreach (var item in guess)
            {
                Console.Write(item);
            }
            Console.WriteLine();
            var distanceString = Console.ReadLine();
            var distance = int.Parse(distanceString);
            if (distance < 1) System.Environment.Exit(0);
            return distance;
        }

यह स्टडआउट का अनुमान लिखता है, फिर स्टड से दूरी पढ़ता है। यह प्रोग्राम को तुरंत समाप्त कर देता है यदि कोई अनुमान सटीक संयोजन है। मैं इसे बहुत कुछ कहता हूं। प्रारंभिक सेटअप अगला:

var lengthString = Console.ReadLine();
int length = int.Parse(l);
var guess = new int[length];
var prevDistance = newGuess(guess);

यह संयोजन की लंबाई प्राप्त करता है, फिर सभी 0s के साथ अनुमान लगाना शुरू करता है। बाद में, यह प्रत्येक अंक के माध्यम से एक forलूप में पुनरावृत्ति करता है।

guess[i] = 5;
var distance = newGuess(guess);
var difference = distance - prevDistance;
var switchVar = difference;
switch (switchVar)

प्रत्येक अंक के लिए, यह 5 अनुमान लगाता है, फिर अगले चरण के आधार पर निर्णय लेता है कि पिछले अनुमान के बाद की दूरी कैसे बदल गई (जहां वह अंक 0 था)।

case 5:
    guess[i] = 0;
    distance -= 5;
    break;

यदि दूरी 5 से बढ़ी, तो 0 उस दूरी के लिए सही थी। उस अंक को वापस समायोजित करें 0. दर्ज की गई दूरी को मैन्युअल रूप से बदलना एक अतिरिक्त अनुमान को रोकता है।

case -5:
    break;

यदि दूरी 5 से कम हो जाती है, तो 5 सही अंक है और हम तुरंत अगले अंक पर चले जाते हैं।

उसके बाद चीजें मुश्किल होती हैं। मेरे प्रारंभिक अनुमानों का उपयोग करना 5और उनके 0लिए इसका मतलब है कि शेष अंतर संभावनाएं 3, 1, -1, -3प्रत्येक के लिए 2 संभावनाओं के साथ हैं , जिन्हें भेद करने के लिए 1 अतिरिक्त अनुमान की आवश्यकता है। इन मामलों में से प्रत्येक एक समान रूप लेता है

case 3:
    guess[i] = 1;
    distance = newGuess(guess);
    difference = distance - prevDistance;
    if (difference > 0)
    {
        guess[i] = 9;
        distance -= 2;
    }

कुछ संख्याएँ बदलती हैं, लेकिन अनिवार्य रूप से हम दो संभावनाओं में से एक को आज़माते हैं, और जाँचते हैं कि क्या परिवर्तन उस अंक के लिए सही था। यदि यह नहीं था, तो दूसरा अंक सही है, इसलिए हम उस अंक को सेट करते हैं फिर अंतर को मैन्युअल रूप से समायोजित करते हैं।

इस विधि का मतलब है कि हमें अधिकतम ० अंक के लिए १ अनुमान लगाना चाहिए, २ अंक प्रति अंक, और फिर अंतिम अंक सुनिश्चित करने के लिए १ अंतिम अनुमान।

यह छोटी गाड़ी हो सकती है, यह जहाँ तक मैंने मैन्युअल रूप से जाँच की है, लेकिन यह कोई गारंटी नहीं है। बग पाया और कोलरा सु को धन्यवाद दिया


मैंने इसका परीक्षण किया और जब जवाब है तो यह काम नहीं किया 37। आउटपुट है: 00, 50, 30, 75, 75(हाँ, दो 75 के दशक)।
कोलेरा सु

जगह <के साथ >हर में ifमें switchबग को ठीक करने लगता है। यदि आप चाहते हैं कि, आपका स्कोर है 182255*ln(617+50)=1185166
सु

@ColeraSu वास्तव में! कोड को छोटा करते समय मुझे ढूंढने / बदलने में गलती हुई होगी। मैंने गोल्फ कोड में क्रिया को ठीक कर दिया है (क्रिया संस्करण की तुलना सही थी)।
कामिल दकरी

2

पायथन 2 और 3: 175 बाइट्स, कुल प्रयास = 1005972, स्कोर = 5448445

यह कार्यक्रम छत (लॉग (एन)) * प्रति संयोजन 10 प्रयास या हर एक अंक 10 प्रयास लेता है (इसलिए, 33330 प्रयास लेता है)।

N=int(input());o=0
def c(a):
 print("0"*(N-len(str(a)))+str(a))
 return int(input())
for j in range(N):m={c(i):i for i in reversed(range(0,10**(j+1),10**j))};o+=m[min(m)]
c(o)

Colera Su को इनपुट / आउटपुट कार्यक्षमता के साथ मेरी मदद करने के लिए बहुत धन्यवाद।

चुनौती का पायथन संस्करण ( ओपी द्वारा संशोधित )।

मैंने पायथन के अंदर लॉक कोड का एक संस्करण लिखा था। आप आगे बढ़ सकते हैं और उपयोग कर सकते हैं यदि आप इसे पायथन (मेरी तरह) में हल करने की कोशिश कर रहे हैं। पायथन 2 और 3 में निम्नलिखित काम करता है। इसने लॉक को लागू करने के लिए एक बहुत अधिक समझदारी बना दी है क्योंकि आप जिस वर्ग के खिलाफ परीक्षण कर सकते हैं और मैंने इनपुट्स का अनुमान लगाने के लिए एक जनरेटर फ़ंक्शन बनाने का फैसला किया है।

import sys

class Lock:
    def __init__(self, number):
        self.lock = str(number)
    def l(self): #lengthOfNumber
        return len(self.lock)
    def c(self, guess): #check a guess
        guess = str(guess)
        guess = "0" * (len(self.lock) - len(guess)) + guess
        difference = 0
        for i in range(len(self.lock)):
            d1 = abs(int(self.lock[i]) - int(guess[i]))
            d2 = 10 - d1
            difference += d1 if d1 < d2 else d2
        return difference

def masterLock():
    testdata = ["000","555","755","735","744","746"]
    for answer in testdata:
        yield Lock(answer)

class LockIO:
    def __init__(self):
        self.lock = int(input())
    def l(self):
        return self.lock
    def c(self, guess):
        guess = str(guess)
        guess = "0" * (self.lock - len(guess)) + guess
        print(guess)
        sys.stdout.flush()
        return int(input())

for l in masterLock():
    # Write your code here that tries to guess it
    #   When you're done testing you can unindent your code,
    #   replace "for l in masterLock():" with "l = LockIO()"
    #   and submit the code.
    # 
    # Examples:
    #  l.l()      # returns the length of the lock
    #  l.c("952") # returns the distance to the lock
    #  l.c(952)   #  number also works
    pass

सबसे पहले, इस बारे में खेद है कि मैंने LockIOकक्षा को गलत लिखा है। मैंने एक संपादन अनुरोध भेजा है। दूसरा, मुझे लगता है कि आपने स्कोरिंग मानदंड को गलत बताया है। स्कोर की गणना जनरेटर द्वारा उत्पन्न टेस्टडेटा द्वारा की जाती है, उदाहरण के लिए नहीं (मैंने आपके प्रोग्राम को निष्पादित किया है, और कुल संख्या 1005972 है)। प्राकृतिक लॉग भी गायब है। तीसरा, मैंने निर्दिष्ट किया है कि आपको एक पूर्ण कार्यक्रम प्रदान करने की आवश्यकता है, इसलिए आपको LockIOअपने बाइट की गिनती में भाग को भी शामिल करना चाहिए । इसके अतिरिक्त, आपको अंतिम परिणाम का उत्पादन करने की आवश्यकता है, और यह भी स्कोर में गिना जाता है।
कोलेरा सु

@ColeraSu यहां "क्लास लॉकियो" कैसे संबंधित है? इसके अलावा पायथन कोड का दूसरा ब्लॉक किसके लिए उपयोग किया जाता है?
user202729

@ user202729 Lockऔर masterLockपरीक्षण की सुविधा के लिए है। LockIOवास्तव में आपको सबमिट करने की आवश्यकता है, क्योंकि यह आवश्यक I / O प्रारूप का उपयोग करता है।
कोलेरा सु

@nfnneil मैंने मुख्य पोस्ट में एक नमूना कार्यक्रम जोड़ा है। मैंने आपके संदर्भ के लिए एक संपादन अनुरोध भी भेजा है।
कोलेरा सु

@ColeraSu जैसा कि मैं सो रहा था मुझे एहसास हुआ कि आपका क्या मतलब है और धन्यवाद आदमी। यह एक अच्छी चुनौती थी।
नील

2

आर , 277 बाइट्स (स्कोर = 1175356) 258 बाइट्स, कुल प्रयास = 202999, स्कोर = 1163205

f=file("stdin","r")
w=function(b=1,A=X){cat(A,"\n",sep="");if(b){b=scan(f,n=1)};b}
M=0:9
s1=c(-5,-3,-1,1,3,5,3,1,-1,-3)
s2=s1+rep(c(1,-1),,,5)
L=w(1,"")
X=S=rep(0,L)
v0=w()
for(i in 1:L){X[i]=5
v1=v0-w()
X[i]=4
v2=v0-w()
S[i]=M[s1==v1&s2==v2]
X=0*S}
b=w(0,S)

इसे ऑनलाइन आज़माएं!

स्टड-स्टडआउट संस्करण, जैसा कि ओपी द्वारा अनुरोध किया गया है, कोई बॉयलरप्लेट्स नहीं। एक प्रारंभिक बग को ठीक करने के लिए कोलेरा सु के लिए धन्यवाद। यह टिप्पणियों में एक से थोड़ा कम संस्करण है।


TIO के भीतर परीक्षणों का एक बैच चलाने के लिए TIO सबमिशन के नीचे यहाँ

आर , 189 बाइट्स

M=0:9
s1=c(-5,-3,-1,1,3,5,3,1,-1,-3)
s2=c(-4,-2,0,2,4,4,2,0,-2,-4)
f=function(L){S=rep(0,L)
v0=v(S)
X=S
for(i in c(1:L)){X[i]=5
v1=v0-v(X)
X[i]=4
v2=v0-v(X)
S[i]=M[s1==v1&s2==v2]
X[i]=0}
S}

इसे ऑनलाइन आज़माएं!

आइए प्रारंभिक अनुमान के रूप में शून्य के एक वेक्टर पर विचार करें। चलो V को वर्तमान अनुमान और समाधान के बीच की दूरी कहते हैं। प्रत्येक स्थिति के लिए आपको केवल 0 में 5 के साथ और 4 के साथ वी में होने वाले परिवर्तनों की जांच करनी होगी। वास्तव में, 5 के साथ 0 बदलने के बीच अंतर मेरे वेक्टर एस 1 में सूचीबद्ध हैं। 4 के साथ 0 बदलने के बीच अंतर मेरे सदिश s2 में सूचीबद्ध हैं। जैसा कि आप इन दोनों वैक्टरों को विशिष्ट रूप से समाधान के अंकों को देखते हैं।

परीक्षणों की कुल संख्या इस प्रकार 3 * एल 2 * एल + 1 है, जहां एल कोड की लंबाई है: सभी शून्य के खिलाफ एक प्रारंभिक जांच, फिर प्रत्येक अंक के लिए दो चेक, 5 के खिलाफ एक और 4 के खिलाफ एक।

एक कारक 3 से एक कारक 2 में सुधार कामिल दकरी की अधीनता से प्रेरित था।

TIO सबमिशन की शेष राशि आर के लिए बॉयलरप्लेट है। TIO सबमिशन रनिंग टाइम और एल = 1 ... 200, 5 के साथ 1000 रन के लिए संचालन की कुल संख्या दर्शाती है। L के प्रत्येक मान के लिए प्रतिकृति है।


मुझे Error in scan(n = 1) : scan() expected 'a real', got 'S=rep(0,L)'निष्पादित करते समय मिलता है ।
कोलेरा सु

1
ऐसा लगता है कि scan(file=file("stdin"),n=1)काम करता है। यह कार्यक्रम (आपके जैसा, सिर्फ सही I / O) का स्कोर मिलता है 202999*ln(277+50)=1175356
कोलेरा सु

@ कोलरेसु, मुझे कुछ याद हो सकता है, लेकिन मैंने सोचा कि202999*ln(258+50) != 202999*ln(277+50)
NofP

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