Generator liczb losowych 1c dla klienta internetowego. Wypadek, zbieg okoliczności, wzór

21
//Funkcja generuje czytelną reprezentację wartości. 16
// Przykłady formatowania liczb ValueFormat = Format(123456.789, " NRT=10; NRT=2"); //ValueFormat = "123 456,79"ValueFormat = Format(123456,789, "HH=0; NHV=2"); //Wartość 8
Wyszukiwanie pełnotekstowe - pozwoli Ci znaleźć informacje tekstowe znajdujące się niemal w każdym miejscu używanej konfiguracji. W takim przypadku potrzebne dane można wyszukiwać albo w całej konfiguracji jako całości, albo zawężając... 6
„Punkt w czasie” jest polem wirtualnym, nie przechowywanym w bazie danych. Zawiera obiekt Punkt w czasie (który zawiera datę i LINK DO DOKUMENTU). W wersji 7.7 istniała koncepcja Pozycji Dokumentu, a w wersji 8.x Punkt w Czasie Aby uzyskać...

Dla wersji 8.x FindByLinks (FindDataByRef) Składnia: FindByLinks (lista łączy) Parametry: Lista łączy Wymagany typ: Array. Tablica zawierająca listę łączy do obiektów, których łącza należy znaleźć. ...

Słowa kluczowe: generator, losowość, liczby, liczba, algorytm, losowość, randomizacja, dystrybucja, uniformizacja, loteria

Nie sądziłem, że będzie to przydatne w 1C, ale dla ciebie... klienci zdecydowali się na promocję typu „zbieraj czapki”, tylko ty musisz zbierać słowa, ten, kto uzbiera właściwe słowo ze swojego zestawu liter wygrywa. Ogólnie rzecz biorąc, zadanie wydawałoby się proste: jest alfabet, jest pewne słowo, które należy zebrać, na przykład „koniak”, ma 6 liter, jak widać.

Należy: wygenerować pewną liczbę losowych kombinacji sześcioliterowych z dowolnych liter alfabetu, dodać do tego pewną liczbę opcji, w których można jeszcze dodać słowo, np. „nkkoya” – słowo się tworzy, ale „kavry” najwyraźniej nie jest odpowiednie.

Warunek dodatkowy: wszystkie te opcje (poprawne i nie) muszą być ponumerowane, aby po otrzymaniu karty „nagrodowej” można było sprawdzić numer (czy był).
Wydawałoby się, co ma z tym wspólnego 1C? Chcą więc dodać rozliczenie tych kart i nagród do programu księgowego, a jednocześnie poprosili o wygenerowanie losowych kombinacji (no, żeby nie układać ich ręcznie).

Dla każdej promocji generowane są jednorazowo kombinacje, następnie na ich podstawie tworzone są karty, tj. następnym razem słowo będzie inne itp.
Generalnie zadanie sprowadza się do:
1. Generuj liczby losowe, najlepiej z dużym rozrzutem.
3. Punkt przeciwny do poprzedniego - sprawdź słownie numer kombinacji.

Rozwiązanie:
1. ponieważ generator z avb i NS dał mały rozrzut liczb losowych, musiałem zastosować nieco inny algorytm:

Funkcja Losowa()
jeśli pusta wartość (randSeed) = 1, to
RandSeed = _get Performancecounter();
endif;

RandSeed=(a*randSeed+c)%m;
zwróć RandSeed;
funkcja końcowa

Tutaj:
a=1664525; c=1013904223; m=4294967296;
ostatnia zmienna to 2 do potęgi 32, pozostałe dwa to współczynniki zalecane do tego celu

Maksymalny limit wartości 2^32 został wybrany na podstawie maksymalnej liczby kombinacji (dla przyciętego alfabetu składającego się z 28 liter i 7 słów każdy, ponieważ w prawdziwym zadaniu jest ich dokładnie 7, łączna liczba kombinacji wyniesie 28 ^7, zatem wybrany limit leży mniej więcej w środku przedziału, co w zupełności wystarczy dla próby 20-30 tysięcy opcji)

