Drücken Sie eine Zahl aus
In den 60er Jahren erfanden die Franzosen die TV-Spielshow "Des Chiffres et des Lettres" (Ziffern & Buchstaben). Das Ziel des Digits-Teils der Show war es, einer bestimmten dreistelligen Zielzahl so nahe wie möglich zu kommen, wobei einige halbzufällig ausgewählte Zahlen verwendet wurden. Die Teilnehmer könnten die folgenden Operatoren verwenden:
- Verkettung (1 und 2 ist 12)
- Addition (1 + 2 ist 3)
- Subtraktion (5 - 3 = 2)
- Division (8/2 = 4); Teilung ist nur zulässig, wenn das Ergebnis eine natürliche Zahl ist
- Multiplikation (2 * 3 = 6)
- Klammern, um die reguläre Priorität von Operationen zu überschreiben: 2 * (3 + 4) = 14
Jede angegebene Nummer kann nur einmal oder gar nicht verwendet werden.
Beispielsweise kann die Zielnummer 728 genau mit den Zahlen 6, 10, 25, 75, 5 und 50 mit dem folgenden Ausdruck übereinstimmen:
75 * 10 - ( ( 6 + 5 ) * ( 50 / 25 ) ) = 750 - ( 11 * 2 ) = 750 - 22 = 728
In dieser Code-Challenge haben Sie die Aufgabe, einen Ausdruck zu finden, der einer bestimmten Zielnummer möglichst nahe kommt. Da wir im 21. Jahrhundert leben, werden wir größere Zielzahlen und mehr Zahlen einführen, mit denen wir arbeiten können als in den 60er Jahren.
Regeln
- Zulässige Operatoren: Verkettung, +, -, /, *, (und)
- Der Verkettungsoperator hat kein Symbol. Verketten Sie einfach die Zahlen.
- Es gibt keine "inverse Verkettung". 69 ist 69 und kann nicht in eine 6 und eine 9 aufgeteilt werden.
- Die Zielnummer ist eine positive Ganzzahl und besteht aus maximal 18 Ziffern.
- Es gibt mindestens zwei Nummern und maximal 99 Nummern. Diese Zahlen sind auch positive ganze Zahlen mit maximal 18 Stellen.
- Es ist möglich (tatsächlich sehr wahrscheinlich), dass die Zielnummer nicht in Zahlen und Operatoren ausgedrückt werden kann. Das Ziel ist es, so nah wie möglich zu kommen.
- Das Programm sollte in einer angemessenen Zeit beendet sein (einige Minuten auf einem modernen Desktop-PC).
- Es gelten Standardlücken.
- Ihr Programm ist möglicherweise nicht für das Testset im Abschnitt "Wertung" dieses Puzzles optimiert. Ich behalte mir das Recht vor, das Testset zu ändern, wenn ich den Verdacht habe, dass jemand gegen diese Regel verstößt.
- Dies ist kein Codegolf.
Eingang
Die Eingabe besteht aus einer Reihe von Zahlen, die auf beliebige Weise formatiert werden können. Die erste Nummer ist die Zielnummer. Die restlichen Zahlen sind die Zahlen, mit denen Sie arbeiten sollten, um die Zielnummer zu bilden.
Ausgabe
Die Anforderungen für die Ausgabe sind:
- Es sollte eine Zeichenfolge sein, die aus Folgendem besteht:
- Beliebige Untermenge der eingegebenen Nummern (außer der Zielnummer)
- Beliebig viele Bediener
- Ich bevorzuge die Ausgabe als einzelne Zeile ohne Leerzeichen, aber wenn Sie müssen, können Sie Leerzeichen und Zeilenumbrüche hinzufügen, wie Sie es für richtig halten. Sie werden im Steuerungsprogramm ignoriert.
- Die Ausgabe sollte ein gültiger mathematischer Ausdruck sein.
Beispiele
Zur besseren Lesbarkeit haben alle diese Beispiele eine exakte Lösung und jede Eingabenummer wird genau einmal verwendet.
Eingabe: 1515483, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
Ausgabe:111*111*(111+11+1)
Eingabe: 153135, 1, 2, 3, 4, 5, 6, 7, 8, 9
Ausgabe:123*(456+789)
Eingabe: 8888888888, 9, 9, 9, 99, 99, 99, 999, 999, 999, 9999, 9999, 9999, 99999, 99999, 99999, 1
Ausgabe:9*99*999*9999-9999999-999999-99999-99999-99999-9999-999-9-1
Eingabe: 207901, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
Ausgabe:1+2*(3+4)*(5+6)*(7+8)*90
Eingabe: 34943, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
Ausgabe: 1+2*(3+4*(5+6*(7+8*90)))
Aber auch gültige Ausgabe ist:34957-6-8
Wertung
Die Strafpunktzahl eines Programms ist die Summe der relativen Fehler der Ausdrücke für das unten stehende Testset.
Wenn zum Beispiel der Zielwert 125 ist und Ihr Ausdruck 120 ergibt, ist Ihre Strafpunktzahl abs (1 - 120/125) = 0,04.
Das Programm mit der niedrigsten Punktzahl (niedrigster relativer Gesamtfehler) gewinnt. Beenden zwei Programme gleich, gewinnt die erste Einreichung.
Zum Schluss das Testset (8 Fälle):
14142, 10, 11, 12, 13, 14, 15
48077691, 6, 9, 66, 69, 666, 669, 696, 699, 966, 969, 996, 999
333723173, 3, 3, 3, 33, 333, 3333, 33333, 333333, 3333333, 33333333, 333333333
589637567, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
8067171096, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199
78649377055, 0, 2, 6, 12, 20, 30, 42, 56, 72, 90, 110, 132, 156, 182, 210, 240, 272, 306, 342, 380, 420, 462, 506, 552, 600, 650, 702, 756, 812, 870, 930, 992
792787123866, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169
2423473942768, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 2000000, 5000000, 10000000, 20000000, 50000000
Vorherige ähnliche Rätsel
Nachdem ich dieses Rätsel erstellt und in der Sandbox veröffentlicht hatte, bemerkte ich in zwei vorherigen Rätseln etwas Ähnliches (aber nicht dasselbe!): Hier (keine Lösungen) und hier . Dieses Rätsel ist etwas anders, weil es den Verkettungsoperator einführt, ich nicht suche und exakte Übereinstimmung und ich mag es, Strategien zu sehen, um der Lösung ohne rohe Gewalt näher zu kommen. Ich finde es herausfordernd.
quelle
Antworten:
C ++ 17, Punktzahl .0086
Dieses Programm hat aufgrund von Thread-Rennen einen nicht deterministischen Strafpunktestand. Ich beziehe mich daher auf durchschnittlich drei Läufe, von denen jeder die Testsuite in weniger als einer Minute bewältigte:
Hier ist das Programm; Erläuterungen finden Sie in den Kommentaren. Sie können
CONCAT_NONE
für herkömmliche Countdown-Regeln definieren, die keine Verkettung zulassen, oderCONCAT_DIGITS
die Verkettung der Eingabewerte zulassen, jedoch keine Zwischenergebnisse. Standardmäßig werden die liberalsten Regeln verwendet, ohne dass eine der beiden definiert ist.Ich habe dies mit GCC 6.2 kompiliert
g++ -std=c++17 -fopenmp -march=native -O3
(zusammen mit einigen Debugging- und Warnoptionen).quelle
Python 2.7. Ergebnis: 1,67039106
Also beschloss ich, es selbst zu versuchen. Nichts Besonderes. Dieses Programm sortiert die Zahlen in umgekehrter Reihenfolge (groß bis klein) und probiert alle Operatoren nacheinander aus. Blitzschnell, aber eine Leistung, die es verdient, abgelöst zu werden.
Hier ist das Programm:
Die Ausgabe für alle Testfälle ist:
quelle