Es ist Zeit zu rechnen


14

Einführung

Dies ist eines meiner Lieblingsrätsel.

Wenn Sie eine Ziffer (sagen Sie 3) und die Häufigkeit der Verwendung dieser Ziffer (sagen Sie 5) gegeben haben, generieren Sie 10 Ausdrücke, die mit nur + zu 1, 2, 3, 4, 5, 6, 7, 8, 9 und 10 führen. -, ×, ÷, ^ und √ (Wurzel) (Klammern dürfen Operationen gruppieren).

Beispielsweise:

(3^3 + 3)/(3 + 3) = (33 - 3)/(3 + 3) = 3 + 3/3 + 3/3 = 5

Beachten Sie, dass für alle obigen Werte fünf 3en und die mathematischen Operationen und das Ergebnis 5 verwendet werden. Sie können auch eine 3 vor √ verwenden, um eine Kubikwurzel zu bezeichnen. Gleiches gilt für die Verwendung von 4 vor √, um eine vierte Wurzel zu bezeichnen.

Beachten Sie auch, dass zwei Dreien verwendet werden können, um 33 zu bilden, oder drei Dreien können verwendet werden, um 333 zu bilden und so weiter.

Herausforderung

  • Sie erhalten zwei Zahlen (beide von 1 bis 5) als Funktionsargument, STDIN oder Befehlszeilenargument.
  • Die erste Zahl gibt an, welche Ziffer verwendet werden soll, und die zweite Zahl gibt an, wie oft diese Ziffer im Ausdruck verwendet werden soll.
  • Ihr Programm sollte ein Array der Größe 10 (oder 10 durch Leerzeichen getrennte Zahlen) ausgeben, wobei jedes Element angibt, ob ein mathematischer Ausdruck (unter Verwendung nur der zulässigen Operatoren), der zur (index + 1)Zahl führt, möglich ist oder nicht, wobei ein wahrer / falscher Wert verwendet wird.

Zum Beispiel, wenn die Eingabe ist

1 3

Dann sollte der Ausgang sein

[1, 1, 1, 0, 0, 0, 0, 0, 0, 1]

weil nur 1, 2, 3 und 10 mit drei Einsen ausgedrückt werden können.

Ergebnis

  • Dies ist ein so dass die minimale Codelänge in Bytes gewinnt.

Bonus

Alles drucken [−50]

Subtrahieren Sie 50 von Ihrer Punktzahl, wenn die Elemente des Ausgangs-Arrays der Gesamtzahl der plausiblen Kombinationen entsprechen, um den (index + 1)Wert anstelle von wahrheitsgemäßen oder falschen Werten zu erhalten.

Zum Beispiel, wenn es nur 3 mögliche Kombinationen von fünf 3s , die bis 5 zur Folge hat , dann 4 ist das Ausgangsarray th sollte Eintrag 3 sein.

Extreme Mathematik [−100]

Subtrahieren Sie 100 von Ihrer Punktzahl, wenn die Elemente des Ausgabearrays mindestens einen der tatsächlichen Ausdrücke enthalten, die zu dem (index + 1)Wert führen.

Wenn zum Beispiel fünf 3s Verwendung des 4 der Ausgangs - Array - ten Eintrag kann entweder (3^3 + 3)/(3 + 3), (33 - 3)/(3 + 3)oder3 + 3/3 + 3/3

Überfordert [−200]

Subtrahieren Sie 200 von Ihrer Punktzahl, wenn die Elemente des Ausgabearrays alle möglichen Kombinationen enthalten (getrennt durch |). Dieser Bonus wird zusätzlich zum Extreme Maths- Bonus hinzugefügt , sodass Sie insgesamt −300 erhalten.

Wenn zum Beispiel fünf 3s Verwendung des 4 der Ausgangsarray - ten Element sollte(3^3 + 3)/(3 + 3)|(33 - 3)/(3 + 3)|3 + 3/3 + 3/3

Hinweis: Beliebige zwei Ausdrücke, um dasselbe Ergebnis zu erzielen, sollten logisch unterschiedlich sein und in beiden einen unterschiedlichen Ansatz haben.

