Seite 2 von 2

Verfasst: Mittwoch 18. Juni 2008, 07:39
von n4p
Karl hat geschrieben:5. Wäre es cool, jetzt einfach den Pythoncode zu posten? :)
defintiv nicht :P

Verfasst: Mittwoch 18. Juni 2008, 10:08
von BlackJack
Und die obligatorische Lösung in Io:

Code: Alles auswählen

#!/usr/bin/env io

BigNum squared := method(self ** 2)
Sequence asBigNum := method(BigNum with(self))

QRandom := Object clone do(
    state ::= BigNum
    length ::= 0
    offset ::= 0
    
    with := method(n,
        result := QRandom clone setState(BigNum with(n))
        result setLength(result state asString size)
        result setOffset(result length >> 1)
    )
    
    next := method(
        state = state squared asString slice(offset, offset + length) asBigNum
    )
)

n := 11111
x := 20

random := QRandom with(n)
x repeat(random next println)

Verfasst: Mittwoch 18. Juni 2008, 11:57
von Rebecca
So, dann will ich auch mal. "Zufalls"zahlen in Emacs:

Code: Alles auswählen

(defun middle-letters (txt n)
  (let ((start (/ (- (length txt) n) 2))
	(end (/ (+ (length txt) n) 2)))
    (substring txt start end)))

(defun neumann-step (number)
  (let ((n (length (number-to-string number))))
    (string-to-number (middle-letters (number-to-string (expt number 2)) n))))

(defun neumann-rand (start steps)
  (dotimes (i steps start)
    (setq start (neumann-step start))))

(neumann-rand 123 3)

Verfasst: Mittwoch 18. Juni 2008, 12:50
von Hyperion
Ich warte auf Brainf**k oder zur Not Prolog ;-)

Verfasst: Mittwoch 18. Juni 2008, 16:40
von EyDu
Na gut, dann noch eine Prologlösung. Nicht schön, aber selten:

Code: Alles auswählen

square(N, M) :- M is N * N.
heads([H], []).
heads([H|T], [H|K]) :- heads(T, K).
intToList(I, L) :- intToListH(I, T), reverse(T, L).
intToListH(I, [I]) :- I < 10, !.
intToListH(I, [H|Tail]) :- H is I mod 10, R is I // 10, intToListH(R, Tail).
listToInt(L, A) :- reverse(L, R), listToIntH(R, 1, A).
listToIntH([E], F, G) :- E < 10, G is E*F, !.
listToIntH([H|T], F, E) :- A is H*F, FF is F*10, listToIntH(T, FF, C), E is A+C.
center(A, N, A) :- length(A, L), L =:= N, !.
center([H|T], N, B) :- length(T, L), I is L mod 2, I =:= 0, center(T, N, B), !.
center(T, N, B) :- heads(T, K), center(K, N, B), write('test'), !.
main(I, R) :- square(I, X), intToList(I, Z), intToList(X, Y), length(Z, L),
              center(Y, L, A), listToInt(A, R).

Verfasst: Mittwoch 18. Juni 2008, 17:03
von Karl
Wie genau ist denn "2. quadriere und wähle die mittleren n Ziffern als neue Zufallszahl" gemeint?
123456789
-> Welche Ziffern muss ich denn jetzt da rausnehmen?

Verfasst: Mittwoch 18. Juni 2008, 17:14
von EyDu
Du nimmst dir eine Zahl n. Zum Beispiel 5484.
Dann quadrierst du diese: 30074256.
Die Zufallszahl bildet sich dann aus den viert (weil n vier Zeichen lang ist) mittleren Ziffern des Quadrats: 0742.

Verfasst: Mittwoch 18. Juni 2008, 17:41
von Karl
EyDu hat geschrieben:Du nimmst dir eine Zahl n. Zum Beispiel 5484.
Dann quadrierst du diese: 30074256.
Die Zufallszahl bildet sich dann aus den viert (weil n vier Zeichen lang ist) mittleren Ziffern des Quadrats: 0742.
Okay, so hab ich mir das auch gedach, aber nehmen wir mal an, du nimmst 1111 und quadrierst diese Zahl: 1234321
So, welche sind die mittleren Ziffern?
2343 oder 3432?

Verfasst: Mittwoch 18. Juni 2008, 17:43
von EyDu
Karl hat geschrieben:So, welche sind die mittleren Ziffern?
Such Dir eben eine der Möglichkeiten aus ;-)

Verfasst: Mittwoch 18. Juni 2008, 17:59
von Karl
EyDu hat geschrieben:
Karl hat geschrieben:So, welche sind die mittleren Ziffern?
Such Dir eben eine der Möglichkeiten aus ;-)
Wenn der uns hier schon einen Algorithmus beschreibt, könnte's ja auch eindeutig sein :p Ist ja sonst keiner.
Also *noch einen 6. Punkt gefunden hat, warum Leonidas keine Millionen kriegt* (wobei der 4. und 5. Punkt keine Gründe sind)

