[PYTHON] N-stellige Version des fragerseitigen Programms Hit & Blow (Numer0n) und des fragerseitigen Programms

1. Zuallererst

** "Hit & Blow" ** ist Es ist eine Art Zahlen-Ratespiel, bei dem zwei Spieler gegeneinander spielen. In Übersee heißt es ** Bulls & Cows **.

Als abgeleitetes Spiel ist ** Numer0n **, das im TV-Programm gezeigt wurde, berühmt. https://ja.wikipedia.org/wiki/Numer0n

Der Inhalt des Spiels selbst scheint vor über einem Jahrhundert entwickelt worden zu sein.

Es gibt auch ein Brettspiel namens "Mastermind", das um 1970 verkauft wurde. Die Regeln unterscheiden sich geringfügig von ** Hit & Blow (Bulls & Cows) **.

2. Spielregeln

Die Regeln des Spiels ** Hit & Blow (Bulls & Cows) ** lauten wie folgt.

Es wird normalerweise in 4 Ziffern gespielt, kann aber auch in 3 Ziffern oder einer anderen Ziffer gespielt werden.

Auf Papier schreibt jeder Spieler eine vierstellige Geheimnummer. Alle Zahlen müssen unterschiedlich sein.

Dann errät der Spieler wiederum die Nummer des Gegners, der die Anzahl der Spiele angibt, und stellt Fragen. ** "Hit" ** wenn sich die übereinstimmenden Zahlen an der richtigen Position befinden, ** "Blow" ** wenn sie sich an verschiedenen Positionen befinden. (In Numer0n heißen sie ** EAT ** bzw. ** BITE **.)

Zum Beispiel

Meine Antwort (Lösung): ** 4721 ** Frage des Gegners: ** 1234 **

Wenn ja, lautet die Antwort

** 1 Treffer ** und ** 2 Schläge ** (** Treffer ** ist ** "2" **, ** Schlag ** ist ** "4" ** und ** "1" **.)

Und teilen Sie das Ergebnis der anderen Partei mit. Wenn Sie die andere Person nicht mehr gefragt haben, fragen Sie die andere Person nach der Nummer, die Sie erraten haben.

Die Person, die die ** Geheimnummer (Antwort (Lösung)) ** des Gegners mit ** weniger Fragen ** als der Gegner errät, ist der ** Gewinner **.

3. Fragestellerseitenprogramm und Fragestellerseitenprogramm

3.1. Programm des Fragestellers

Die ** Hit & Blow (Bulls & Cows) ** Regeln sind einfach und

Generieren Sie zufällige Antworten und beantworten Sie Bullen- und Kuhzahlen auf menschliche Fragen Das ** Fragestellerprogramm ** wurde früh erstellt.