Zum Beispiel, um 5 mit fünf 3en zu bekommen, 3 + 3/3 + 3/3ist das Gleiche wie 3/3 + 3 + 3/3oder 3/3 + 3/3 + 3weil für jeden von ihnen der gleiche Ansatz gewählt wird. (3^3 + 3)/(3 + 3)und (33 - 3)/(3 + 3)unterscheiden sich, da die 30 im Zähler über verschiedene Ansätze erreicht wird.

UPDATE : Nachdem alle Antworten durchgesehen wurden, wurde festgestellt, dass alle Antworten Unvollkommenheiten aufgrund von Randfällen von unär -und √ aufwiesen. Das Fehlen dieser Randfälle wurde daher als in Ordnung angesehen, soweit es um die Vollständigkeit der Antworten geht.

Dies ist eine schwierige, aber sehr interessante Frage.

Viel Spaß beim Golfen!


1
Es tut mir leid, das ist vielleicht dumm, aber wie kommt man mit nur drei 1s auf 10 ?
FryAmTheEggman

3
@FryAmTheEggman 11-1
Optimizer

1
Ah, also ich war dumm: p
FryAmTheEggman

4
Das ist eine sehr vage Regel. Ich kann entscheiden, dass die Quadratwurzel von 1, die Quadratwurzel der Quadratwurzel von 1 usw. alle unterschiedliche Ansätze sind und ich unendlich viele Antworten habe. Unterscheidet sich a + b von b + a? Unterscheidet sich (-a) * (-b) von b * a?
Feersum

2
Mir ist dies bewusst, aber ich kann 4 ^ (4 ^ (4 ^ (4 ^ (4 ^ 4))) in keinem regulären Zahlenformat darstellen - das Speichern von 4 ^ (4 ^ (4 ^ 4)) als Ganzzahl benötigt bereits mehr Bits als es Atome im Universum gibt). Wenn ich also kein Computeralgebrasystem verwende, das in der Lage ist, solche Zahlen zu verarbeiten (sofern überhaupt eines vorhanden ist), muss ich diese als Sonderfälle behandeln. Dies erfordert jedoch mit ziemlicher Sicherheit mehr Charaktere, als ich durch Overkilled gewinne . Daher sind diese Auszeichnungen sinnlos, es sei denn, Sie schließen mehrere Quadratwurzeln aus.
Wrzlprmft

Antworten:


1

Python 3 (unvollkommen), 449 - 300 = 149

Leidet an den gleichen Nachteilen wie die Lösung von KSab : Keine unären Operatoren, die vollständig in Klammern angegeben sind, enthalten äquivalente Ausdrücke wie (1+1)+1und 1+(1+1). Ich habe exakte Duplikate eliminiert, indem ich die Ergebnisse an weitergegeben habe set(). Die Ausgabe könnte etwas hässlicher sein, um ein paar Bytes zu sparen, aber ich mag es so. Ich habe auch n-te Wurzeln nicht gemacht, weil es nicht so aussieht, als würden sie dir bei diesem Problem viel abverlangen.

R=range
E=lambda z:eval(z.replace("^","**"))
def m(d,n):_=R(1,11);s={i:[]for i in _};r=R(1,n);n<2 and s[d].append(str(d));d=str(d);t=[[(d*i,i)for i in r]]+[[]]*n;h=[];[(h.append("("+A+o+B+")"),t[l].append((h[0],a+b))if a+b<n else E(*h)in _ and s[E(*h)].append(h[0]),h.pop())for l in r for j in R(l)for A,a in t[j]for k in R(l)for B,b in t[k]if a+b<=n for o in"+-*/^"if(o=="^"and-~-(0<E(B)<9)or 0==E(B)and"/"==o)-1];[print(i,set(s[i])or'')for i in _]

Die Ausführung dauert einige Minuten, wenn das zweite Argument 5 lautet. Testen Sie durch Aufrufen von m(digit, number):