Potrzebujemy jeszcze jednej funkcji pomocniczej - podniesienia do dodatniej potęgi całkowitej:

Stopień funkcji (wartość a, wartość b, Res = 1)
Jeśli b>0 To
Rozdzielczość=Rozdzielczość*a;
b=b-1;
Stopień (a, b, Res);
Powrót do rozdzielczości;
W przeciwnym razie
Powrót do rozdzielczości;
koniecJeśli;
Funkcja końcowa

Tutaj: a - podstawa stopnia, b - wykładnik, Res - wynik

2. Identyfikacja zależności pomiędzy kombinacjami sekwencyjnymi okazała się zaskakująco prosta:

Po uporządkowaniu szeregu elementów ujawniłem podobieństwo układu symboli z systemem liczbowym, tyle że nie dziesiętnym, ale w tym przypadku „szesnastkowym” (według liczby znaków w powstałym „słowie”).
Zatem, aby obliczyć kombinację według jej liczby, konieczne było przeliczenie jej liczby na ten właśnie system liczbowy.

W naszym systemie liczbowym podstawą będą potęgi szóstki, tj. aby otrzymać pierwszą cyfrę po lewej stronie należy liczbę naszej kombinacji podzielić przez 6 do potęgi 5, następnie resztę dzielenia przez 6 do potęgi 4 itd.

W ten sposób otrzymujemy zestaw sześciu liczb, które w istocie są numerami kolejnymi liter w naszym alfabecie.

Wynikowy kod:

Funkcja GetCharacters(Pos,TexCharacter=1,SymStr="")
Jeśli TekSymv Divisor=Stopień(StrLength(Litera),k-TekSymv);
TechOst=Poz%Dzielnik;
SimStr=String(SimStr)+Av(Litery,Liczba całkowita(Poz/Dzielnik+?(TekOst>0,1,0)),1);
GetSymbols(TekOst,TekSymv+1,SymStr);
zwróć SimStr;
W przeciwnym razie
SimStr=SimStr+Średnia(Litery,(?(Poz=0,StrLength(Litery),Poz)),1);
zwróć SimStr;
koniecJeśli;
Funkcja końcowa

Tutaj:
Pos - numer kombinacji (liczba pseudolosowa)
TechSym - aktualnie przetwarzany symbol
SimStr - wynikowy ciąg znaków
Litery = ciąg zawierający litery alfabetu w standardowej kolejności („abv…yuya”)
k - liczba znaków w wyszukiwanym słowie (w tym przypadku = 6)

3. Odwrotna transformacja jest również banalna:

Funkcja GetCombination(Word, TechCharacter=0, Pos=0)
NomSymv=Znajdź(Litery,Am(Słowo,k-TekSymv,1));
Jeśli TechCym>0 To
Jeśli TechCym Pos=Pos+(NomCym-1)*Stopień(StrLength(Litery),TechCym);
W przeciwnym razie
Pozycja zwrotu;
koniecJeśli;
W przeciwnym razie
Pos=?(NomCym=StrLength(Litery),0,NomSymv);
GetCombination(Słowo, Znak Technologiczny+1, Poz);
Pozycja zwrotu;
koniecJeśli;
Funkcja końcowa

Tutaj:
Słowo to kombinacja znaków, których liczby szukamy
TekSymv - aktualnie przetwarzany symbol (w zasadzie cyfra „liczby” w formacie szesnastkowym)
Pos - żądany numer kombinacji


************************

Wymieszaj N liczb:

Dla a=1 do N cyklu
tablica[a]=a;
Koniec cyklu;
Dla a=1 do N-1 cyklu
Sl=Case(a,N);// Całkowita liczba losowa w przedziale [a..N]
K=tablica[a];
tablica[a]=tablica[Sl];
tablica[Sl]=K;
Koniec cyklu;

//********************************************************************************
************************