Der erste ist berühmt für ** "MOO" **, [Multics-Betriebssystem](https: // en) mit ** PL / I ** von ** JM Grochow ** im Jahr 1970 Geschrieben für .wikipedia.org / wiki / Multics).

Bei einigen ** Unix ** der ** BSD-Serie ** ist das ** MOO ** -Fragenprogramm noch standardmäßig installiert.

Als Anfängeraufgabe in der Programmierung scheint es, dass es oft an Schulen gefragt wird.

3.2. Programm des Fragestellers

Auf der anderen Seite das ** Fragesteller-Programm **, mit dem der Computer ** Hit & Blow (Bulls & Cows) ** spielen kann ** Im Vergleich zum ** Fragesteller-Programm ** ist der Rechenaufwand groß und kompliziert.

Auf einem typischen 16-Bit-PC vor 30 Jahren Es dauerte ein paar Minuten, bis die Antwort richtig war.

Bei PCs kann heutzutage jedoch sofort die richtige Antwort gefunden werden. (Wenn Sie 8 oder mehr Ziffern in Python verarbeiten möchten, müssen Sie eine Weile warten.)

Übrigens, auch wenn Sie den Prozess schreiben, um eine 4-stellige Lösung in ** Python3 ** zu finden, Bei modernen CPUs scheint die Lösung innerhalb von ** 0,02 Sekunden ** gefunden zu werden. Sogar die ** 10.000 Fragen ** Fragen wurden in ** 170 Sekunden ** beantwortet. (Für Inten (R) Core (TM) i5-8265U-CPU bei 1,60 GHz (1,80 GHz))

Zwischen 1995 und 2000 wurde es in ** JavaScript ** usw. beschrieben. Es sind viele Websites erschienen, die mit dem ** Fragesteller-Programm ** im Web abgespielt werden können. Sie können immer noch viele finden, indem Sie suchen.

Bei einem 4-stelligen Spiel beträgt die Anzahl der Kandidaten zum Zeitpunkt der ersten Frage

10×9×8×7 = 5040

Es gibt.

Abhängig von der von Ihnen angeforderten Nummer und dem Ergebnis der Antwort wird der Satz festgelegt, der die Bedingungen für die Antwort erfüllt.

Wie man die beste Frage für das Set stellt Es ist ein Punkt, ein starkes ** Fragesteller-Nebenprogramm ** zu machen.

Diese Geschichte wird später in einem späteren Kapitel besprochen.

In ** 1987 ** wurde dieses Problem als Problem für ** bit ** ** Nanopico Class ** angesprochen. Das Programm des Gewinners war zu diesem Zeitpunkt ** Die durchschnittliche Mindestanzahl an Fragen ** betrug ** 5,22 (Gesamtzahl der Fragen 26347) **.

In ** 1996 ** wurde die ** durchschnittliche Mindestanzahl von Fragen 26274/5040 = 5,2131 ** erreicht.

Im Fall von 4-stelligem ** Hit & Blow (Bulls & Cows) ** wurde nachgewiesen, dass jede Zahl innerhalb von ** 7 Runden ** aufgelöst werden kann.

4. Ich habe es in Python geschrieben

Das erstellte Programm ist unten angeordnet. https://github.com/NobuyukiInoue/pyHitAndBlow

Es ist Zeit, die Nummer für die erste Frage zu bestimmen, Es gibt eine Möglichkeit, Fragen zu stellen wie ** "0123" **,

Wenn die andere Partei ein Mensch ist, werden Maßnahmen ergriffen Zufallszahlen werden verwendet, um n-stellige Zufallszahlen zu generieren und zu verwenden, die sich voneinander unterscheiden.

** Im fragerseitigen Programm ** wird der Prozess der Vorbereitung der Antwortnummer, In ** Programm auf der Fragesteller-Seite **, während Sie die Nummer auswählen, um eine Frage zu stellen,

Sie werden jeden brauchen.

In meinem Programm habe ich ** Treffer ** und ** Schläge ** für Fragen berechnet. Zur Vereinfachung (nicht beschleunigen) Ich habe beschlossen, die ** n-stellige Nummer ** der Antwort oder Frage als ** Zeichenfolge ** zu behandeln.

Wenn Sie Zufallszahlen ziffernweise generieren und verketten, gehen Sie wie folgt vor.

Gibt n verschiedene Zufallszahlen zurück(random.randint()Auflage)


def create_random_n_digits_number(n:int) -> str:
    target_number_str = ""
    for _ in range(n):
        while True:
            d = str(random.randint(0, 9))
            if d not in target_number_str:
                target_number_str += d
                break
    return target_number_str

Übrigens ist der obige Prozess Dies kann in einer Zeile erreicht werden, indem die ** Stichprobenfunktion ** des ** Zufallsmoduls ** verwendet wird.

Gibt n verschiedene Zufallszahlen zurück(random.sample()Auflage)


def create_random_n_digits_number(n:int) -> str:
    return "".join([str(_) for _ in random.sample(list(range(10)), n)])

Auch wenn Antwortnummern und Fragennummern als Zeichenfolgen behandelt werden, ** Trefferzahl ** und ** Schlagzahl ** können durch die folgende Verarbeitung zusammengestellt werden.

Ordnen Sie die Fragennummer der Lösungskandidatennummer zu und geben Sie die Treffer- und Schlagnummer zurück (Teil 1).


def response_check(n:int, answer_number:str, target_number:str) -> (int, int):
    """
    response check.
    """
    H, B = 0, 0
    for i in range(0, n):
        if target_number[i] == answer_number[i]:
            H += 1
        else:
            for j in range(0, n):
                if i != j and target_number[i] == answer_number[j]:
                    B += 1
    return H, B

Oder

Ordnen Sie die Fragennummer der Lösungskandidatennummer zu und geben Sie die Treffer- und Schlagnummer zurück (Teil 2).


def response_check(n:int, answer_number:str, target_number:str) -> (int, int):
    """
    response check.
    """
    H, B = 0, 0
    for n, m in zip(answer_number, target_number):
        if n == m:
            H += 1
        elif n in target_number:
            B += 1
    return H, B

Die Bearbeitungszeit der Sekunde ist übrigens kürzer.

Als nächstes werden n-stellige Kandidaten für die erste Frage generiert.

Bei 4 Ziffern beträgt der Zahlenbereich "0123-9876". Die Anzahl der Lösungskandidaten beträgt "9 * 8 * 7 * 6 = 5040".

Es gibt verschiedene Möglichkeiten, es zu generieren, Wenn Sie es rekursiv aufrufen, um n Ziffern zu entsprechen, ist es wie folgt.

Erstellen Sie eine Liste mit Kandidatennummern für die (erste) Lösung


def create_target_numbers(n:int)-> [str]:
    """
    create target numbers.
    """
    target_numbers = []

    def sub_create_target_numbers(n, workStr):
        if n == 0:
            target_numbers.append(workStr)
            return
        for i in range(10):
            if str(i) not in workStr:
                sub_create_target_numbers(n - 1, workStr + str(i))

    if n == 1:
        for i in range(10):
            target_numbers.append(str(i))
    
    elif n > 1:
        for i in range(10):
            sub_create_target_numbers(n - 1, str(i))

    return target_numbers

4-1. Ein Programm, das n-stellige Zufallszahlen ausgibt, die sich voneinander unterscheiden

Wir haben ein Programm vorbereitet, das nur n-stellige Zufallszahlen ausgibt, die sich voneinander unterscheiden. Dieses Programm wird zum Testen des ** Fragestellerprogramms ** verwendet.

https://github.com/NobuyukiInoue/pyHitAndBlow/blob/master/create_random_n_digits_number.py https://github.com/NobuyukiInoue/pyHitAndBlow/blob/master/mylibs/lib_hit_and_blow.py

4-1-1. Ausführungsmethode

Das Format des Fragestellerprogramms ist wie folgt.

create_random_n_digits_number.py [N]
Möglichkeit Erläuterung
N Anzahl der Ziffern (2 <= N <= 10)
(Standardwert ist 4)

4-1-2. Ausführungsbeispiel

$ python create_random_n_digits_number.py 4
2357

4-2. Programm auf der Fragestellerseite

Das von mir erstellte ** Fragesteller-Programm ** ist unten aufgeführt. ** Fragesteller-Programm ** ist ein relativ einfaches Programm.

Da es lange dauern wird, werde ich die Veröffentlichung der Quelle unterlassen.

https://github.com/NobuyukiInoue/pyHitAndBlow/blob/master/pyHitAndBlow_defence.py https://github.com/NobuyukiInoue/pyHitAndBlow/blob/master/mylibs/lib_hit_and_blow.py

4-2-1. Ausführungsmethode

Das Format des Arguments ist wie folgt.

pyHitAndBlow_defence.py [N [enable print] [answer number]]]
Möglichkeit Erläuterung
N Anzahl der Stellen in der Antwort (2 <= N <= 10)
(Standardwert ist 4)
enable_print unused (Standardwert ist False)
Antwortnummer Antwortnummer. Sie können die Antwortnummer auch im Voraus angeben.