Verfasst: Mittwoch 18. Juni 2008, 21:56
von Leonidas
EyDu hat geschrieben:
Karl hat geschrieben:So, welche sind die mittleren Ziffern?
Such Dir eben eine der Möglichkeiten aus ;-)
Ja, das war auch genau der Punkt der mir das meiste Kopfzerbrechen bei meiner Lösung gekostet hat, weil ich mich nicht entscheiden konnte und das wohl nicht definiert war. Ich finde das aber recht blöd, weil es damit quasi zwei Arten des Algorithmus gibt, die unterschiedliche Ergebnisse liefern.

Verfasst: Mittwoch 18. Juni 2008, 22:03
von Karl
Ja, deshalb ist das korrekterweise auch kein Algorithmus.
Jedenfalls ist er zu unpräzise beschrieben.
Ich hab gerade angefangen, das in Brainfuck zu schreiben, aber ich bin noch nicht wirklich weit :p das is ne richtige Qual.

Verfasst: Mittwoch 18. Juni 2008, 22:12
von numerix
Es scheint so zu sein, dass man bei der Quadratmittenmethoden nach Neumann, um die es hier ja geht, in solchen Fällen, die "Mitte" nach rechts verschiebt.

Beleg - leider ohne weitere Erläuterung, warum gerade dies die Mitte ist:
http://statistik.mathematik.uni-wuerzbu ... seudo.html

Verfasst: Mittwoch 18. Juni 2008, 22:34
von BlackJack
Eine Lösung in C, die `libgmp` verwendet. Mittelpunktberechnung ist aber bei meinen Lösungen auf die hypothetischen doppelt so vielen Ziffern der Ausgangszahl bezogen, die beim Quadrieren entstehen können. Alles andere war mir zu kompliziert, weil man sich Sonderfälle einhandelt, wenn der aktuelle Zustand weniger als die hälfte der Ziffern der Ausgangszahl hat.

Code: Alles auswählen

#include <alloca.h>
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>

typedef struct {
    mpz_t state;
    unsigned int length;
} QRandom;

void QRandom_init(QRandom *r, unsigned long n)
{
    mpz_init_set_ui(r->state, n);
    r->length = mpz_sizeinbase(r->state, 10);
}

void QRandom_destroy(QRandom *r)
{
    mpz_clear(r->state);
    r->length = 0;
}

unsigned long QRandom_next(QRandom *r)
{
    char *tmp;
    unsigned int offset;
    
    mpz_mul(r->state, r->state, r->state);
    tmp = alloca(r->length * 2 + 1);
    mpz_get_str(tmp, 10, r->state);
    offset = r->length / 2;
    tmp[offset + r->length] = '\0';
    mpz_set_str(r->state, tmp + offset, 10);
    return mpz_get_ui(r->state);
}

int main(int argc, char** argv) {
    QRandom random;
    unsigned int i;
    
    QRandom_init(&random, 11111);
    for (i = 0; i < 20; ++i) {
        printf("%lu\n", QRandom_next(&random));
    }
    QRandom_destroy(&random);
    
    return EXIT_SUCCESS;
}
Wobei mir gerade auffällt, dass vielleicht auch mal eine 0 oder eine 1 als Zustand auftreten kann, dann sieht's blöd aus mit den folgenden "Zufallszahlen". :-)

Verfasst: Mittwoch 18. Juni 2008, 23:05
von mitsuhiko
Und hier in Vimscript: http://paste.pocoo.org/show/73064/

Muss mal wieder Schmerzen spüren :-)

Verfasst: Donnerstag 19. Juni 2008, 00:01
von dennda
Hier noch ein bisschen sehr schlechtes Java.

Wer mich dafür kritisiert wird erschossen. :D

Verfasst: Donnerstag 19. Juni 2008, 00:18
von audax
Rekursiv in Java?
Mutig ;D

Verfasst: Donnerstag 19. Juni 2008, 07:28
von Hyperion
audax hat geschrieben:Rekursiv in Java?
Mutig ;D
Wieso?

@dennda:
Du könnest Dir den häßlichen Cast in Zeile 25 sparen:

Code: Alles auswählen

String subsequence = cast.substring(mid-2, mid+2);

Verfasst: Donnerstag 19. Juni 2008, 08:23
von mitsuhiko
Und weil's so schön ist nochmal in C:

Code: Alles auswählen

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int
nrnd(int n, int x)
{
        int l, nl, offset, i;
        char s[100], s2[100];
        sprintf(s, "%d", n);
        l = strlen(s);

        for (i = 0; i != x; ++i) {
                sprintf(s, "%d", n * n);
                nl = (strlen(s) - l) / 2;
                memcpy(s2, s + nl, l);
                s2[l] = '\0';
                n = atoi(s2);
        }

        return n;
}