>>> m(1,3)
1 {'((1*1)^1)', '(1^(1+1))', '((1-1)+1)', '((1/1)/1)', '((1*1)*1)', '((1^1)/1)', '(1*(1*1))', '(1^(1*1))', '(1+(1-1))', '(1^(1^1))', '((1^1)*1)', '(1^(1/1))', '((1/1)*1)', '(1-(1-1))', '(1/(1^1))', '(1/(1*1))', '(1/(1/1))', '(1*(1^1))', '((1+1)-1)', '((1*1)/1)', '((1^1)^1)', '(1*(1/1))', '((1/1)^1)'}
2 {'(1*(1+1))', '((1^1)+1)', '((1+1)/1)', '((1*1)+1)', '((1+1)^1)', '(1+(1*1))', '((1/1)+1)', '(1+(1^1))', '(1+(1/1))', '((1+1)*1)'}
3 {'((1+1)+1)', '(1+(1+1))'}
4 
5 
6 
7 
8 
9 
10 {'(11-1)'}
>>> m(3,3)
1 {'((3/3)^3)'}
2 {'(3-(3/3))', '((3+3)/3)'}
3 {'(3-(3-3))', '((3-3)+3)', '((3/3)*3)', '(3*(3/3))', '(3/(3/3))', '((3+3)-3)', '(3^(3/3))', '(3+(3-3))', '((3*3)/3)'}
4 {'((3/3)+3)', '(3+(3/3))'}
5 
6 {'((3*3)-3)'}
7 
8 
9 {'(3+(3+3))', '((3+3)+3)', '((3^3)/3)'}
10 

4

Python (unvollkommen) 493 474 - 300 = 174

Es gibt eine ganze Reihe von Problemen mit dieser Lösung. Erstens ignoriert sie zu große Exponenten (Exponenten mit mehr als 100). Ich denke eigentlich nicht, dass dies alle Möglichkeiten für Eingaben kleiner oder gleich 5 ausschließt, aber ich bin nicht 100% sicher.

Eine andere Sache ist, dass es keine unären Quadratwurzeln berücksichtigt, da es kompliziert werden würde (jede Lösung mit einem Term gleich 0 oder 1 würde eine unendliche Anzahl von Lösungen hervorbringen). Aus dem gleichen Grund wird auch keine unäre Negation (das '-' Symbol) berücksichtigt, ebenso wie die Tatsache, dass ich nicht sicher bin, ob die Frage danach gestellt wurde.

Ich habe auch darüber nachgedacht, nach welchen Kriterien entschieden werden soll, ob zwei Ausdrücke gleichwertig sind, aber ich fand keinen Weg, sie auf eine Art und Weise zu definieren, die ich als intuitiv empfand. Daher habe ich (zumindest im Moment) so etwas nicht implementiert. Dies bedeutet, dass es einige Ergebnisse ausgibt und Klammern auf ziemlich naive Weise verwendet.

Ich denke, dass dies die längste einzelne Codezeile sein könnte, die ich geschrieben habe, insbesondere bevor sie vollständig ausgenutzt war.

R=range
F=lambda s:lambda a,b:eval(s)
L=lambda D,N:[(int(str(D)*N),str(D)*N)]+[(o(u,v),"(%s%s%s)"%(s,c,t))for p in R(1,N)for u,s in L(D,p)for v,t in L(D,N-p)for c,o in[('+',F('a+b')),('-',F('a-b')),('*',F('a*b')),('/',F("1.*a/b if b else''")),('^',F("''if(a<0 and int(b)!=b)|(a and b<0)|(b>99)else a**b")),('v',F("b**(1./a)if a and(a>=0 or b)and(b>=0 or int(1./a)==1./a)&(1./a<99)else''"))]if o(u,v)!='']
A=L(*input())
for i in R(11):
 for v,s in A:
    if v==i:print i,s[1:-1]

Beispiel: ('v' steht für '√')

2,3

