Ihre Aufgabe ist es, Dezimalstellen in die Summe der Quadratwurzeln von ganzen Zahlen umzuwandeln. Das Ergebnis muss eine Genauigkeit von mindestens 6 signifikanten Dezimalstellen haben.
Eingabe :
Eine Zahl, die die Anzahl der Quadratwurzeln angibt, und eine Dezimalzahl, die die ungefähre Anzahl angibt.
Beispiel Eingabe:
2 3.414213562373095
Ausgabe : Ganzzahlen, die durch Leerzeichen getrennt sind und bei Quadratwurzelbildung und Addition ungefähr die ursprüngliche Dezimalstelle darstellen, mit einer Genauigkeit von mindestens 6 signifikanten Dezimalstellen.
Nullen sind in der Lösung nicht zulässig.
Wenn es mehrere Lösungen gibt, müssen Sie nur eine drucken.
Beispielausgabe (in beliebiger Reihenfolge):
4 2
Das funktioniert weil Math.sqrt(4) + Math.sqrt(2) == 3.414213562373095
.
Das ist Code Golf. Der kürzeste Code (mit optionalem Bonus) gewinnt!
Es wird immer eine Lösung geben, aber -10, wenn Ihr Programm "Nein" ausgibt, wenn es keine Lösung mit ganzen Zahlen gibt. Außerdem -10, wenn Ihr Programm alle Lösungen (durch Zeilenumbrüche oder Semikolons oder was auch immer getrennt) anstelle von nur einer ausgibt.
Testfälle:
3 7.923668178593959 --> 6 7 8
2 2.8284271247461903 --> 2 2
5 5.0 --> 1 1 1 1 1
5 13.0 --> 4 4 9 9 9 --> 81 1 1 1 1 --> 36 9 4 1 1 etc. [print any, but print all for the "all solutions bonus"]
Und ja, Ihr Programm muss in endlicher Zeit mit endlichem Speicher auf jedem vernünftigen Computer beendet werden. Es kann nicht nur "theoretisch" funktionieren, man muss es auch tatsächlich testen können.
quelle
6 7 8
zweiten Bonus drucken ?Antworten:
Python 3, 90 - 10 = 80
(Mega danke an @xnor für Tipps, insbesondere die Umstrukturierung der for-Schleife in eine Weile)
Ein einfacher rekursiver Versuch. Es beginnt mit der Zielzahl und subtrahiert kontinuierlich Quadratwurzeln, bis es 0 oder weniger erreicht. Die Funktion
S
kann wieS(2,3.414213562373095)
folgt aufgerufen werden (das zweite Argument wird als positiv angenommen).Das Programm druckt nicht nur alle Lösungen aus, es druckt auch alle Permutationen von Lösungen aus (etwas irrelevant, ich weiß). Hier ist die Ausgabe für den letzten Fall: Pastebin .
Eine leichte Änderung ergibt eine 98 - 10 = 88- Lösung, die keine Permutationen druckt, wodurch sie effizienter wird:
Und nur zum Spaß, diese 99 - 10 = 89 ist ungefähr so effizient wie es nur geht (im Gegensatz zu den anderen sprengt es nicht den Stapel auf
S(1,1000)
:Beachten Sie, dass, obwohl wir ein veränderbares Standardargument haben, dies niemals ein Problem verursacht, wenn wir die Funktion erneut ausführen, da
n+[i]
eine neue Liste erstellt wird.Beweis der Richtigkeit
Um in eine Endlosschleife zu gelangen, müssen wir einen Punkt erreichen, an dem x <0 und 0.1 + x 2 > 1 . Dies wird durch x <-0.948 ... erfüllt .
Beachten Sie jedoch, dass wir mit positivem x beginnen und x immer kleiner wird. Um also x <-0,948 zu treffen, müssen wir x '- i 0,5 <-0,948 ... für einige x'> -0,948 haben. . vor x und positive ganze Zahl i . Damit die while-Schleife ausgeführt werden kann, muss auch 0.1 + x ' 2 > i vorliegen .
Beim Umordnen erhalten wir x ' 2 + 1.897x' + 0.948 <i <0.1 + x ' 2 , wobei die äußeren Teile bedeuten , dass x' <-0.447 . Aber wenn -0,948 <x '<-0,447 , dann kann keine positive ganze Zahl i in die Lücke in der obigen Ungleichung passen.
Daher werden wir niemals in eine Endlosschleife geraten.
quelle
abs
mitx*x<1e-12
.while
Schleife zu ersetzen funktioniert dasfor
:while.1+x*x>i:S(x-i**.5,n+[i]);i+=1
, initialisiert hat ,i=1
in den Funktionsparametern. Damit soll vermieden werden, dass inint
s konvertiert werden muss . Das.1
ist, um Ungenauigkeiten zu behandeln; Ich denke, es ist sicher gegen Endlosschleifen.N
jetzt einem Funktionsargument ist es kürzer, mit zu rekursierenN-1
und zu prüfen, wannN==0
und nichtlen(n)==N
..1
sicher ist; Wenn Sie möchten, kann ich Sie über ein Argument unterhalten.ECLiPSe-Prolog - 118 (138-20)
Ich habe die folgende Implementierung von Prolog verwendet: http://eclipseclp.org/
Dies ist ein sehr naiver, exponentieller Ansatz. Das Auflisten aller möglichen Lösungen nimmt Zeit in Anspruch, um alle Kombinationen abzudecken ( einige Bearbeiten : Der Bereich der besuchten Ganzzahlen nimmt jetzt mit jedem Schritt ab, wodurch viele unnötige Kombinationen entfernt werden).
Hier folgt ein Protokoll einer Testsitzung. Standardmäßig versucht die Umgebung, alle möglichen Lösungen zu finden (-10) und gibt "Nein" aus, wenn dies nicht der Fall ist (-10).
Wie Sp3000 im Kommentar richtig vermerkt hat, wird bei Erfolg auch "Ja" ausgegeben. Das bedeutet sicherlich, dass ich 10 weitere Punkte entfernen kann ;-)
(Bearbeiten) In Bezug auf die Leistung ist es zumindest im Vergleich zu anderen recht gut (siehe zum Beispiel diesen Kommentar von FryAmTheEggman ). Fügen Sie zunächst das folgende Prädikat hinzu, wenn Sie alle Ergebnisse drucken möchten:
Unter http://pastebin.com/ugjfEHpw finden Sie den Fall (5,13.0), der in 0,24 Sekunden abgeschlossen ist und 495 Lösungen enthält (aber möglicherweise fehlen mir einige Lösungen, die ich nicht kenne).
quelle
Erlang,
305-10302-10Diese Funktion gibt die Zeichenfolge "Nein" oder eine Zeichenfolge mit durch Leerzeichen getrennten Werten zurück. Es verarbeitet (ineffizient) alle möglichen Werte, um sie in eine große Ganzzahl umzuwandeln, und beginnt mit höheren Werten. 0 sind in der Lösung nicht zulässig, und 0 steht für alle Einsen. Der Fehler ist quadriert.
Beispiel:
Bitte haben Sie etwas Geduld,
f(5,13.0)
da der Funktionssuchbereich 13 ^ 10 ist. Es kann mit 2 zusätzlichen Bytes schneller gemacht werden.quelle
Python
32:173159 - 10 = 149Erläuterung: Jede Lösung hat die Form x_1 x_2 ... x_n mit 1 <= x_1 <= x ^ 2, wobei x die Zielsumme ist. Daher können wir jede Lösung als ganze Zahl in der Basis x ^ 2 kodieren. Die while-Schleife durchläuft alle (x ^ 2) ^ n Möglichkeiten. Dann konvertiere ich die ganze Zahl zurück und teste die Summe. Ziemlich einfach.
Es werden alle Lösungen gefunden, aber der letzte Testfall dauert viel zu lange.
quelle
JavaScript (ES6) 162 (172 - 10)
173Bearbeiten Ein bisschen kürzer, ein bisschen langsamer.
Als eine Funktion mit 2 Parametern, Ausgabe auf Javascript-Konsole. Dies druckt alle Lösungen ohne Wiederholungen (Lösungstupel werden bereits sortiert generiert).
Es ging mir mehr um das Timing als um die Anzahl der Zeichen, sodass es in einer Browserkonsole innerhalb des Standard-JavaScript-Zeitlimits problemlos getestet werden kann.
(Update Februar 2016) Aktuelle Zeit für den letzten Testfall: ca. 1
150 Sek. Speicherbedarf: vernachlässigbar.ES 5 Version Beliebiger Browser
Test Snippet sollte auf jedem aktuellen Browser ausgeführt werden
( Bearbeiten ) Unten sehen Sie das Ergebnis auf meinem PC, als ich diese Antwort vor 15 Monaten gepostet habe. Ich habe es heute versucht und es ist 100-mal schneller auf demselben PC, nur mit einer 64-Bit-Alpha-Version von Firefox (und Chrome hinkt deutlich hinterher)! - aktuelle Zeit mit Firefox 40 Alpha 64 Bit: ~ 2 Sek., Chrome 48: ~ 29 Sek
Ausgabe (auf meinem PC - letzte Nummer ist Laufzeit in Millisekunden)
quelle
Mathematica - 76 - 20 = 56
Beispiele
quelle
No
? Außerdem ist die Ausgabe nicht durch Leerzeichen getrennt. Kannst du auch nichtTr@
anstelle von verwendenPlus@@
? Und Sie könnten in der Lage sein , einige Zeichen zu speichern , indem SieSelect
aufCases
, die Funktion am Ende zu einem Muster, und machtef
eine unbenannte reine Funktion.Haskell,
8780 - 10 = 70Dies ist ein rekursiver Algorithmus, der dem Python 3-Programm von @ Sp3000 ähnelt. Es besteht aus einer Infix-Funktion
#
, die eine Liste aller Permutationen aller Lösungen zurückgibt.Mit einer Punktzahl von
102 9992 - 10 = 82 können wir jede Lösung nur einmal ausdrucken, sortiert:quelle
Pyth
55 5447-20 = 27Probieren Sie es online aus.
Schamlos leiht sich von xnor Kommentar ;)
Dies führt auf jedem vernünftigen Computer sogar für einen Wert wie zu wenig Arbeitsspeicher
5,5.0
. Definiert eine Funktion,g
die wie folgt aufgerufen werden kanng 3 7.923668178593959
.Dieses Python 3-Programm verwendet im Wesentlichen den gleichen Algorithmus (führt am Ende nur nicht den "Nein"
print(K if K else "No")
-Druck aus, was durch Zuweisen einer Variablen zu allen Ergebnissen und anschließendes Schreiben erfolgen kann ), sondern verwendet einen Generator. Es wird kein Speicherfehler angezeigt (es dauert immer noch sehr lange, aber ich habe den Ausdruck so eingestellt, dass die Werte gefunden werden):Dies ergab genau die gleichen Ergebnisse wie bei @ Sp3000. Es dauerte auch einige Tage, bis ich fertig war (ich hatte keine Zeit dafür, aber ungefähr 72 Stunden).
quelle
Python 3 -
157174169 - 10 = 159Edit1: Das Ausgabeformat wurde in durch Leerzeichen getrennte Ganzzahlen anstatt durch Kommas getrennt geändert. Vielen Dank für den Tipp, die Klammern um (n, x) zu entfernen.
Edit2: Danke für die Golftipps! Ich kann weitere 9 Zeichen abschneiden, wenn ich nur einen == Test verwende, anstatt die ungefähre Gleichheit innerhalb von 1e-6 zu testen, aber das würde ungefähre Lösungen, falls solche existieren, ungültig machen.
Verwendet itertools, um alle möglichen Ganzzahlkombinationen zu generieren, hoffentlich effizient :)
Ich habe keine Möglichkeit gefunden, effizient "Nein" zu drucken. Es sind immer mehr als 10 zusätzliche Zeichen erforderlich.
quelle
n,x
.SyntaxError
s zu bekommen, wenn ich dieeval
Linie versuchen ...from itertools import*
Speichert 1, entfernt den Platzz**.5for
spart 1 und entfernt den[]
In-sum(z**.5for z in c)
Speicher 2 und entfernt den()
In-if(...)
Speicher 1.n,x=input()
kompakter?Scala (397 Bytes - 10)
Wenn es keine Permutationen gibt, druckt dieses Programm nichts.
quelle