Sc = CreateObject("MSScriptControl.ScriptControl");
Sc.language = "VBscript";
sc.executeStatement("randomize");
będzie tutaj = Sc.eval("rnd");

Jak mogę losowo wybrać liczby od 1 do 100?

Rand=_GetPerformanceCounter()%(100+1);

wygląda na to, że to jest najlepsze

//********************************************************************************
************************

W wersji 8.0 można używać wbudowanego generatora identyfikatorów GUID do generowania liczb losowych.
Oto przykład prostej funkcji:

//tylko dla liczb całkowitych
Funkcja GetRandomNumber (min., maks.)

//zamiast Randomize
Dla n = 1 Do 100 cykli
Unikalny = nowy unikalny identyfikator;
Koniec cyklu;

//wygeneruj identyfikator GUID
Unikalny = AbbrLP (Nowy unikalny identyfikator);

//zachowaj tylko liczby
Unikalny = StrReplace(Unikalny, „-”, „”);
Unikalny = StrReplace(Unikalny, „a”, „”);
Unikalny = StrReplace(Unikalny, „b”, „”);
Unikalny = StrReplace(Unikalny, „c”, „”);
Unikalny = StrReplace(Unikalny, „d”, „”);
Unikalny = StrReplace(Unikalny, „e”, „”);
Unikalny = StrReplace(Unikalny, „f”, „”);

//mianownik musi mieć tę samą liczbę zer + 1
mianownik = 10;
Dla n = 2 By (StrLength(StrReplace(Unique,Characters.NPP,””))) Pętla
Mianownik = Mianownik * 10;
Koniec cyklu;

Przypadek = liczba (unikalna) / mianownik; //tutaj otrzymujemy ułamkową liczbę losową od 0 do 1

//przekonwertuj ją na liczbę losową z danego przedziału i zaokrąglij do najbliższej liczby całkowitej
NumberOfInterval = Min(Max(Ab(Min + (Max-Min)*Rand),Min),Max);

zwróć liczbę z interwału;

Funkcja końcowa

Zaczerpnięto z [musisz się zarejestrować, aby zobaczyć link]

//********************************************************************************
************************

PS. Natknąłem się na ten artykuł, szukając generatora liczb losowych. Więc dla siebie wybrałem opcję
Rand=_GetPerformanceCounter()%(100+1);

Nie tylko od tego wykrzyknika zacząłem artykuł. Tak się stało, programista ma w swoim arsenale wygodne narzędzie, które pozwala mu uzyskać losową liczbę całkowitą w zadanym przedziale. Standardowe funkcje w innych językach programowania generowały liczbę ułamkową z zakresu od 0 do 1. Nie jest to zbyt wygodna liczba w użyciu; trzeba się bardzo napracować, aby uzyskać losową sekwencję z danego zakresu, np 1 do 5.

Trzeba sprawdzić wygodne narzędzie, często RNG nie są zbyt wysokiej jakości i trzeba dodatkowo poćwiczyć matematykę, aby zwiększyć losowość generowanych liczb, aby pozbyć się źle wymieszanych pseudociągów. Często powierzamy losowym liczbom tajemnice, zasoby finansowe, rozrywkę, modelowanie, testowanie krytycznych zautomatyzowanych systemów sterowania, programy testujące, dlatego bardzo ważne jest, aby mieć unikalną sekwencję szeregu o różnych określonych cechach od przedziałów wartości po stopień mieszania numerów sekwencyjnych.

Podam przykład nieudanego generowania liczb losowych. W 1993 roku, kiedy niekolorowy monitor VGA o rozdzielczości 640x480 był uważany za dobry, a oczy programistów mniej się nim męczyły, system Paradox DBMS był powszechny. Chciwi ludzie z Borland International postanowili zarobić więcej pieniędzy i potrzebowali klucza składającego się z 10 cyfr, aby uzyskać dostęp do sieci. Im więcej kluczy wprowadzisz, tym więcej użytkowników będzie mogło jednocześnie połączyć się z bazą danych.