0 2*(2-2)
0 2v(2-2)
0 (2-2)*2
0 (2-2)/2
0 (2-2)^2
1 2^(2-2)
1 2-(2/2)
1 2v(2/2)
1 (2/2)^2
2 2v(2+2)
2 2+(2-2)
2 2-(2-2)
2 2v(2*2)
2 2*(2/2)
2 2/(2/2)
2 2^(2/2)
2 2v(2^2)
2 (2+2)-2
2 (2+2)/2
2 (2-2)+2
2 (2*2)-2
2 (2*2)/2
2 (2/2)*2
2 (2/2)v2
2 (2^2)-2
2 (2^2)/2
3 2+(2/2)
3 (2/2)+2
6 2+(2+2)
6 2+(2*2)
6 2+(2^2)
6 (2+2)+2
6 (2*2)+2
6 (2^2)+2
8 2*(2+2)
8 2*(2*2)
8 2*(2^2)
8 (2+2)*2
8 (2*2)*2
8 (2^2)*2

Ich habe ein paar Dinge gefunden, die Sie tun können, um zu verkürzen L:L=lambda D,N:[(int(str(D)*N),str(D)*N)]+[(o(u,v),"(%s%s%s)"%(s,c,t))for p in R(1,N)for u,s in L(D,p)for v,t in L(D,N-p)for c,o in[('+',F('a+b')),('-',F('a-b')),('*',F('a*b')),('/',F("1.*a/b if b else''")),('^',F("''if(a<0 and int(b)!=b)|(a and b<0)or b>100 else a**b")),('v',F("''if a==0 or(b<0 and int(1./a)!=(1./a))or(b or a<0)or(1./a)>100 else b**(1./a)"))]if o(u,v)!='']
FryAmTheEggman

Es tut mir leid, dieser Kommentar sieht wirklich schlecht aus :( Wie auch immer, um es zu erklären: Beim Vergleich 0mit habe ich versucht, die Aussage zu negieren und dann die Konsequenzen auszutauschen. Ich habe auch ein paar Stellen gefunden, an denen |und &anstelle von orund verwendet werden können and. Beide Tricks könnte verwendet werden, um den letzten Anruf nach F zu verkürzen, aber für diesen Anruf wären einige von Demorgan und mir die Schnabelzeiten
ausgegangen

@FryAmTheEggman Oh, das ist ein guter Fang, ich habe meine Antwort mit dem, was Sie gepostet haben, aktualisiert und wenn ich Zeit habe, werde ich mir die letzte ansehen. Diese Bedingungen, um die Gültigkeit der Eingabe zu überprüfen, wurden etwas schwerwiegender als ich erwartet hatte: /
KSab

+10 für die Brillanz verschachtelter Lambdas und eval- Ich habe eine ganze Weile gebraucht, um deine zweite Zeile herauszufinden! Ich glaube, ich habe dich in der "längsten einzelnen Zeile" geschlagen. ;) Ich bin damit einverstanden, große Exponenten zu ignorieren; Tatsächlich denke ich, dass ein Exponent, der größer als 9 ist, nicht nützlich ist (außer als No-Op, wenn die Basis 1 ist).
DLosc

@ DLosc Nun, das eine Szenario, das Sie haben können, ist so etwas wie 3 = 33 √ (3 ^ 33). Eigentlich merke ich beim Schreiben, dass zwei (wahrscheinlich die einzigen?) Kombinationen, die meine Antwort vermisst, 4 = (4^4) √ (4 ^ (4^4))und der äquivalente Ausdruck mit 5s sind. Zugegebenermaßen scheinen Roots dem Problem nicht viel hinzuzufügen, da die überwiegende Mehrheit von ihnen entweder als No-Ops bei 0 oder 1, No-Ops bei Root 1 oder nur zum Aufheben einer Potenz verwendet wird.
KSab

3

Python 3 - 349 346

r=range
l=lambda s:eval("lambda a"+s)
def T(u,f,X,Y):
    try:return u(f(X,Y))
    except:0
c=l(',x:{x}.union(*[{u(int("1"*a)*x)}|{T(u,f,X,Y)for j in r(1,a)for X in c(j,x)for Y in c(a-j,x)for f in[l(",b:a%sb"%o)for o in{"**"}|set("+-*/")]+[l(",b:a**b**-1")]}for u in[l(":-a")]+[l(":a**.5**%i"%k)for k in r(9)]])')
R=l(",i:[{n+1}<c(i,a)for n in r(10)]")

Hier ist eine eher ungolfed Version:

def R(x,i):
    # Unary Operations
    U = [lambda a:-a] + [eval("lambda a:a**(1/2.**%i)" % j) for j in range(9)]
    # Binary Operations
    F = [eval("lambda a,b:a%sb"%o) for o in ["+","-","*","/","**"]] + [lambda a,b:a**(1./b)]

    def combos(i):
        L = {x}
        for u in U:
            # 3, 33, 333, etc.
            L |= {u(int(str(x)*i))}

            for j in range(1,i):
                for X in combos(j):
                    for Y in combos(i-j):
                        for f in F:
                            # To avoid trouble with division by zero, overflows and similar:
                            try:
                                L |= {u(f(X,Y))}
                            except:
                                pass
        return L

    return [n in combos(i) for n in range(1,11)]

Zum Testen empfehle ich, (9)auf etwas Kleineres zu wechseln , da dies die Anzahl der berücksichtigten multiplen Quadratwurzeln ist, was einen großen Einfluss auf die Leistung hat.

Schließlich habe ich mich gefragt, ob das unäre Minus in manchen Fällen tatsächlich benötigt wird ...


1
Ich denke, Sie haben Recht, wenn es um das unäre "-" geht, das wahrscheinlich nichts hinzufügt (zumindest nicht zur Grundfrage ohne die Boni). Das einzige nicht triviale Szenario, an das ich denken kann, wäre so etwas 1 = 3^3 * 3^(-3), aber selbst wenn ich das bedenke, bezweifle ich, dass es Zahlen gibt, für die dies eine mögliche Lösung ist, wenn es keine anderen gibt.
KSab

1
Sie können 3 Bytes einsparen, indem Sie a**.5**%istattdessen a**(1/2**%i)die mehreren Quadratwurzeln berechnen.
DLosc

@ DLosc: In der Tat, danke.
Wrzlprmft

Sie können sechs Bytes einsparen, indem Sie den Einzug mit vier Leerzeichen auf ein Leerzeichen reduzieren.
Beta Decay

@BetaDecay: Ich benutze niemals vier Leerzeichen (Schauder), ich benutze Tabulatoren. Schau einfach in die Quelle meines Beitrags. Durch Stapelaustausch werden sie nur als vier Leerzeichen gerendert.
Wrzlprmft

2

Mathematica - 246 Zeichen (keine Boni beansprucht)

f[x_,y_]:=x-y
g[x_,y_]:=x/y
h[x_,y_]:=x^(1/y)
j[x_,y_]:=FromDigits@Join[IntegerDigits@x,{y}]
z[{r_,n_,L_}]:=z[{L[[1]][r,n],n,Rest@L}]
z[{r_,n_,{}}]:=r
a[n_,t_]:=Union@Select[z[{n,n,#}]&/@Tuples[{Plus,f,Times,g,Power,h,j},t-1],IntegerQ@#&&0<#<11&]

Erläuterung

Die Funktion jverkettet zwei Ziffern.

Die Funktion zübernimmt ein Ergebnis r, eine Nummer nund eine Liste von FunktionenL , die jeweils mit zwei Argumenten arbeiten. Anschließend wird die Liste der Funktionen unter [r,n]Verwendung der Rekursion sequentiell auf Argumente angewendet , bis die Liste leer ist, woraufhin das Ergebnis zurückgegeben wird.

Funktion animmt eine Nummer nund eine Anzahl von Kopient . Es erstellt alle Tupel der Länge (t-1) aus der Liste der Funktionen, {Plus, f, Times, g, Power, h, j}sendet jedes Tupel durch die Funktion z und gibt dann eine Liste aller Nummern 1 bis 10 zurück, die erstellt wurden.

Beispielausführung a[2,3] Rückkehr zur{1, 2, 3, 6, 8} .

Einschränkungen

Da die Liste der Funktionen nacheinander angewendet wird und jedes Mal eine Kopie der Nummer verbraucht, können einige Kombinationen fehlen. Wenn beispielsweise vier Zweien verwendet werden, wird 22/22 = 1 verpasst, da die Liste der Funktionen nicht in der richtigen Reihenfolge ausgewertet werden kann. Natürlich deckt 2/2 * 2/2 = 1 diesen Fall ab.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.