4-2-2. Ausführungsbeispiel

$ python pyHitAndBlow_defence.py 4
N ... 4
When you want to end on the way, please input 0

[1] : select number xxxx = 3429        <--- "3429"Eingeben
input response is Hit = 0, Blow = 2
[2] : select number xxxx = 7594        <--- "7594"Eingeben
input response is Hit = 0, Blow = 1
[3] : select number xxxx = 9613        <--- "9613"Eingeben
input response is Hit = 1, Blow = 2
[4] : select number xxxx = 9386        <--- "9386"Eingeben
input response is Hit = 2, Blow = 1
[5] : select number xxxx = 9036        <--- "9036"Eingeben
input response is Hit = 1, Blow = 3
[6] : select number xxxx = 9360        <--- "9360"Eingeben
input response is Hit = 4, Blow = 0

congratulations!!!
my answer number is 9360.


===== challenge history ======
[1]  .... 3429 (0, 2)
[2]  .... 7594 (0, 1)
[3]  .... 9613 (1, 2)
[4]  .... 9386 (2, 1)
[5]  .... 9036 (1, 3)
[6]  .... 9360 (4, 0)

4-3. Programm des Fragestellers

Das Fragesteller-Programm ist unten.

https://github.com/NobuyukiInoue/pyHitAndBlow/blob/master/pyHitAndBlow_offence.py https://github.com/NobuyukiInoue/pyHitAndBlow/blob/master/mylibs/lib_hit_and_blow.py