Teraz zacznę się chwalić swoimi sukcesami :). Na różne sposoby trafiły do ​​mnie 3 klucze i dotarło do mnie, że sekwencja była pseudolosowa i słabo zmiksowana. Bez żadnej technologii, skomplikowanych obliczeń, a nawet bez kalkulatora udało mi się uzbierać dowolną ilość tych kluczy. Oczywiście firma Borland nie poniosła dużych strat, ale skoro już zajmujesz się ochroną, to rób to dobrze lub nie marnuj czasu na bezużyteczną pracę. Nie będę wyciągał z tego morału, mam nadzieję, że stanie się jaśniejsze, że RNG to ważna sprawa.

W obronie ciągów pseudolosowych powiem, że czasami są one konieczne, np. gdy klucz zabezpieczający jest obliczany za pomocą wzoru i program postanawia pomyślnie zweryfikować klucz w trybie lokalnym. W 1993 roku Internet nie był jeszcze powszechny i ​​programiści musieli wymyślać algorytmy sekwencyjne bez testowania ich na serwerach innych firm. Ale pamiętaj, aby dobrze wymieszać. Wraz z nowoczesnym rozwojem sieci możliwa stała się weryfikacja numeru seryjnego zarówno programów, jak i sprzętu za pomocą serwerów weryfikacyjnych. System ten znacznie zwiększył odporność na podrabianie, ale nie jest tajemnicą, że mimo tego nadal dochodzi do nieuprawnionego korzystania z oprogramowania.

Wniosek jest taki: zamki i zaparcia instalują uczciwi ludzie.

Działanie obiektu na platformie 1C jest niezwykle proste, chociaż istnieją pewne osobliwości.

RNG = NewRandomNumberGenerator(Inicjalizacja); //Tutaj możesz zmienić działanie generatora liczb losowych, zmieniając Inicjalizacja liczby daje inne wyniki Return RNG.RandomNumber(1, SettingsOption);

Jeśli nie określisz Inicjalizacji, sekwencje będą generowane losowo, inicjując się. Podany numer inicjujący zwróci przewidywalną sekwencję, która czasami jest konieczna i przydatna. A jeśli za każdym razem podasz inną liczbę, uzyskasz bardzo dobre wymieszanie sekwencji liczb.

Aby zbadać działanie generatora liczb losowych w 1C, stworzyłem kilka zabiegów i uczyniłem jeszcze jeden bardziej interesujący w formie gry, ale gra później, najpierw biznes.

Wygenerowano 500 liczb losowych z zakresu od 0 do 10000, przy czym generator był stale inicjowany przez funkcję CurrentUniversalDateInMillisekundy(). Diagram pokazuje dobry rozkład wartości. Fantazyjny wzór. Na osi Y znajduje się wartość numeru, na osi X numer iteracji.

Położenia punktów są dość rzadkie, prawie się nie sklejają, co jest bardzo dobre, co oznacza, że ​​generowane liczby są dość zróżnicowane.

Stwórzmy sztucznie złą wersję diagramu:

W przypadku dobrego pokolenia tak nie powinno być.

Ustawienia generatora liczb losowych są bardzo ważnym punktem. Jest ich niewielu, ale wszystko od nich zależy.

Przy tym ustawieniu tworzony jest ciąg 500 liczb z zakresu od 0 do 10000, a generator jest stale inicjalizowany nową liczbą.

Przyjrzyjmy się wygenerowanej tabeli wartości, po wcześniejszym posortowaniu jej według wartości, aby sprawdzić, czy nie ma zduplikowanych liczb wydanych przez generator.

Szybka kontrola wzrokowa posortowanej listy wykazała, że ​​występowały powtórzenia, chociaż prawdopodobieństwo ich wystąpienia było niskie. Do generowania określono szeroki zakres liczb, ale w krokach 10 i 30 liczby się powtarzały.

Dochodzimy do wniosku: obiekt Generator liczb losowych może generować powtarzające się liczby.

