|
|
|
|
Schon, aber du dann habe ich das Maximum, ich will die Liste aber sortiert haben. Außerdem dachte ich, ich kann das durch kluges Iterieren lösen, also in N^2.
|
|
|
|
|
|
|
Du weißt das Maximum der Zahlen, also kannst du Radixsort oder einfach Countingsort verwenden, um die Zahlen in linearer Zeit zu sortieren.
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von Redh3ad am 06.06.2014 18:22]
|
|
|
|
|
|
1. sind die Zahlen von 0 bis 99 nicht dreistellig.
2. ist es egal, wie viele O(N²)-Operationen du aneinanderreihst - du bleibst in O(N²). Sprich: O(c * N²) = O(N²). Außer natürlich, die Anzahl hängt von einer Eingabegröße ab. Dann hast du selbstverständlich O(N³).
|
|
|
|
|
|
|
Jetzt kommen wieder alle mit ihrer Aufwandstheorie. Es geht mir darum, ob es ein Iterationsverfahren gibt, wobei die automatisch sortiert sind. Wenn nicht, kriege ich es schon hin, die zu sortieren.
Hintergrund ist der, dass ich nach der größten Zahl in allen Produkten von dreistelligen Zahlen suchen will, die bestimmte EIgenschaften erfüllt und dann die Loops abbrechen möchte, damit ich gar nicht erst weit iterieren muss. Wenn ich erst alle Produkte berechnen muss, dann sortieren und dann wieder von oben durchgehe, ist das deutlich weniger elegant, auch wenn der Aufwand in O Notation der gleiche ist.
/e: Die gesuchte Zahl ist irgendwo bei 9xx * 9xx, deshalb fange ich auch oben an.
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von Oli am 06.06.2014 18:39]
|
|
|
|
|
|
Hast du was anderes in diesem Thread erwartet?
|
|
|
|
|
|
|
| Zitat von Oli
Jetzt kommen wieder alle mit ihrer Aufwandstheorie.
| |
Als hätte jemand danach gefragt, ne?
|
|
|
|
|
|
|
| Zitat von Rufus
| Zitat von Oli
Jetzt kommen wieder alle mit ihrer Aufwandstheorie.
| |
Als hätte jemand danach gefragt, ne?
| |
Wo?
|
|
|
|
|
|
|
Tss, er editiert!
| Zitat von Oli
Jemand ne Idee, wie ich das in O(N) (mit N = 999^2) hinkriege?
| |
|
|
|
|
|
|
|
Werden revisions gespeichert, hast du nen guten Browser Cache oder einfach nur ein gut funktionierendes Kurzzeitgedächtnis?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Zitat von Oli
| Zitat von Rufus
| Zitat von Oli
Jetzt kommen wieder alle mit ihrer Aufwandstheorie.
| | Als hätte jemand danach gefragt, ne?
| | Wo?
| | Du kannst Fragen stellen. Wenn du in diesem Thread eine Antwort bekommst, dann hast du natürlich auch danach gefragt! Als würde hier jemand unnötig umfangreiche oder am Ziel vorbeischießende Antworten geben ...
Warum willst du überhaupt eine (un-)sortierte Liste? Eigentlich brauchst du doch nur das Maximum festzuhalten, um es gegen neu gefundene Palindromzahlen zu vergleichen.
|
|
|
|
|
|
|
Rats hilft mir bestimmt.
/e: Natürlich war die Frage falsch formuliert und natürlich sind eure Antworten gut und gerechtfertigt. Aber sowas zuzugeben liegt nich in meiner Natur.
Ich denke nachher über deine Lösung nach.
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von Oli am 06.06.2014 18:54]
|
|
|
|
|
|
Rats hilft dir, indem er 5 Seiten lang über die O-Notation referiert, dabei nach NP=P abdriftet und dir als Sahnehäubchen einen 2-seitigen Vermerkt über Magnetismus und das Paarungsverhalten bolivianischer Neumondyakzuchtbullen obendrauf gibt.
|
|
|
|
|
|
|
Und alles frisch von Wikipedia oder aus den guten Erstsemester-Scripten kopiert!
|
|
|
|
|
|
|
| Zitat von cms
Warum willst du überhaupt eine (un-)sortierte Liste? Eigentlich brauchst du doch nur das Maximum festzuhalten, um es gegen neu gefundene Palindromzahlen zu vergleichen.
| |
Stimmt, eine Sequence ist deutlich sinnvoller, dank lazy evaluation.
Spoiler - markieren, um zu lesen:
Zumindest in anständigen Programmiersprachen.
|
|
|
|
|
|
|
| Zitat von cms
Warum willst du überhaupt eine (un-)sortierte Liste? Eigentlich brauchst du doch nur das Maximum festzuhalten, um es gegen neu gefundene Palindromzahlen zu vergleichen.
| |
Das ist mein aktueller Ansatz, bedeutet aber leider (wiederum), dass ich alle N^2 Möglichkeiten durchlaufen muss. Wie gesagt, könnte ich beim ersten Match abbrechen, das wäre schön. Motiviert ist meine Frage übrigens dadurch, dass Vanilla Python 3 für die Aufgabe eine spürbare Zeit braucht (so eine gute halbe Sekunde), und mich das irgendwie stört.
|
|
|
|
|
|
|
|
Code: |
val=999
def func():
for i in range(0,val):
for j in range(0,i):
x=val-i+j+1
y=val-j
if(x<=y):
z=x*y
if(str(z) == str(z)[::-1]):
print(str(x)+"*"+str(y))
return z
print(func())
|
|
|
Code: |
[reno@jupiter:~] $ time python euler4.py
913*993
906609
real 0m0.044s
user 0m0.040s
sys 0m0.000s
|
|
Ist jetzt hingerotzt und sicher hässlich, aber ich mach auch selten python.
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von Anarchy am 07.06.2014 0:26]
|
|
|
|
|
|
Ich würde z direkt umwandeln, bringt zusätzliche Perfomance:
|
Code: |
from timeit import Timer
def func1(val=999):
for i in range(0, val):
for j in range(0, i):
x = val - i + j + 1
y = val - j
if x <= y:
z = x*y
if(str(z)== str(z)[::-1]):
#print(str(x)+"*"+str(y))
return z
def func2(val=999):
for i in range(0, val):
for j in range(0, i):
x = val - i + j + 1
y = val - j
if x <= y:
z = str(x*y)
if z == z[::-1]:
#print(str(x)+"*"+str(y))
return z
print("func1", Timer(func1).timeit(number=1000))
print("func2", Timer(func2).timeit(number=1000))
|
|
~>
|
Code: |
func1 4.125017361002392
func2 3.4162949439996737 |
|
|
|
|
|
|
|
|
Hier (ergooglelt durch Lösungen höherstelliger Zahlen ) noch eine andere Lösung.
Es ist hübscher und schneller bis zur 5. Stelle...
|
[Dieser Beitrag wurde 3 mal editiert; zum letzten Mal von Anarchy am 07.06.2014 1:19]
|
|
|
|
|
|
|
Code: |
def is_palindromic(n): return str(n)==str(n)[::-1]
pmax = 0
for i in range(999, 100, -2):
for j in range(i, 900, -2):
p = i*j
if p < pmax: break
if is_palindromic(p): x, y, pmax = i, j, p
|
|
Ich bin mir ziemlich sicher, dass ihr beide das gleiche tut. Er schließt lediglich gerade Zahlen aus, weil die multiplikativ keine Palindrome bilden (beweist er nicht, mir fällt spontan kein Ansatz ein, ich bin kein Mathematiker, aber mir fällt auch kein Palindrom ein, was aus zwei geraden Zahlen zusammengemalt wird.). Dann suche auf einer schrägen (wenn man sich i×j als X-Y-Diagramm denkt) nach unten, größtes Palindrom behalten.
Sein is_palindromic wieder ineffizient mit dem doppelten str(n), sowas optimiert Python nicht, weil Python überhaupt nicht optimiert. Außerdem hat er da ja noch nen Funktionsaufruf drin, der wird ebenfalls was kosten.
Du suchst ja andersrum, vielleicht liegts einfach schon daran.
|
|
|
|
|
|
|
Danke für die Erklärung!
|
|
|
|
|
|
|
Danke anarchy, so stellte ich mir das vor.
Über Python strings habe ich das auch gelöst, ich muss mir nochmal überlegen, wie man am effizientesten numerische palindrome feststellt.
|
|
|
|
|
|
|
Da das ne Eigenschaft der Darstellung bezgl. einer Basis ist, wird man m.E. nicht umhin kommen die Zahl explizit in das System umzuwandeln. Ist ja keine Eigenschaft der Zahl...
|
|
|
|
|
|
|
Unterschätze nie die Mathematik. Da lassen sich bestimmt irgendwelche Theoreme für finden.
|
|
|
|
|
|
|
Mit etwas geschickten rumfummeln an der Zahl sollte sich die Zahl "umdrehen" lassen. Das geschickte rumfummeln wird aber nicht ohne mehrere teure Operationen gehen.
Die Wahrscheinlichkeit das der Stringvergleich effizienter ist ist also recht hoch.
[e]Ah, pff. Warum selbst machen. http://stackoverflow.com/questions/199184/how-do-i-check-if-a-number-is-a-palindrome
[e2]
|
Code: |
def is_palindromic(n): return n==n[::-1]
pmax = 0
for i in range(999, 100, -2):
for j in range(i, 900, -2):
p = i*j
if p < pmax: break
if is_palindromic(str(p)): x, y, pmax = i, j, p
|
|
Und noch eine Strinconversion gespart \o/
|
[Dieser Beitrag wurde 2 mal editiert; zum letzten Mal von Ares am 07.06.2014 14:45]
|
|
|
|
|
|
Andererseits benutzt str() den Heap, und das ist auch sehr langsam.
Beweis:
Spoiler - markieren, um zu lesen:
str(x) ruft PyObject_Str(x) auf, was für normale Objekte, die kein String sind, tp_str aufruft, was für int long_to_decimal_string ist, was long_to_decimal_string_interl aufruft, was in Zeile 1618 von Objects/longobject.c _PyLong_New sowie in Zeile 1668 mit PyUnicode_New einen neuen String erzeugt.
Ich finde die Komplexität dieser Funktion sehr bemerkenswert. Primär ist sie so kompliziert, weil ints in Python beliebig lang sein können.
|
Code: |
/* Convert an integer to a base 10 string. Returns a new non-shared
string. (Return value is non-shared so that callers can modify the
returned value if necessary.) */
static int
long_to_decimal_string_internal(PyObject *aa,
PyObject **p_output,
_PyUnicodeWriter *writer)
{
PyLongObject *scratch, *a;
PyObject *str;
Py_ssize_t size, strlen, size_a, i, j;
digit *pout, *pin, rem, tenpow;
int negative;
enum PyUnicode_Kind kind;
a = (PyLongObject *)aa;
if (a == NULL || !PyLong_Check(a)) {
PyErr_BadInternalCall();
return -1;
}
size_a = Py_ABS(Py_SIZE(a));
negative = Py_SIZE(a) < 0;
/* quick and dirty upper bound for the number of digits
required to express a in base _PyLong_DECIMAL_BASE:
#digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE))
But log2(a) < size_a * PyLong_SHIFT, and
log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT
> 3 * _PyLong_DECIMAL_SHIFT
*/
if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) {
PyErr_SetString(PyExc_OverflowError,
"int too large to format");
return -1;
}
/* the expression size_a * PyLong_SHIFT is now safe from overflow */
size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT);
scratch = _PyLong_New(size);
if (scratch == NULL)
return -1;
/* convert array of base _PyLong_BASE digits in pin to an array of
base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP,
Volume 2 (3rd edn), section 4.4, Method 1b). */
pin = a->ob_digit;
pout = scratch->ob_digit;
size = 0;
for (i = size_a; --i >= 0; ) {
digit hi = pin[i];
for (j = 0; j < size; j++) {
twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi;
hi = (digit)(z / _PyLong_DECIMAL_BASE);
pout[j] = (digit)(z - (twodigits)hi *
_PyLong_DECIMAL_BASE);
}
while (hi) {
pout[size++] = hi % _PyLong_DECIMAL_BASE;
hi /= _PyLong_DECIMAL_BASE;
}
/* check for keyboard interrupt */
SIGCHECK({
Py_DECREF(scratch);
return -1;
});
}
/* pout should have at least one digit, so that the case when a = 0
works correctly */
if (size == 0)
pout[size++] = 0;
/* calculate exact length of output string, and allocate */
strlen = negative + 1 + (size - 1) * _PyLong_DECIMAL_SHIFT;
tenpow = 10;
rem = pout[size-1];
while (rem >= tenpow) {
tenpow *= 10;
strlen++;
}
if (writer) {
if (_PyUnicodeWriter_Prepare(writer, strlen, '9') == -1) {
Py_DECREF(scratch);
return -1;
}
kind = writer->kind;
str = NULL;
}
else {
str = PyUnicode_New(strlen, '9');
if (str == NULL) {
Py_DECREF(scratch);
return -1;
}
kind = PyUnicode_KIND(str);
}
#define WRITE_DIGITS(TYPE) \
do { \
if (writer) \
p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + strlen; \
else \
p = (TYPE*)PyUnicode_DATA(str) + strlen; \
\
/* pout[0] through pout[size-2] contribute exactly \
_PyLong_DECIMAL_SHIFT digits each */ \
for (i=0; i < size - 1; i++) { \
rem = pout[i]; \
for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) { \
*--p = '0' + rem % 10; \
rem /= 10; \
} \
} \
/* pout[size-1]: always produce at least one decimal digit */ \
rem = pout[i]; \
do { \
*--p = '0' + rem % 10; \
rem /= 10; \
} while (rem != 0); \
\
/* and sign */ \
if (negative) \
*--p = '-'; \
\
/* check we've counted correctly */ \
if (writer) \
assert(p == ((TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos)); \
else \
assert(p == (TYPE*)PyUnicode_DATA(str)); \
} while (0)
/* fill the string right-to-left */
if (kind == PyUnicode_1BYTE_KIND) {
Py_UCS1 *p;
WRITE_DIGITS(Py_UCS1);
}
else if (kind == PyUnicode_2BYTE_KIND) {
Py_UCS2 *p;
WRITE_DIGITS(Py_UCS2);
}
else {
Py_UCS4 *p;
assert (kind == PyUnicode_4BYTE_KIND);
WRITE_DIGITS(Py_UCS4);
}
#undef WRITE_DIGITS
Py_DECREF(scratch);
if (writer) {
writer->pos += strlen;
}
else {
assert(_PyUnicode_CheckConsistency(str, 1));
*p_output = (PyObject *)str;
}
return 0;
}
static PyObject *
long_to_decimal_string(PyObject *aa)
{
PyObject *v;
if (long_to_decimal_string_internal(aa, &v, NULL) == -1)
return NULL;
return v;
}
|
|
| Zitat von Ares
Und noch eine Strinconversion gespart \o/
| |
Die hatten wir aber schon weiter oben rausgekürzt
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von csde_rats am 07.06.2014 15:02]
|
|
|
|
|
|
In den Quellen meiner derzeitigen SRT-Lektüre gerade das (laut Buch (Gourgoulhon)) erste Lehrbuch zur ART gefunden. Online, frei.
Max (von) Laue - Das Relativitätsprinzip (1911)
Alleine im Inhaltsverzeichnis kann man viel interessantes sehen: Natürlich ist die Pädagogik noch nicht so festgelegt von der historischen Entwicklung - dafür werden alle möglichen Alternativen und Versuche damit verglichen. Und es tauchen viele Begriffe auf, die man so nicht mehr zu sehen bekommt.
Where Wikipedia leads, I follow. BAAAAAH.
|
[Dieser Beitrag wurde 1 mal editiert; zum letzten Mal von Wraith of Seth am 07.06.2014 16:49]
|
|
|
|
|
|
|
|
|
|
Spaß mit Algorithmen? Das Problem kenn ich, Spaß hatte ich nie...
|
|
|
|
|
|
Thema: pOT-lnformatik, Mathematik, Physik XVI ( Ship painting activities ) |