Der allgemeine Verarbeitungsablauf des Programms des Fragestellers ist

  1. Erstellen Sie eine Liste mit "Zahlen, die Kandidatenlösungen sind".
  2. Lesen Sie die "Fragennummer der anderen Partei"
  3. Passen Sie die "Fragennummer der anderen Partei" und die "Kandidatennummer der Lösung" nacheinander an und lassen Sie nur die Kandidaten übrig, deren Treffer- und Schlagnummer übereinstimmen.

Wird bearbeitet,

Wenn die Anzahl der Ziffern 4 beträgt, wiederholen Sie den Vorgang, bis die Antwort ** Treffer 4 ** lautet.

Der Prozess von 3 ist wie folgt.

Generieren Sie die nächste Liste der "Kandidatenlösungen" neu, und lassen Sie nur Kandidaten mit übereinstimmenden Treffern und Schlägen übrig


        # create new canidiates numbers list.
        new_target_numbers = []

        for current_number in target_numbers:
            if answer_check(n, current_number, selected_number, H, B):
                # new candidates number add.
                new_target_numbers.append(current_number)

        target_numbers = new_target_numbers

In der ersten Frage, egal welche Nummer Sie fragen

Die Wahrscheinlichkeit einer korrekten Antwort beträgt ** 1/5040 **, wenn die Anzahl der Ziffern 4 und beträgt Die Anzahl der Fragen, die erforderlich sind, um eine Lösung zu finden, ist unentschlossen.

Abhängig vom Ergebnis der Beantwortung der zweiten Frage Im schlimmsten Fall wird die Gesamtzahl der Fragen bestimmt, um die Lösung zu erreichen.

Besonders in dieser zweiten Frage

** Anstatt die Nummer auszuwählen, die als nächstes aus der Liste der "Kandidatennummern" gefragt werden soll ** ** Es ist besser, "Nummer, die die Anzahl der Fragen minimiert, bis eine Lösung gefunden wird" ** auszuwählen und eine Frage zu stellen.

Die durchschnittliche Anzahl der Fragen ist gering. Diese Methode heißt ** "Minimum Question Strategy" **.

Nach etwa 10.000 Versuchen

** Bei Auswahl aus der Liste der "Zahlen, die Kandidatenlösungen sind" ** Die durchschnittliche Anzahl der Fragen lag bei ** 5,469 **,

Nur die zweite Frage (in der aktuellen Implementierung), Wenn Sie in ** "Minimum Question Strategy" ** fragen Die durchschnittliche Anzahl der Fragen ist auf ** 5,436 ** gesunken.

Wenn Sie nach unten gehen, wird es auf ** 5.2131 **, Wir haben (zu diesem Zeitpunkt) nicht so viel implementiert.

Vielleicht müssen Sie auch die zufällige Verzerrung des Zufallsmoduls in Python berücksichtigen. (Tatsächlich weisen die im Allgemeinen verwendeten zufallsbezogenen Bibliotheken Unterschiede darin auf, dass es Werte gibt, die wahrscheinlich auftreten, und Werte, die wahrscheinlich nicht auftreten, weil das Innere durch Binärzahlen dargestellt wird.)

4-3-1. Wählen Sie die Nummer aus, um den Lösungskandidaten die nächste Frage zu stellen

** "Wählen Sie die Nummer aus, um die nächste Frage von den Lösungskandidaten zu stellen" ** Die Verarbeitung in diesem Fall ist wie folgt.

Geben Sie unter Verwendung von Zufallszahlen eine Ganzzahl im Bereich der Elemente (0 bis len (Zielnummern) -1) in der ** Liste der Lösungskandidaten ** zurück. Gibt den Wert dieses Elements als die Nummer zurück, die als nächstes gefragt werden soll.

Ab dem zweiten Mal kann dieselbe Nummer wie die, die Sie in der Vergangenheit gefragt haben, ausgewählt werden Wenn die Zahlen gleich sind, werden die Kandidaten erneut ausgewählt.