Czasami jest to niedopuszczalne. Na przykład generujemy losowy numer dokumentu, niespójnie, aby poinformować użytkownika, kto może otworzyć konkretny dokument. W takim przypadku powtórzenia są niedopuszczalne, w przeciwnym razie po powtórzeniu nie będzie jasne, który dokument otworzyć.

Dlaczego potrzebna jest numeracja losowa? Załóżmy, że wystawiamy naszym partnerom numery dokumentów na sprzęt oddany do naprawy. Można nadawać numery ciągłe, sekwencyjne, ale klient mając jeden numer może przeglądać przynajmniej sąsiednie i znając odstęp numeracji może przeglądać wszystkie dokumenty. W podanym przykładzie nie jest to aż taka tajemnica, ale czasami konieczne jest zachowanie w tajemnicy informacji z innych dokumentów.

Przy dużych odstępach wartości liczb generacji prawdopodobieństwo powtórzenia się zdarzeń będzie się zmniejszać, ale jeśli zdarzenie może wystąpić, to na pewno wystąpi.

Rozwiązaniem może być sprawdzenie wygenerowanej liczby pod kątem niepowtarzalności, ale w przypadku bardzo długich sekwencji zajmie to dużo czasu. Będziemy musieli pomyśleć o bardziej skomplikowanym miksowaniu, ale to czyni zadanie ciekawszym ;).

Podczas wyświetlania wartości na wykresie przetwarzanie zaczyna zauważalnie zwalniać, na moim komputerze po dodaniu 1000 wartości, dlatego w ustawieniach znajduje się checkbox „Nie generuj wykresu”. Po zainstalowaniu prędkość działania znacznie wzrasta przy generowaniu długich sekwencji, dlatego podczas badań należy zachować ostrożność przy ustalaniu liczby generowanych liczb.

Generatorowi można nadać określoną wartość inicjującą, wtedy niezależnie od tego, jak mocno naciśniesz przycisk generowania, wynik będzie taki sam. Gdy pole przetwarzania „Numer inicjujący RNG” jest ustawione na 0, podczas generowania ciągu liczb następuje inicjalizacja pseudolosowa.

Szybkość generatora jest dobra, np. 100 000 liczb zostało wygenerowanych w mniej niż 0,5 sekundy.

Pokażę przykład użycia RNG na niewielkim zakresie liczb na przykładzie gry Kamień, Papier, Nożyce.

Zasady są proste: dwóch graczy pokazuje gestami wskazane obiekty. Wygrywa ten, kto w danym momencie będzie miał silniejszą sylwetkę.

Kamień pokonuje Nożyce.

Nożyczki pokonują papier.

Papier pokonuje Kamień.

W tej opcji wszystko jest równoważne i szanse na wygraną są takie same.

Po rozegraniu 99 gier wykonałem taką samą liczbę kliknięć w każdą figurkę, 33 razy, co widać na prawym dolnym schemacie. Komputer wygrywał częściej ode mnie, co było trochę rozczarowujące. Komputer częściej korzystał z papieru, co widać na lewym dolnym wykresie. Wykres pośrodku pokazuje, że nie byłem zwycięzcą. Czerwony wykres wygranych komputera jest wyższy niż zielony (moje wygrane).

Spróbuj szczęścia! Pomimo tego samego prawdopodobieństwa wypadnięcia kawałków, wynik jest zawsze inny.

Statystyki gry wyświetlane są pośrodku, u góry, w różowej grupie elementów.

Klikając raz myszką w przycisk, można następnie za pomocą cyfr na klawiaturze (nie dodatkowej) wybrać żądaną cyfrę. Naciskając klawisze, możesz nieco szybciej wprowadzać dane, szczególnie jeśli musisz grać w bezmyślne gry, aby gromadzić statystyki.

Skomplikujmy grę. Do klasycznych figurek dołóżmy Studnię.

Kamień pokonuje Nożyce.

Nożyczki pokonują papier.

Paper pokonuje Rock and Well.

