Przeczytałem to pytanie i pomyślałem, że będzie to niezłe wyzwanie.
Zadanie
Podaj dane wejściowe, aby 0<n<10
wygenerować losową liczbę z
- dokładnie n cyfr
- pierwszy nie
0
- więc
f(n)>10**(n-1)-1
- więc
- wyraźne cyfry
Kryteria wygranej
To jest golf golfowy, więc wygrywa najkrótszy kod.
Losowy
Mam na myśli równomiernie rozłożone losowo. Z punktu widzenia programu każda możliwa liczba ma taką samą szansę. Jeśli język, w którym piszesz, ma dziwny generator liczb losowych, możesz go używać.
Przykład
Lista wartości do losowego wyboru dla n=2
to:
[10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98]
code-golf
number
random
grid
game
king-of-the-hill
javascript
code-golf
arithmetic
statistics
code-golf
math
code-golf
math
code-golf
string
palindrome
code-golf
string
interactive
code-golf
quine
polyglot
code-golf
string
stack-exchange-api
code-golf
number-theory
decision-problem
code-golf
tips
code-golf
string
internet
code-golf
graphical-output
image-processing
fractal
code-golf
ascii-art
geometry
hexagonal-grid
code-golf
string
restricted-source
hello-world
code-golf
game
code-golf
cipher
code-golf
permutations
cops-and-robbers
permutations
cops-and-robbers
code-golf
internet
stack-exchange-api
code-golf
ascii-art
random
code-golf
tips
code-golf
ascii-art
code-golf
code-golf
kolmogorov-complexity
code-golf
string
unicode
code-golf
number
sequence
primes
palindrome
code-golf
game
decision-problem
code-golf
math
geometry
code-golf
graphical-output
interactive
code-golf
set-partitions
code-golf
number
arithmetic
restricted-source
code-golf
decision-problem
python
recursion
code-golf
ascii-art
code-golf
source-layout
code-golf
function
recursion
functional-programming
code-golf
game
combinatorics
permutations
code-golf
string
file-system
code-golf
string
hashing
code-golf
stack-exchange-api
code-golf
string
code-golf
math
number
arithmetic
polyglot
Roman Gräf
źródło
źródło
Odpowiedzi:
Python 2 , 77 bajtów
Wypróbuj online!
Tasuje listę 10 cyfr, aż nie zacznie się od 0, a następnie tworzy liczbę z pierwszymi
n
cyframi na liście.źródło
9
lub10
.[1::3]
działa konwersja go z listy do ciągu? Nigdy wcześniej tego nie widziałem.[
.[1::3]
pobiera znak o indeksie 1, a następnie co trzeci. To[1, 2, 3]
daje123
, pomijając nawiasy klamrowe, przecinki i spacje.[1, 2, 3]
już stringified i że przecinki i spacje potrzebne pomijam. Dzięki!Brachylog ,
910 bajtówWypróbuj online!
Jak zwykle w przypadku Brachylog, jest to przesłanie funkcji. Powyższe łącze TIO otrzymało argument wiersza polecenia, aby uczynić tę funkcję pełnym programem.
Musiałem dodać dodatkowy bajt z pierwszej wersji tego, zmieniając
ℕ
naℕ₁
, aby uniemożliwić wyjście 0 (coś, co zostało teraz wyjaśnione).Wyjaśnienie
Dość nieefektywny, ponieważ interpreter generuje listę wszystkich możliwych wartości, a następnie wybiera jedną losowo (to
ᶠṛ
znaczy; Brachylog nie miał opcji „wybierz losowe rozwiązanie” w momencie zadawania pytania).Kilka uwag na temat etykietowania tutaj: jeśli
≜
zostanie pominięty, sekcja w nawiasach klamrowych wytwarza tylko jedną wartość, ograniczenie reprezentujące liczby z pożądaną właściwością; wybranie losowego wyniku daje nam zatem ograniczenie, a interpreter wyprowadza minimalną wartość bezwzględną, która spełnia ograniczenie (1, 10, 102, 1023, 10234 itd.), czego nie chcemy. Musimy więc zmusić go do stworzenia listy poprzez wyraźne oznaczenie.Większość implementacji Prologa, które widziałem, ma wbudowaną funkcję znajdowania losowego wyniku pasującego do ograniczenia, ale zazwyczaj nie z jednakowym prawdopodobieństwem; Brachylog nie miał jednak jednego (został dodany w odpowiedzi na to wyzwanie, ale oczywiście nie mogę go użyć z powodu reguł luki). Gdyby tak było, a gdyby zdarzyło się, że dałoby to jednolite prawdopodobieństwo wystąpienia tego problemu, po tym programie
~lℕ₁≠
następowałaby wbudowana funkcja, prawdopodobnie o długości 6 bajtów.Brachylog , 8 bajtów, we współpracy z @Fatalize
Wypróbuj online!
Jest to genialna sztuczka niskiego poziomu, która ma sens tylko w sposobie, w jaki Prolog robi rzeczy, i nie ma większego sensu, gdy jest opisana matematycznie.
Tak jak poprzednio,
~lℕ₁≠
tworzy wartość opisującą ograniczenie („długość równa wartości wejściowej, liczba naturalna, wszystkie elementy różne”). Następnie≜ᶠ
generuje wszystkie możliwe wartości, które spełniają ograniczenie. Chodzi o to, że w sekwencji oceny Brachylog nie dokonuje się żadnych rzeczywistych wyborów do momentu≜
pojawienia się, więc operacja „znajdź wszystkie rozwiązania”ᶠ
musi mieć zastosowanie tylko do operacji „konkretnej wartości, która spełnia ograniczenie”≜
. Oznacza to, że nie trzeba{…}
wybierać jego zakresu, oszczędzając 2 bajty.źródło
≜₁
zanim zdałem sobie sprawę, że zostało dodane z powodu tego wyzwaniaGalaretka , 9 bajtów
Wypróbuj online! (nie będzie działać w TIO dla n> 6 z powodu nieefektywności wdrożenia)
lub alternatywne wdrożenie tego samego:
W jaki sposób?
Jest to dość podstępne i bardzo nieefektywne! Galaretka robi pośrednio pewne użyteczne rzeczy, gdy atom oczekuje listy, ale otrzymuje liczbę całkowitą (jest to zgodne z projektem).
W tym kodzie zastosowano kilka użytecznych niejawnych działań:
Atom monadyczny
Ṗ
, „pop”, gdy jest wywoływany z wejściową liczbą całkowitą, domyślnie tworzy zakres, z którego ma się wyskoczyć, więc wejście n najpierw powoduje [1, 2, ..., n] , a następnie wyskakuje, dając [1, 2 , ..., n-1] .Atom monadyczny
Q
, „de-duplikat” lub „unikatowy”, gdy jest wywoływany z wejściową liczbą całkowitą, domyślnie tworzy listę dziesiętną do de-duplikacji, więc na wejściu n gdzie:n = d k-1 × 10 k-1 + d k-2 × 10 k-2 + ... + d 1 × 10 + d 0
najpierw tworzy
[d k-1 , d k-2 , ..., d 1 , d 0 ],
a następnie daje unikalne wartości przez pierwsze pojawienie się.
Na przykład n = 5835518 dałoby [5, 8, 3, 1] .
Ponadto atom monadyczny
M
, „indeksy maksymalnych elementów”, zwraca indeksy maksymalnych pozycji z listy, co pozwala zaoszczędzić dwa bajty na znacznie bardziej oczywistej alternatywie testowania równości z danymi wejściowymi i znajdowaniem prawdziwych indeksów⁵*ṖQL$€=⁸TX
, lub⁵*ṖðQL⁼ð€TX
Wszystko to jest dość nieefektywne, zarówno pod względem czasu, jak i pamięci: najpierw tworzona jest lista 10 n liczb całkowitych, a jedna jest odrzucana, a następnie dla każdej z nich tworzona jest lista n liczb całkowitych (nie jakiś wymyślny 4-bitowy obiekt lub wyliczenie) a następnie zduplikowane. Ta deduplikacja ma całkowicie opartą na liście implementację (pod zestawem nie są zaangażowane żadne zestawy, zestawy posortowane ani słowniki, każda cyfra jest sprawdzana pod kątem istnienia na liście, która ostatecznie otrzymuje dane wyjściowe).
Offline n = 7 zużywa ~ 0,5 GB i zajmuje ~ 25 sekund, podczas gdy n = 8 zużywa ~ 4 GB i zajmuje ~ 5 minut - nie przejmowałem się uruchomieniem n = 9, ponieważ mam tylko 16 GB pamięci RAM (myślę, że zajęłoby to ~ 45 minut ).
Alternatywna implementacja korzysta tylko z wbudowanego
ÐṀ
szybkiego filtrowania i utrzymywania minimalnego poziomu (co tutaj dodaje tylko trochę narzutu w zarządzaniu dla tej samej liczby bajtów).źródło
Galaretka , 11 bajtów
Wypróbuj online!
Jak to działa
źródło
JavaScript (ES6),
72717069 bajtówJest to funkcja rekurencyjna, która przyjmuje liczbę cyfr x . Drugi parametr y , początkowo ustawiony na pusty ciąg, śledzi liczbę, gdy generujemy ją cyfra po cyfrze.
Najpierw musimy wygenerować losowy cyfrowy Z. z
Math.random()*10|0
. Teraz chcemy sprawdzić, czy y nie zawiera z , i czy y i z nie są równe 0 .Możemy obliczyć pierwszy warunek za pomocą
!y.match(z)
.y.match(z)
zwraca tablicę (zawsze prawdę), jeśli y zawiera z , w przeciwnym razie null (fałsz);!
zamienia to wartość logiczną i odwraca ją.Drugi warunek jest sprawdzany za pomocą
y|z
. Chociaż y jest łańcuchem, JS domyślnie przekształca go na liczbę całkowitą podczas używania|
. Jest to dodatnia liczba całkowita, jeśli y zawiera już cyfry, w przeciwnym razie 0 . Wynik netto jest taki, żey|z
zwraca 0, jeśli y jest puste, a z wynosi 0 , w przeciwnym razie dodatnia liczba całkowita.Jeśli oba te warunki są spełnione, wówczas dodajemy cyfrę do y , zmniejszamy x i rozpoczynamy proces od nowa. W przeciwnym razie po prostu wracamy do początku i mamy nadzieję, że następna losowa cyfra zadziała. Gdy x osiągnie wartość 0 , po prostu zwracamy pusty ciąg znaków, aby zakończyć rekurencję.
Poprzednia wersja:
Jest to funkcja rekurencyjna, która przyjmuje liczbę cyfr. Pierwotnie niezdefiniowany drugi parametr y to 10-bitowa tabela odnośników, która informuje nas, które cyfry już mamy, wygodnie przechowywane jako liczby całkowite.
Najpierw musimy wygenerować losowy cyfrowy Z. z
Math.random()*10|0
. Teraz chcemy sprawdzić, czy z „th najmniej znaczący bit y nie jest ustawiona, a y i z nie są zarówno 0 .Możemy obliczyć pierwszy warunek za pomocą
~y>>z&1
; odwróć y , przesuń go z bitów w prawo i weź tylko najmniej znaczący bit. Daje to 1, jeśli nie wygenerowaliśmy jeszcze danej cyfry, lub 0 w przeciwnym razie.Drugi warunek był początkowo dość trudny do zrozumienia (próbowałem
y/z
na początku wygenerować,NaN
jeśli oba są równe 0), ale w pewnym momencie zdałem sobie sprawę, że to po prostu wystarczyy|z
. Wynik wynosi 0, jeśli zarówno y, jak i z są równe 0 ; w przeciwnym razie dodatnia liczba całkowita.Jeśli oba te warunki są spełnione (
~y>>z&1&&y|z
), wówczas generujemy resztę liczby i poprzedzamy z . Reszta numeru jest generowana przez ponowne wywołanie funkcji za pomocąx-1
iy|1<<z
( y , ale z bitem o indeksie z ustawionym na 1 ). Kiedy x osiągnie wartość 0 , po prostu zwracamy pusty ciąg znaków, aby zakończyć rekurencję.źródło
ClojureScript,
8179 bajtówJest to anonimowa funkcja, więc musisz użyć jej w następujący sposób:
Gdzie zastępujesz
{arguments}
argumentami.Możesz wypróbować kod tutaj (ClojureScript REPL).
Dzięki
@cliffroot
za wygaszenie 2 bajtów!Rozszerzony kod:
Wyjaśnienie:
Będę przeglądać wiersze jeden po drugim, używając przykładowego wejścia
8
.Całkiem proste, definiuje funkcję za
random-digits
pomocą jednego wywołanego argumentun
. W mojej odpowiedzi użyłem anonimowej funkcji (#(...)
), aby zapisać bajty.Przyjrzyjmy się wewnątrz
let
, od wewnątrz:W ClojureScript (i Clojure)
(range n)
jest podobny do Pythonarange(n)
: daje listę z każdą liczbą od0
don - 1
(9
w tym przypadku).shuffle
pobiera listę i zwraca wektor (który nieco różni się od listy) z tasowaniem wszystkich jego elementów. Korzystając z naszego przykładu, otrzymujemy coś takiego:(subvec vector start end)
pobiera wektor (tylko wektor) i zwraca wektor, który ma wszystkie elementy od indeksustart
doend
. W tym przypadku bierzemy elementy z0
elementu th do podanego argumenturandom-digits
. Jeśli zastosujemy to do naszego przykładu, otrzymamy:To
if
instrukcja sprawdza, czy pierwszym elementemnum-vector
jest0
.Jeśli to jest
0
, to wywołujemy funkcję ponownie z argumentemn
, używającrecur
.Jeśli nie jest to
0
:(apply function list)
pobiera listę i umieszcza je w funkcji jako argumenty. Na przykład:Przemienia się w:
Co równa się
9
.(str items)
zamienia każdy element witems
ciąg, a następnie łączy je.int
konwertuje wszystko na liczbę całkowitą. Jeśli zastosujemy to do naszego przykładu, otrzymamy:Co jest naszą ostateczną odpowiedzią.
źródło
(int string)
zamiast(Integer/parseInt string)
:)read-string
w Clojure, ale nie jest to o wiele lepsze ...#(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))
przemieszczaapply str
część na końcu, umożliwia porównanie się0
zamiast\0
i zastosowaniasubvec
zamiasttake
pozwala na wykorzystanie wektora jako funkcję i aby usunąćfirst
shuffle
zmienił kolekcję wvec
. Dzięki! Będę jednak musiał napisać nowe wyjaśnienie ...Python 2,
898180 bajtówWypróbuj online
źródło
99**n
, żeby mieć pewność, że dostanę je wszystkie. : Dif`set(`i`)`[5*n:]]
.R, 45 bajtów
źródło
k=0
ponieważ jest to domyślny wektor długości 1, i możesz użyć i = scan (), aby pobrać dane wejściowe ze standardowego wejścia jako liczby. Nie jestem również pewien, czy lista cyfr jest „poprawnym” zgłoszeniem, ale nie jestem sędzią.while(!k[1])
zadziałałoby zapisanie 2 bajtów?Narzędzia Bash + GNU, 46
Wypróbuj online .
To zajmuje dużo czasu dla większego n - około 30s dla n = 7 i rośnie 10 razy dla każdego przyrostu, więc prawdopodobnie 8-9 godzin dla n = 10.
źródło
Java 7,
150147145134 bajtów-2 bajty dzięki @TheLethalCoder
(stary) Objaśnienie:
Kod testowy:
Wypróbuj tutaj.
Przykładowe dane wyjściowe:
źródło
n->...
czy to jest Java 8+?for(int l,x;(l=r.length())<n;)
a więc powinieneś zapisać bajt.n->...
jest Java 8. Osobiście wolę kodegolfa w Javie 7, mimo że 8 jest zawsze krótsza.Perl 6 , 44 bajtów
Spróbuj
Rozszerzony:
źródło
PHP, 67 bajtów
Wersja online
Wszystkie wersje bazują na losowaniu cyfr od 0 do 9
71 bajtów
73 bajtów
źródło
MATL , 15 bajtów
Wypróbuj w MATL Online!
Wyjaśnienie
źródło
Galaretka , 12 bajtów
Obecnie jeden bajt za moją drugą odpowiedzią na żelki, ale naprawdę podoba mi się ten.
Wypróbuj online!
Jak to działa
źródło
APL (Dyalog) ,
271917 bajtówWymaga
⎕IO←0
ustawienia domyślnego w wielu systemach.Wypróbuj online!
Tasuje cyfry, aż będą ważne:
10⊥
dekodować z 10 cyfr podstawowych na zwykły numer,⊢
następnie↑
pierwsze elementy{
...}⍣{
...}
powtarzając funkcję ...?⍨10
przetasować pierwsze dziesięć całkowite dodatnieaż ...
⊃⍺
pierwsza cyfra z ostatniej próby×
jest dodatniźródło
Python 2 ,
100939290 bajtówDzięki @ mbomb007 za golenie 2 bajtów
Próbuje liczby w wymaganym miejscu, dopóki nie zostaną znalezione z unikalnymi cyframi. Założę się, że jest o wiele czystszy sposób na zrobienie tego, ale nikt nie przychodzi mi do głowy.
źródło
return(n==len(set(`k`)))*k or f(n)
. Wypróbuj onlinePyth , 11 bajtów
Używa tego samego algorytmu, co odpowiedź Dennisa .
Wypróbuj online!
źródło
Perl, 48 bajtów
Wyjaśnienie:
Wielokrotnie generuj losowe liczby całkowite od 1 do 10 ** $ n-1, odrzucając je, dopóki nie będzie jednej z prawidłowej długości (czyli co najmniej 10 ** ($ n-1)) bez powtarzających się cyfr.
źródło
Partia, 156 bajtów
x
zachowuje maskę bitową używanych cyfr.f
wskazuje liczbę dostępnych cyfr (odliczanie od 9). Cyfry losowe są generowane do momentu znalezienia nieużywanej cyfry.n=10
może być obsługiwany dla 165 bajtów:(
r
zawiera dodatkowe wiodące zero, ponieważ w ten sposób jest bardziej golfowy.) Poprzednie podejście do 165 bajtów, w szczególności pierwsza cyfra, a także działało zn=10
(wersja numeryczna faktycznie zajęła 166 bajtów!):Oryginalne podejście do 170 bajtów działało również dla
n=10
:Używa manipulacji ciągiem w celu wykrycia zduplikowanych cyfr.
źródło
Bash , 66 bajtów
Wypróbuj online!
Mówiąc wprost, używa shuf, xargs służy do łączenia linii i kontynuuje próbę, podczas gdy kombinacja zaczyna się od 0.
Nie mogę pokonać 46 znaków z innej odpowiedzi, ale dlatego jest szybki!
źródło
Pyth,
1528 bajtówWypróbuj tutaj
źródło
0
, więc myślę, że będziesz chciał zmienić^TttQ
na^TtQ
(-1 bajt, premia!). 2) wszystkie cyfry na wyjściu muszą być unikalne, więc będziesz musiał jakoś to wymusić.C #,
127132128126125 bajtówWypróbuj online!
Borrowed the idea from @KevinCruijssen's answer to initialise the random,
r
, in theif
statement to save 2 bytes.Pretty sure this can be golfed further but I don't have time at the moment.
Old version using a
while
loop:źródło
0
, to najpierw spróbowaćif(s.Length<1&r>0)
co jest fałszywe, ale to będzie zrobićif(!s.Contains(r+""))
, co jest prawdą, a jeszcze Dołącz"0"
dos
jako pierwszą cyfrę..Next(10)
... z;
. Więc nie ma dalszych ulepszeń, ale dobry pomysł.n=>{var s="";for(int l=0,r;l<n;l=s.Length)if((l<1&(r=new System.Random().Next(10))>0)|(l>0&!s.Contains(r+"")))r+=x;return s;};
:)C (gcc),
123122100951041039997 bytesThis one generating an actual random number
Try it online!
C (gcc),
8785 bytesHere it is printing a string of digits.
Try it online!
źródło
PHP,
6563 bytestakes input from STDIN; run with
-nR
.create random number between
1
and10^N
inclusive;repeat while count of distinct characters is <
N
.źródło
while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;
-2 BytesMathematica
6560 BytesHere is a faster version but adds 9 bytes:
źródło
Java 9 JShell, 86 bytes
Try it online!
Note: I'm not counting the imports as those packages are imported by default in JShell, but there's no Try-it-online link that I know of for JShell, so I've provided one for Java 9 with header and footer code to make it work in that context. In JShell you can just do:
And then:
How it works:
We define a function from Integer to Long and create an infinite stream of random longs in the range from 0-9, limit it to the first n-1 items, then reduce it with a random int from 1-9 as the initial value and a function that multiplies the value by 10 and adds the next value from the stream.
I used longs so this should work for up to about 18 digits (n = 18).
źródło
C,
9693 bytesFisher-Yates shuffle initialization until the first digit isn't zero.
Is uniform, assuming
rand()%i
is uniform. (Since for most iRAND_MAX/i
leaves a small remainder, there is a very small bias. This bias grows smaller as RAND_MAX grows larger.)See it work online.
See it generate correct numbers for when n equals 2, as shown in the question.
źródło
Axiom, 191 bytes
ungolf it, test result
źródło
Jellyfish, 17 bytes
Try it online!
Fork of Dennis' Jelly answer.
źródło
Ruby,
5352 bytesShuffle until the first digit is not 0, then combine the digits and convert to an integer.
Try it online!
źródło