Wählen Sie die Nummer aus, um die nächste Frage unter den Lösungskandidaten zu stellen


def create_canidiate_number(n:int, target_numbers:[str], history:HistoryRecords) -> str:
    """
    create canidiate number.
    """
    if len(history.challenge) == 0:
        index = random.randint(0, len(target_numbers) - 1)
        return target_numbers[index]
    else:
        while True:
            index = random.randint(0, len(target_numbers) - 1)
            if target_numbers[index] in history.challenge:
                continue
            return target_numbers[index]

Bei dieser Methode habe ich erklärt, dass die durchschnittliche Anzahl der Fragen ** 5,469 ** beträgt. Trotzdem ist es im Vergleich zu Menschen ** ziemlich stark **. (Ich kann übrigens kaum gewinnen)

4-3-2. Strategie für Mindestfragen

Bei der "Mindestfragenstrategie" wird die Nummer der zweiten Frage durch die Anzahl und Antwort der ersten Frage bestimmt.

Wenn die erste Frage beispielsweise ** "0123" ** lautet, wählen Sie eine Zahl wie die folgende aus.

Die von Ihnen ausgewählte Anzahl ist also nicht auf Lösungskandidaten beschränkt In einigen Fällen wird eine Nummer ausgewählt, die wahrscheinlich nicht richtig beantwortet wird.

Es ist erwiesen, dass die durchschnittliche Anzahl der richtig zu beantwortenden Fragen abnimmt.

Erste Antwort Zweite Frage Elementanzahl Gesamtzahl der Fragen Mit der ersten Fragennummer
Zweite Frage番号の
Unterschied
4H0B ---- 1 0 ---
3H0B 0245 24 73 1H1B
2H2B 0132 6 15 2H2B
2H1B 0145 72 240 2H0B
2H0B 0245 180 659 1H1B
1H3B 0134 8 22 2H1B
1H2B 0245 216 804 1H1B
1H1B 0245 720 2992 1H1B
1H0B 0456 480 1446 1H0B
0H4B 1230 9 23 0H4B
0H3B 1435 264 1004 0H2B
0H2B 1245 1260 5548 0H2B
0H1B 1456 1440 6595 0H1B
0H0B 4567 360 1446 0H0B

Referenzen) Minimale Fragestrategie und stärkste Strategie des Zahlenschätzspiels MOO https://www.tanaka.ecc.u-tokyo.ac.jp/ktanaka/papers/gpw96.pdf

Wählen Sie die Anzahl, die die Anzahl der Fragen minimiert


def create_canidiate_number4_Minimum_question_strategy(n:int, target_numbers:[str], history:HistoryRecords) -> str:
    """
    create canidiate number.
    (Minimum question strategy)
    """
    if len(history.challenge) == 1:
        while True:
            selected_number = create_random_n_digits_number(n)
            if selected_number in history.challenge:
                continue
            H, B = response_check(n, history.challenge[-1], selected_number)

            if history.response[-1] == [3, 0]:
                if (H, B) == (1, 1):
                    return selected_number
            elif history.response[-1] == [2, 2]:
                if (H, B) == (2, 2):
                    return selected_number
            elif history.response[-1] == [2, 1]:
                if (H, B) == (2, 0):
                    return selected_number
            elif history.response[-1] == [2, 0]:
                if (H, B) == (1, 1):
                    return selected_number
            elif history.response[-1] == [1, 3]:
                if (H, B) == (2, 1):
                    return selected_number
            elif history.response[-1] == [1, 2]:
                if (H, B) == (1, 1):
                    return selected_number
            elif history.response[-1] == [1, 1]:
                if (H, B) == (1, 1):
                    return selected_number
            elif history.response[-1] == [1, 0]:
                if (H, B) == (1, 0):
                    return selected_number
            elif history.response[-1] == [0, 4]:
                if (H, B) == (0, 4):
                    return selected_number
            elif history.response[-1] == [0, 3]:
                if (H, B) == (0, 2):
                    return selected_number
            elif history.response[-1] == [0, 2]:
                if (H, B) == (0, 2):
                    return selected_number
            elif history.response[-1] == [0, 1]:
                if (H, B) == (0, 1):
                    return selected_number
            elif history.response[-1] == [0, 0]:
                if (H, B) == (0, 0):
                    return selected_number
            else:
                return selected_number

    else:
        while True:
            index = random.randint(0, len(target_numbers) - 1)
            if target_numbers[index] in history.challenge:
                continue
            return target_numbers[index]