Well pokonuje Kamień i Nożyce.

W tym wariancie pojawia się nierówna wartość pionów i teoretycznie większe szanse na wygraną jest wybór Papieru i Studni, gdyż w swoim arsenale mają zwycięstwo nad dwoma innymi pionami. Sprawdźmy to w praktyce:

Klikałem tylko na mocne elementy i wygrywałem. Teorię potwierdziła praktyka.

Klikanie tylko na słabe kawałki też dawało rezultaty, przegrałem.

Jeszcze bardziej złożoną wersją gry jest wprowadzenie piątego elementu, Fire.

Rock pokonuje Nożyce, a Well przegrywa z Papierem i Ogniem.

Scissors pokonuje Paper, a Fire przegrywa z Rock and Well.

Papier pokonuje Skałę, a Studnia przegrywa z Ogniem i Nożycami.

Well pokonuje Ogień i Nożyce przegrywa z Rock and Paper.

Ogień pokonuje Papier, a Kamień przegrywa z Nożyczkami i Studnią.

W tym wariancie piony są równe, ale dwie figury wygrywają i przegrywają, co dodaje intrygi i zmniejsza prawdopodobieństwo remisu.

Moje kliknięcia były chaotyczne i komputer znowu mnie ubiegł. Podczas gry możesz zobaczyć, której figury komputer używa częściej; na podstawie tych informacji możesz spróbować grać nie chaotycznie, ale przemyślanie i możliwie zwiększyć swoje szanse na sukces.

Konfigurowanie generatora liczb losowych ma swoją własną charakterystykę. Gdy flaga „Nie używaj odpowiedzi użytkownika” jest wyczyszczona, podczas inicjalizacji RNG używany jest numer klawisza naciśniętego przez gracza, co dodaje losowości do generowania. Człowiek jest doskonałym generatorem liczb losowych, ale mimo to mózg ma także pseudociągi. Jeśli zmusisz osobę do wykonania 100 naciśnięć klawiszy, to tę procedurę można wykonać sumiennie, wciskając jak najwięcej różnych klawiszy, lub można to zrobić niedbale, wciskając tylko jeden przycisk. Kiedy ta flaga jest ustawiona, działa tylko tasowanie komputerów.

Otrzymując od osoby losową sekwencję, na przykład w celu utworzenia klucza do podpisu elektronicznego, warto wziąć pod uwagę nie tylko naciśnięty klawisz, ale także odstęp między naciśnięciami. Jest to informacja bardzo losowa, choć dobry muzyk potrafi wygenerować tę samą sekwencję kilka razy.

Flaga „Nie używaj inicjalizacji RNG” włącza/wyłącza tryb inicjalizacji. Jeśli nie określisz inicjalizacji podczas tworzenia obiektu Generatora liczb losowych, wówczas generowana jest sekwencja mieszana. Jak rozumiem, uwzględniony jest pewien rodzaj inicjalizacji, co wydawało mi się całkiem skuteczne.

RNG = generator nowej liczby losowej();

Ponadto podczas przetwarzania możesz ustawić własny numer inicjujący, a następnie zostanie wygenerowany ten sam numer w przewidywalny sposób.

Pisząc procedurę obliczania wygranej, napotkałem problem opisania wyniku, szczególnie w przypadku gry pięciocyfrowej. Po rozgryzieniu tego zdałem sobie sprawę, że będzie dużo liter, ponieważ istnieje wiele opcji o tak wielu kształtach. Kombinatoryka mówi nam, że przy trzech liczbach mamy maksymalnie 9 opcji, przy czterech 16 opcjach i pięciu 25 opcjach. Pomijając losowania, czyli w przypadku wybrania tej samej figury, zdałem sobie sprawę, że będę musiał napisać 19 wariantów warunków.

Pomyślałem o tym, ponieważ oczywiście skutkowałoby to słabo czytelnym kodem, i znalazłem, moim zdaniem, piękne rozwiązanie. W sumie 9 warunków.

Res = Gracz - Komp;

