Generieren Sie eine gültige Gleichung mit benutzerdefinierten Zahlen

10

Dies basiert auf einem Spiel, das einer meiner Mathematiklehrer in der Mittelschule gespielt hat. Er schrieb 5 zufällige einstellige Zahlen an die Tafel und dann eine zufällige zweistellige Zahl. Wir würden versuchen, eine Gleichung zu erstellen, die alle 5 einstelligen Zahlen verwendet, um die zweistellige Zahl zu erhalten. Hier einige Beispiele mit Lösungen, um dies besser zu erklären:

Input:           Solution:
7 5 4 8 4 34     5*8-7+4/4 = 34
3 1 5 7 6 54     (7+3)*6-5-1 = 54
3 9 2 1 6 87     9*(2+1)*3+6 = 87
2 1 6 9 7 16     (9-7+6*1)*2 = 16
2 4 5 8 6 96     8*(5+6)+2*4 = 96
3 8 4 5 4 49     8*(4+4)-3*5 = 49

Diese Herausforderung besteht darin, ein Programm zu schreiben, das solche Gleichungen für eine bestimmte Eingabe erzeugen kann. Die Eingabe kann entweder über die Befehlszeile oder über eine Eingabeaufforderung erfolgen. Die 5 einstelligen Zahlen werden immer zuerst eingegeben (in keiner bestimmten Reihenfolge), gefolgt von der zweistelligen Zahl. Das Programm druckt dann eine Lösungsgleichung aus, die es findet. Sie müssen nicht mit Situationen umgehen, in denen es keine Lösung gibt. Die Funktion muss in der Lage sein, die folgenden Operationen in der Gleichung zu verwenden: Addition, Subtraktion, Multiplikation und Division. Wenn Sie zusätzliche grundlegende Operationen zulassen möchten, ist dies in Ordnung, solange diese im Geiste der Herausforderung bleiben (Negation, Potenzierung und Modul wären nette Ergänzungen). Die Reihenfolge der Operationen folgt den mathematischen Standardregeln, sodass für die Gruppierung Klammern erforderlich sind.

Programme werden basierend auf der Codelänge (einschließlich des erforderlichen Leerzeichens) bewertet. Hinweis: Die Division muss exakt sein, darf nicht auf die nächste Ganzzahl gerundet oder abgeschnitten sein.

Sir_Lagsalot
quelle
Das ist eine sehr ähnliche Aufgabe, aber ich denke, der zusätzliche Begriff und keine Einschränkung der Gruppierung von Ausdrücken sollte das Problem so erweitern, dass es interessant anders ist. Darüber hinaus ist dies eine Golfherausforderung anstelle einer Codeherausforderung, die unterschiedliche Lösungen erfordert.
Sir_Lagsalot
Was ist mit Verkettung? Beispiel: Wenn 7 5 4 8 4 34 angegeben wird, ist die Ausgabe 7 + 54/8 * 4 zulässig.
Patrick Roberts

Antworten:

7

Python 2.7 (284), Python 3.x (253)

from __future__ import division #(Remove for Python 3.x)
from itertools import *
a=raw_input().split()
for i in permutations(a[:-1],5):
 for j in product('+-*/',repeat=5):
  for k,l in combinations(range(1,12,2),2):
   d=''.join(sum(zip(i,j),()))[:-1];d='('+d[:l]+')'+d[l:]
   if eval(d)==int(a[-1]):print d;b

Es gibt einen Fehler (Aufruf einer unbekannten Funktion b) bei der Lösung.

Im Grunde ist es eine gigantische rohe Kraft. Es nimmt die Eingabe auf, teilt sie durch Leerzeichen ( 1 2 -> [1,2]) und durchläuft diese Liste. Bei jeder Permutation werden alle möglichen Zeichenfolgen der Länge 5 mit den Zeichen durchlaufen +-*/. Bei jeder dieser Iterationen werden die Kombinationen der Länge 2 der Liste generiert [1,3,5,7,9,11], die Permutation und die Zeichenfolge miteinander verwoben ( 12345 *-/+- -> 1*2-3/4+5-) und in Klammern gesetzt. Schließlich wird es ausgewertet, und wenn die Antwort und die Gleichung wahr sind, wird die Gleichung gedruckt und gestoppt.

Dies ist ungefähr ineffizient, O(n!/(n-5)!)=O(n^5)läuft aber in einer angemessenen Zeit für die Testeingaben.