4-3-3. Ausführungsmethode

Das Format des Fragestellerprogramms ist wie folgt.

pyHitAndBlow_offence.py [N [enable print] [answer number]]]
Möglichkeit Erläuterung
N Anzahl der Stellen in der Antwort (2 <= N <= 10)
(Standardwert ist 4)
Druck aktivieren Anzeige / Nichtanzeige der verbleibenden Lösungskandidatenliste angeben (Standardwert ist False)
anser_number Antwortnummer

4-3-4. Ausführungsbeispiel

Die Standardanzahl der Ziffern ist 4. Kandidaten für die verbleibenden Stockwerke sind Beispiele für die Ausführung, wenn sie versteckt sind. Geben Sie ** Treffer ** und ** Schläge ** manuell ein.

$ python pyHitAndBlow_offence.py

(remaining count = 5040) Is your number 7016 ?
[1] : please input H, B = 0,1      <-- "0,1"Außerdem"0 1", "01"Aber ja

(remaining count = 1440) Is your number 2950 ?
[2] : please input H, B = 0,1

(remaining count =  378) Is your number 4365 ?
[3] : please input H, B = 0,2      <-- "0,2"Außerdem"0 2", "02"Aber ja

(remaining count =   99) Is your number 3628 ?
[4] : please input H, B = 0,2

(remaining count =   19) Is your number 1234 ?
[5] : please input H, B = 4,0      <-- "4,0"Außerdem"4 0", "4"Aber ja
calculate successful.

===== challenge history =====
[1](5040) ---> 7016 (0, 1)
[2](1440) ---> 2950 (0, 1)
[3]( 378) ---> 4365 (0, 2)
[4](  99) ---> 3628 (0, 2)
[5](  19) ---> 1234 (4, 0)

4-3-5 Über Antwortfehler

Wenn Sie die falsche Antwort ** für die von Ihnen vorbereitete Antwort eingeben, Da sich in der Mitte keine Lösungskandidaten befinden, endet diese, bevor die ** Trefferzahl 4 ** erreicht.

** Vergleichen Sie die angeforderte Nummer und Ihre Antwort ** und seien Sie vorsichtig **, um sicherzugehen. ** Ich selbst mache in 5-10% der Fälle Fehler. ** **.

Da ** Berechnung fehlgeschlagen ** in Zehntausenden von Tests nicht aufgetreten ist, Es scheint (wahrscheinlich) keine Fehler im Programm zu geben. (Das Testskript wird später beschrieben.)

Das Folgende ist

Die Antwort, die ich vorbereitet habe, sollte ** "1234" ** sein, Weil ich in der ersten Antwort ** "0 2" ** anstelle von ** "2 0" ** geantwortet habe Dies ist ein Beispiel für das Beenden ohne Erreichen von ** Hits == 4 **.

$ python pyHitAndBlow_offence.py

(remaining count = 5040) Is your number 9238 ?
[1] : please input H, B = 0 2       <--- "2 0"Nicht aus Versehen"0 2"Wird eingegeben
input response is Hit = 0, Blow = 2

(remaining count = 1260) Is your number 1792 ?
[2] : please input H, B = 1 1
input response is Hit = 1, Blow = 1

(remaining count =  204) Is your number 2763 ?
[3] : please input H, B = 0 2
input response is Hit = 0, Blow = 2

(remaining count =   47) Is your number 1324 ?
[4] : please input H, B = 2 2
input response is Hit = 2, Blow = 2

(remaining count =    0) calculate failed.

===== challenge history ======
[1](5040) ---> 9238 (0, 2)
[2](1260) ---> 1792 (1, 1)
[3]( 204) ---> 2763 (0, 2)
[4](  47) ---> 1324 (2, 2)

4-3-6. Automatischer Antwortmodus

Wenn Sie Probleme bei der Eingabe der Antwort haben,

Geben Sie nach Angabe der Anzahl der Ziffern und Anzeige der Lösungskandidaten die richtige Antwortnummer an. Sie können sie auch automatisch beantworten lassen.

In dem später beschriebenen Testskript wird das ** fragerseitige Programm ** in diesem ** automatischen Antwortmodus ** ausgeführt.