Jeśli SettingsOption = 3 Następnie Jeśli (Res = -1) LUB (Res = 2) Następnie zwróć 1; //Wygraj w przeciwnym razie Zwróć 2; //Pokonaj EndIf;

Pomyślałem, że każda figurka ma swój numer: 1 – Kamień, 2 – Nożyczki, 3 – Papier, 4 – Cóż, 5 – Ogień. W wyniku gry obliczam różnicę między liczbami pionków i ta różnica daje mi jednoznaczną odpowiedź na pytanie, kto wygrał.

Przetwarzanie, które pomaga eksplorować właściwości losowych sekwencji dla zarządzanej aplikacji i jest zapisywane bez odniesienia do konfiguracji. Testowane na platformie 8.3.10, 8.3.11 na cienkim kliencie.

W tym artykule miałem nadzieję przekazać znaczenie i powagę generowania losowych sekwencji liczb.


Dla wersji 8.x FindByLinks (FindDataByRef) Składnia: FindByLinks (lista łączy) Parametry: Lista łączy Wymagany typ: Array. Tablica zawierająca listę łączy do obiektów, których łącza należy znaleźć. ...

Nie sądziłem, że będzie to przydatne w 1C, ale proszę bardzo… klienci zdecydowali się na promocję typu „zbieraj czapki”, tylko Ty musisz zbierać słowa, ktokolwiek zbierze właściwe słowo ze swojego zestawu litery wygrywają. Ogólnie rzecz biorąc, zadanie wydawałoby się proste: jest alfabet, jest pewne słowo, które należy zebrać, na przykład „koniak”, ma 6 liter, jak widać.

Należy: wygenerować pewną liczbę losowych kombinacji sześcioliterowych z dowolnych liter alfabetu, dodać do tego pewną liczbę opcji, w których można jeszcze dodać słowo, np. „nkkoya” – słowo się tworzy, ale „kavry” najwyraźniej nie jest odpowiednie.

Warunek dodatkowy: wszystkie te opcje (poprawne i nie) muszą być ponumerowane, aby po otrzymaniu karty „nagrodowej” można było sprawdzić numer (czy był).

Wydawałoby się, co ma z tym wspólnego 1C? Chcą więc dodać rozliczenie tych kart i nagród do programu księgowego, a jednocześnie poprosili o wygenerowanie losowych kombinacji (no, żeby nie układać ich ręcznie).
Dla każdej promocji generowane są jednorazowo kombinacje, następnie na ich podstawie tworzone są karty, tj. następnym razem słowo będzie inne itp.

Generalnie zadanie sprowadza się do:
1. Generuj liczby losowe, najlepiej z dużym rozrzutem.
2. Korzystając z liczby, oblicz kombinację liter (tj. znajdź zgodność między możliwymi kombinacjami a ich liczbami).
3. Punkt przeciwny do poprzedniego - sprawdź słownie numer kombinacji.

Rozwiązanie:
1. ponieważ generator z avb i NS dał mały rozrzut liczb losowych, musiałem zastosować nieco inny algorytm:

Funkcja Random() jeśli pusta wartość(randSeed) = 1 to randSeed = _get Performancecounter();

endif;
randSeed=(a*randSeed+c)%m;
zwróć RandSeed; funkcja końcowa

Maksymalny limit wartości 2^32 został wybrany na podstawie maksymalnej liczby kombinacji (dla przyciętego alfabetu składającego się z 28 liter i 7 słów każdy, ponieważ w prawdziwym zadaniu jest ich dokładnie 7, łączna liczba kombinacji wyniesie 28 ^7, zatem wybrany limit leży mniej więcej w środku przedziału, co w zupełności wystarczy dla próby 20-30 tysięcy opcji)

Potrzebujemy jeszcze jednej funkcji pomocniczej - podniesienia do dodatniej potęgi całkowitej:

Stopień funkcji (wartość a, wartość b, Res=1) Jeśli b>0 To Res=Res*a;

b=b-1;