beary605
quelle
1
Die Ganzzahlmathematik kann bei Verwendung der Division zu einer falschen Ausgabe führen. Zum Beispiel ergibt die Eingabe "3 6 8 7 1 29" "(3 + 8/6) * 7 + 1", was 31 1/3 entspricht, nicht 29. Ich werde die Beschreibung aktualisieren, um dies explizit zu machen.
Sir_Lagsalot
Es gibt (3/6)*8*7+1für mich.
Beary605
Ok, ich werde das als Problem mit dem von mir verwendeten Dolmetscher bezeichnen.
Sir_Lagsalot
3

Scala 368:

Die 2. g = -Linie ist einfacher zu testen, die erste ist flexibel, um Befehlsargumente zu verwenden, und beide sind gleich lang, daher zähle ich nur von der zweiten - entferne sie, um Argumente zu übergeben:

val g=(args.map(_.toDouble))
val g=Array(3,9,2, 1, 6, 87)
val k="+*/-DQ"
val i=(0 to 5)
val f:Seq[(Double,Double)=>Double]=Seq(_+_,_*_,_/_,_-_,(a,b)=>b-a,(a,b)=>b/a)
val h=g.init.permutations;
for(j<-h;o<-i;p<-i;q<-i;r<-i;z=try{f(r)(f(q)(f(p)(f(o)(j(0),j(1)),j(2)),j(3)),j(4))}catch{case _ => 0}
if(z==g(5)))printf("(((%d%c%d)%c%d)%c%d)%c%d=%d\n",j(0),k(o),j(1),k(p),j(2),k(q),j(3),k(r),j(4),g(5))

Beispielausgabe (möglicherweise haben Sie gerade eine Frage - nur einen Moment):

(((5+7)/1)+6)*3=54
(((5-7)D1)*6)*3=54
(((5D7)+1)*6)*3=54
(((5+7)+6)Q1)Q3=54

Was ist mit dieser 5D7-Sache? D1? Ist es hex? Es gibt Q1, Q3 - was ist das?

Sir_Lagsalot erlaubte neue grundlegende Operationen im Geiste der Herausforderung, und ja, dies sind grundlegende Operationen, Delta und Quotient.

Sie unterscheiden sich von a / b und ab darin, dass aQb b / a und aDb ba bedeutet. Nennen wir es die ukrainische Notation.

Damit

(((5-7)D1)*6)*3=54

meint

((1-(5-7))*6)*3=54
 (1-(-2))*6*3
   3*6*3 = 18*3=54

Zur interessanteren Frage nach dem Wie und Warum: Am Anfang war ich verrückt nach den Möglichkeiten, die Klammern zu setzen, und ob (a + b) -c = a + bc = (a + bc) = ((a + b) ) -c) = (b + a) -c und so weiter. Sie können über diese Frage wütend werden, aber wenn Sie die möglichen Klammerkombinationen aufschreiben, werfen Sie manchmal das Arbeitsblatt weg und stellen sich der Tatsache: Sie führen immer 4 Operationen zwischen 5 Werten aus und beginnen immer mit einer davon. Wenn das Muster immer ist (((_x_)x_)x_)x_ ?= _(x ist einer der 4 Operatoren) und die entgegengesetzte Richtung (xb) und (bxa) zulässt, haben Sie jede Möglichkeit angesprochen.

Für a + b und a * b brauchen wir keine entgegengesetzte Richtung, sie sind kommutativ. Also habe ich den D- und Q-Operator erfunden, der nur die Richtung ändert. Ich habe jetzt 2 Operatoren mehr, muss aber nicht die Richtung wechseln. Nun - es wird in der Funktionssequenz gemacht:

 (a,b)=>b-a,(a,b)=>b/a

Mein Verständnis nimmt die Werte aus dem Array g und verteilt sie auf a bis e. Dann wähle ich 4 Indizes aus, um die Funktion und später das (nur nach Index) zugeordnete Operatorsymbol auszuwählen. Ich muss Div / 0-Fehler abfangen, da Subtraktion zu Nullen führen kann, während die Sample-Eingabedaten keine 0 enthalten.

Benutzer unbekannt
quelle
Die Operatoren Delta und Quotient sind in Ordnung. Wenn Sie jedoch Golf spielen möchten, müssen Sie der Ausgabe Klammern hinzufügen.
Sir_Lagsalot
Die Ausgabe druckt jetzt Klammern.
Benutzer unbekannt