$ python pyHitAndBlow_offence.py 4 false 1234
N ... 4
set answer number ... 1234

(remaining count = 5040) Is your number 1653 ?
input response is Hit = 1, Blow = 1

(remaining count =  720) Is your number 7463 ?
input response is Hit = 0, Blow = 2

(remaining count =  165) Is your number 6054 ?
input response is Hit = 1, Blow = 0

(remaining count =   16) Is your number 3257 ?
input response is Hit = 1, Blow = 1

(remaining count =    2) Is your number 1234 ?
input response is Hit = 4, Blow = 0
calculate successful.

===== challenge history =====
[1](5040) ---> 1653 (1, 1)
[2]( 720) ---> 7463 (0, 2)
[3]( 165) ---> 6054 (1, 0)
[4](  16) ---> 3257 (1, 1)
[5](   2) ---> 1234 (4, 0)

4-4. Testskript für das Programm des Fragestellers

Zum Testen des Fragestellerprogramms steht auch ein Testskript zur Verfügung. https://github.com/NobuyukiInoue/pyHitAndBlow/blob/master/test_pyHitAndBlow.py https://github.com/NobuyukiInoue/pyHitAndBlow/blob/master/testscripts/test_pyHitAndBlow.sh https://github.com/NobuyukiInoue/pyHitAndBlow/blob/master/testscripts/test_pyHitAndBlow.ps1

Beide Testskripte nehmen als Argument Sie können ** die Anzahl der Stellen in der Antwort und der Frage ** und ** die Häufigkeit angeben, mit der das Programm des Fragestellers ausgeführt wird **. Nachdem das fragenseitige Programm eine bestimmte Anzahl von Malen ausgeführt wurde, werden die ** durchschnittliche Anzahl von Fragen ** und ** Ausführungszeit ** ausgegeben, die erforderlich sind, bis die endgültige richtige Antwort vorliegt.

4-4-1. Geschätzte Ausführungszeit des Testskripts

Als Referenz das fragerseitige Programm im automatischen Antwortmodus, Wir werden die Ausführungszeit veröffentlichen, wenn die Lösung 4-stellig ist und 10000 Mal ausgeführt wird.

Item Value
CPU Inten(R) Core(TM) i7-8559U CPU @ 2.70GHz
Speicher 16 GB (LPDDR3 / 2133 MHz)
Dateiname OS Ausführungszeit
test_pyHitAndBlow.py Windows 10 Pro(version 2004) 166[s]
test_pyHitAndBlow.py Windows 10 Pro(version 2004)
(Out-Exportieren Sie mit dem Cmdlet Datei in eine Datei.
Die Festplatte ist möglicherweise langsamer)
129[s]
test_pyHitAndBlow.py WSL2(ubuntu18.04) 123[s]
Art OS Ausführungszeit
test_pyHitAndBlow.sh(bash) WSL2(ubuntu18.04) 530[s]
test_pyHitAndBlow.ps1(PowerShell) WSL2(ubuntu18.04) 554[s]
test_pyHitAndBlow.ps1(PowerShell) Windows 10 Pro(version 2004) 1295[s]

In der Shell-Skriptversion wird pyHitAndBlow_offence.py jedes Mal gestartet, wenn eine Frage gestellt wird. Es ist aufgrund des hohen Overheads beim Starten / Beenden von Prozessen erheblich langsamer als die Einzelprozessversion.

4-4-2. Python3-Version (test_pyHitAndBlow.py)

Ausführungsmethode
python test_pyHitAndBlow.py [N [MAX]]
Ausführungsbeispiel
$ python test_pyHitAndBlow.py 4 10
...
...
(remaining count =    2) Is your number 3970 ?
input response is Hit = 2, Blow = 2

(remaining count =    1) Is your number 9370 ?
input response is Hit = 4, Blow = 0

===== challenge history ======
[1]  .... 5076 (1, 1)
[2]  .... 6049 (0, 2)
[3]  .... 5634 (0, 1)
[4]  .... 4870 (2, 0)
[5]  .... 3970 (2, 2)
[6]  .... 9370 (4, 0)

# Latest Average = 5.4000