Stopień (a, b, Res);

Powrót do rozdzielczości;
W przeciwnym razie zwróć res;

koniecJeśli; Funkcja końcowa

Tutaj: a - podstawa stopnia, b - wykładnik, Res - wynik

2. Identyfikacja zależności pomiędzy kombinacjami sekwencyjnymi okazała się zaskakująco prosta:

Po uporządkowaniu szeregu elementów ujawniłem podobieństwo układu symboli z systemem liczbowym, tyle że nie dziesiętnym, ale w tym przypadku „szesnastkowym” (według liczby znaków w powstałym „słowie”).<к Тогда Делитель=Степень(СтрДлина(Буквы),к-ТекСимв); ТекОст=Поз%Делитель; СимСтр=Строка(СимСтр)+Сред(Буквы,Цел(Поз/Делитель+?(ТекОст>Zatem, aby obliczyć kombinację według jej liczby, konieczne było przeliczenie jej liczby na ten właśnie system liczbowy.

endif;
W naszym systemie liczbowym podstawą będą potęgi szóstki, tj. aby otrzymać pierwszą cyfrę po lewej stronie należy liczbę naszej kombinacji podzielić przez 6 do potęgi 5, następnie resztę dzielenia przez 6 do potęgi 4 itd.
W ten sposób otrzymujemy zestaw sześciu liczb, które w istocie są numerami kolejnymi liter w naszym alfabecie.
Wynikowy kod:
Funkcja GetCharacters(Pos,TechChar=1 ,SymStr="") Jeśli TechChar
0,1,0)),1);

GetSymbols(TekOst,TekSymv+1,SymStr);

zwróć SimStr;<к Тогда Поз=Поз+(НомСимв-1 )*Степень(СтрДлина(Буквы),ТекСимв); ПолучитьКомбинацию(Слово,ТекСимв+1 ,Поз); Иначе Возврат Поз; КонецЕсли; Иначе Поз=?(НомСимв=СтрДлина(Буквы),0 ,НомСимв); ПолучитьКомбинацию(Слово,ТекСимв+1 ,Поз); Возврат Поз; КонецЕсли; КонецФункции

endif;
W przeciwnym razie SimStr=SimStr+Average(Letters,(?(Pos=0 ,StrLength(Litery),Pos)),1 );
zwróć SimStr;
koniecJeśli; Funkcja końcowa

Pos - numer kombinacji (liczba pseudolosowa)

TechSym - aktualnie przetwarzany symbol SimStr - wynikowy ciąg znaków K=tablica[a];

tablica[a]=tablica[Sl];

tablica[Sl]=K; Koniec cyklu;

Sc = CreateObject("MSScriptControl.ScriptControl "); Sc.language = "VBscript"; sc.executeStatement("randomizuj "); będzie tutaj = Sc.eval("rnd ");
Jak mogę losowo wybrać liczby od 1 do 100?

Rand=_GetPerformanceCounter()%(100 +1);
wygląda na to, że to jest najlepsze

Mata biblioteczna. funkcje, gdzie istnieje generator sl. takty muzyczne:
http://1c.proclub.ru/modules/mydownloads/personal.php?cid=92&lid=2688

W wersji 8.0 można używać wbudowanego generatora identyfikatorów GUID do generowania liczb losowych. Oto przykład prostej funkcji: //tylko dla liczb całkowitych Funkcja GetRandomNumber(Min,Max) //zamiast losowania dla n = 1 na 100 Cykl Unique = New UniqueIdentifier; Koniec cyklu;//wygeneruj unikalny identyfikator GUID = AbbrLP(Nowy unikalny identyfikator); //zachowaj tylko liczby Unikalny = StrReplace(Unikalny, „-”, „”); Unikalny = StrReplace(Unikalny, „a”, „”);

Unikalny = StrReplace(Unikalny, „b”, „”);
Unikalny = StrReplace(Unikalny, „c”, „”);



Unikalny = StrReplace(Unikalny, „e”, „”);