2013-02-03 20 views
5

Jak wygenerować losowo w Scheme? Czy istnieje specjalna forma, czy też muszę utworzyć procedurę? A jeśli tak, jak mam to zrobić? (Próbuję utworzyć procedurę o nazwie losowy wybór, która wprowadza dwie strategie i zwraca losowo.)Schemat - generowanie losowe

+0

Ten zły chłopiec może pomóc, nawet jeśli jest zamknięty. [Program: tworzenie losowym [zamknięte]] [1] [1]: http://stackoverflow.com/questions/12334891/scheme-creating-a-random-range – TopGunCoder

Odpowiedz

5

Procedura nazywa się, co zaskakujące, random - chociaż dokładna składnia może być różna w zależności od interpretatora schematu w użyciu (przeczytaj dokumentację!), ale ogólna idea jest następująca:

(random) 
=> 0.9113789707345018 

na powrocie jeden z dwóch możliwych wartości, będzie to rade w Racket:

zauważyć, żeArgumentprzekazany do random zmusza go do losowego zwrócenia jednej z dwóch możliwych wartości: 0 lub 1. Więc jeśli (random 2) ocenia na 0, to zwracana jest a, w przeciwnym razie zwracana jest b.

(random-choice 4 2) 
=> 4 
(random-choice 4 2) 
=> 2 
+3

Nie w standardowym schemacie, nie jest. Większość implementacji ma możliwość tworzenia liczb losowych, ale nie wszystkie używają tej samej nazwy lub tego samego podpisu. Na przykład w Guile istnieje procedura "losowa", ale wymaga ona co najmniej jednego argumentu i zawsze zwraca liczbę całkowitą. Zatem twój kod spowoduje błąd w Guile (i wielu innych implementacjach Schematu, jak sobie wyobrażam). Można udzielać odpowiedzi specyficznych dla implementacji, jeśli nie ma standardowych odpowiedzi, ale należy przynajmniej wspomnieć, że jest to konkretna implementacja i do której konkretnej implementacji jest przeznaczona. – sepp2k

+0

@ sepp2k Wyjaśniłem to, dzięki –

+0

@ sepp2k Jeśli przez "standard" dołączasz "końcowe" skróty SRFI (i robię to), [SRFI 27] (http://srfi.schemers.org/srfi-27/srfi-27 .html) określa interfejs uzyskiwania losowych liczb. –

5

Program standardowy nie zawiera generator liczb losowych i chociaż większość implementacji Schemat podany, są zazwyczaj różnią się w swych szczegółach. Jeśli chcesz napisać program Schematu przenośnego, możesz łatwo zbudować własny generator liczb losowych; oto metoda powodu Knuth:

(define random 
    (let ((a 69069) (c 1) (m (expt 2 32)) (seed 19380110)) 
    (lambda new-seed 
     (if (pair? new-seed) 
      (set! seed (car new-seed)) 
      (set! seed (modulo (+ (* seed a) c) m))) 
     (/ seed m)))) 

Wywołanie (random) Zwraca losową frakcji między 0 (włącznie) i 1 (Exclusive). Cykl losowych frakcji z okresem m. Wywołanie (random seed) resetuje początek generatora liczb losowych, aby dwie losowe sekwencje rozpoczynające się od tego samego materiału siewnego były identyczne; daty w formie RRRRMMDD zrobić dobre nasiona (to urodziny Knuth powyżej). Jeśli chcesz rzucić monetą, powiedz: (if (< (random) 1/2) 'heads 'tails).

Czasami chcesz losową liczbę całkowitą w pewnym zakresie. Przedstawiona poniżej funkcja randint zwraca losową liczbę całkowitą w zakresie od lo (włącznie) do hi (wyłącznie); lo domyślnie 0:

(define (randint . args) 
    (cond ((= (length args) 1) 
      (floor (* (random) (car args)))) 
     ((= (length args) 2) 
      (+ (car args) (floor (* (random) (- (cadr args) (car args)))))) 
     (else (error 'randint "usage: (randint [lo] hi)")))) 

Liczby losowe, takie jak te są wystarczająco dobre dla prostych symulacji, ale uwaga nie nadają się one do zastosowań kryptograficznych. Jeśli jesteś zainteresowany, mam kilka generatorów liczb losowych, w tym niektóre odpowiednie do aplikacji kryptograficznych, pod adresem my blog.

1

Ponieważ twoje drugie pytanie dotyczyło wykonania gry w kosmicznym statku w DrRacket, zakładam, że według Scheme masz na myśli jeden z języków nauczania w DrRacket.

Sposób wyszukiwania informacji o dostępnych funkcjach DrRacket jest prosty. Napisz, powiedzmy, random w oknie interakcji. Umieść kursor na górze, a następnie naciśnij F1.

Dokumentacja na random w HTDP-języków jest tutaj:

http://docs.racket-lang.org/htdp-langs/beginner.html?q=random#(def.htdp-beginner.((lib._lang/htdp-beginner..rkt)._random))

Jednym ze sposobów, aby zwrócić wartość losową:

(list-ref (list "one" "two") (random 2)) 

Tu (losowo 2) zwróci 0 lub 1 List-ref zwróci więc albo wpis z indeksem 0, albo indeksem 1 listy.

Zaletą korzystania z powyższego podejścia jest to, że łatwo jest rozszerzyć na więcej wartości niż dwa.