==== ResultCount history =====
ResultCount[0] = 7
ResultCount[1] = 5
ResultCount[2] = 6
ResultCount[3] = 5
ResultCount[4] = 4
ResultCount[5] = 5
ResultCount[6] = 5
ResultCount[7] = 5
ResultCount[8] = 6
ResultCount[9] = 6
======== distribution ========
0 ... 0
1 ... 0
2 ... 0
3 ... 0
4 ... 1
5 ... 5
6 ... 3
7 ... 1
8 ... 0
9 ... 0
10 ... 0
11 ... 0
12 ... 0
Distribution list Total = 10
==============================
Total Questions = 54
Total Average   = 5.4
==============================
start ... 2020-09-05 12:03:34.129205
end   ... 2020-09-05 12:03:34.271266

4-4-3. Für Bash (test_pyHitAndBlow.sh)

Ausführungsmethode
test_pyHitAndBlow.sh [N [MAX]]
Ausführungsbeispiel (test_pyHitAndBlow.sh)
$ ./testscripts/test_pyHitAndBlow.sh 4 10
...
...
(remaining count =    6) Is your number 6097 ?
input response is Hit = 0, Blow = 2

(remaining count =    1) Is your number 8160 ?
input response is Hit = 4, Blow = 0
calculate successful.

===== challenge history ======
[1](5040) ---> 4065 (1, 1)
[2]( 720) ---> 4203 (0, 1)
[3]( 180) ---> 8495 (1, 0)
[4](  26) ---> 1467 (1, 1)
[5](   6) ---> 6097 (0, 2)
[6](   1) ---> 8160 (4, 0)

# Latest Average = 5.4000

==== ResultCount history =====
result_count[0] = 4
result_count[1] = 5
result_count[2] = 6
result_count[3] = 5
result_count[4] = 6
result_count[5] = 4
result_count[6] = 5
result_count[7] = 6
result_count[8] = 7
result_count[9] = 6
======== distribution ========
0 ... 0
1 ... 0
2 ... 0
3 ... 0
4 ... 2
5 ... 4
6 ... 3
7 ... 1
8 ... 0
9 ... 0
10 ... 0
11 ... 0
12 ... 0
Distribution list total = 10
==============================
Total Questions = 53
Total average   = 5.3000
==============================
start ... 2020-09-05 13:09:44
end   ... 2020-09-05 13:09:46
total execution time ... 2[s]

4-4-4. Für PowerShell (test_pyHitAndBlow.sh)

Ausführungsmethode
test_pyHitAndBlow.ps1 [N] [MAX]
Ausführungsbeispiel
D:\pyHitAndBlow> .\testscripts\test_pyHitAndBlow.ps1 4 10
...
...
(remaining count =   16) Is your number 3895 ?
input response is Hit = 2, Blow = 2

(remaining count =    1) Is your number 5893 ?
input response is Hit = 4, Blow = 0
calculate successful.

===== challenge history ======
[1](5040) ---> 6380 (0, 2)
[2](1260) ---> 4069 (0, 1)
[3]( 304) ---> 1938 (0, 3)
[4](  16) ---> 3895 (2, 2)
[5](   1) ---> 5893 (4, 0)

# Latest Average = 5.4

==== ResultCount history =====
ResultCount[0] = 6
ResultCount[1] = 5
ResultCount[2] = 7
ResultCount[3] = 4
ResultCount[4] = 5
ResultCount[5] = 7
ResultCount[6] = 4
ResultCount[7] = 6
ResultCount[8] = 5
ResultCount[9] = 5
======== distribution ========
0 ... 0
1 ... 0
2 ... 0
3 ... 0
4 ... 2
5 ... 4
6 ... 2
7 ... 2
8 ... 0
9 ... 0
10 ... 0
11 ... 0
Distribution list Total = 10
==============================
Total Questions = 54
Total Average   = 5.4
==============================
start ... 2020-09-05 12:20:56
end   ... 2020-09-05 12:20:57
Total execution time ... 1.1599779[s]

5. Schlussfolgerung

Für die minimale durchschnittliche Strategie

Wie oben erwähnt Derzeit nur implementiert, wenn ** n = 4 **, Wir implementieren die Mindestfragenstrategie nur für die zweite Frage.

Andere, Es kann einige Fehler im Programm geben, aber Ich würde mich freuen, wenn Sie mich freundlich informieren könnten.

Recommended Posts

N-stellige Version des fragerseitigen Programms Hit & Blow (Numer0n) und des fragerseitigen Programms
Über Probleme und Lösungen von OpenPyXL (Version 3.0)