Uzyskaj losową liczbę n cyfr z wyraźnymi cyframi, a najpierw nie zero

22

Przeczytałem to pytanie i pomyślałem, że będzie to niezłe wyzwanie.

Zadanie

Podaj dane wejściowe, aby 0<n<10wygenerować losową liczbę z

  • dokładnie n cyfr
  • pierwszy nie 0
    • więc f(n)>10**(n-1)-1
  • wyraźne cyfry

Kryteria wygranej

To jest 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=2to:

[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]
Roman Gräf
źródło
4
Należy unikać
flawr
zwraca jako liczbę całkowitą, a nie ciąg, tak?
Giuseppe,
@Giuseppe generuje liczbę losową
mbomb007 24.04.17
4
Myślę o tym za każdym razem, gdy ktoś zadaje losowe pytanie liczbowe xkcd.com/221
Thunda,
1
@ ais523 "Podaj wartość wejściową 0 <n <10 wygeneruj liczbę losową za pomocą"
cleblanc

Odpowiedzi:

17

Python 2 , 77 bajtów

from random import*
r=range(10)
while[1]>r:shuffle(r)
print`r`[1:input()*3:3]

Wypróbuj online!

Tasuje listę 10 cyfr, aż nie zacznie się od 0, a następnie tworzy liczbę z pierwszymi ncyframi na liście.

xnor
źródło
Zdecydowanie działa szybciej i ma mniej pamięci na wprowadzanie 9lub 10.
mbomb007
Schludne rozwiązanie! Czy możesz wyjaśnić, w jaki sposób [1::3]działa konwersja go z listy do ciągu? Nigdy wcześniej tego nie widziałem.
Julian Wolf
@JulianWolf Działa tylko wtedy, gdy każdy element listy ma taką samą długość. W rzeczywistości pobiera ciąg znaków reprezentujący listę, a następnie kroi go, biorąc co trzeci znak po pominięciu pierwszego [.
mbomb007
@JulianWolf [1::3]pobiera znak o indeksie 1, a następnie co trzeci. To [1, 2, 3]daje 123, pomijając nawiasy klamrowe, przecinki i spacje.
Dennis
Strzelaj, dobrze - to ma sens. Ja zapominając, że [1, 2, 3]już stringified i że przecinki i spacje potrzebne pomijam. Dzięki!
Julian Wolf
10

Brachylog , 9 10 bajtów

{~lℕ₁≜≠}ᶠṛ

Wypró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

{~lℕ₁≜≠}ᶠṛ
{      }ᶠṛ  Pick a random value with these properties:
 ~l           it has length equal to the input;
   ℕ₁         it's a positive integer;
     ≜        it's a specific value (not a constraint);
      ≠       all its elements (digits in this case) are different.

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

~lℕ₁≠≜ᶠṛ

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
Zamierzałem opublikować rozwiązanie, ≜₁zanim zdałem sobie sprawę, że zostało dodane z powodu tego wyzwania
Niepowiązany ciąg
8

Galaretka , 9 bajtów

⁵*ṖQL$€MX

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:

⁵*ṖQL$ÐṀX

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

⁵*ṖQL$€MX - Main link: n                       e.g. 2
⁵         - literal 10
 *        - exponentiate: 10^n                      100
  Ṗ       - pop (make range 1 to 10^n, then pop)    [1  ,2  ,...,21   ,22 ,23   ,...,97   ,98   ,99]
     $€   - last two links as a monad for €ach:
   Q      -   unique (makes a decimal list first)   [[1],[2],...,[2,1],[2],[2,3],...,[9,7],[9,8],[9]]
    L     -   length                                [1  ,1  ,...,2    ,1  ,2    ,...,2    ,2    ,1  ]
       M  - indexes of maximal elements             [        ...,21       ,23,   ...,97   ,98       ]
          -                                         - i.e. all n-digit numbers with n-distinct digits.
        X - pick a random element from that list

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).

Jonathan Allan
źródło
Och wow. Próbowałem czegoś bardzo podobnego do tego, ale nie udało mi się zapisać wartości do zwrócenia w indeksach listy (poprzez odpowiednie wypełnienie listy), zamiast próbować przechowywać je osobno. Jest to sztuczka, która dość często przydaje się w Galaretce i zawsze wydaje mi się, że jej brakuje.
7

Galaretka , 11 bajtów

9Xœ|⁵ḶẊ¤ḣ¹Ḍ

Wypróbuj online!

Jak to działa

9Xœ|⁵ḶẊ¤ḣ¹Ḍ  Main link. Argument: n

9            Set the return value to 9.
 X           Pick; pseudo-randomly select an integer from [1, ..., 9].
       ¤     Combine the three preceding links into a niladic chain.
    ⁵          Yield 10.
     Ḷ         Unlength; yield [0, ..., 9].
      Ẋ        Shuffle; pseudo-randomly select a permutation of [0, ..., 9].
  œ|         Multiset OR; prepend the selected integer to the selected permutation
             and remove the second occurrence of the first element.
         ¹   Identity; yield n.
        ḣ    Head; keep the first n digits of the permutation.
          Ḍ  Undecimal; convert from base 10 to integer.
Dennis
źródło
To bardzo sprytny sposób na usunięcie duplikatu ...
Leaky Nun
7

JavaScript (ES6), 72 71 70 69 bajtów

f=(x,y="")=>x?!y.match(z=Math.random()*10|0)&&y|z?f(x-1,y+z):f(x,y):y

Jest 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, że y|zzwraca 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:

f=(x,y)=>x?~y>>(z=Math.random()*10|0)&1&&y|z?z+f(x-1,y|1<<z):f(x,y):""

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/zna początku wygenerować, NaNjeśli oba są równe 0), ale w pewnym momencie zdałem sobie sprawę, że to po prostu wystarczy y|z. Wynik wynosi 0, jeśli zarówno y, jak i zró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-1i y|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ę.

ETHprodukcje
źródło
5

ClojureScript, 81 79 bajtów

#(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))

Jest to anonimowa funkcja, więc musisz użyć jej w następujący sposób:

(#(...) {arguments})

Gdzie zastępujesz {arguments}argumentami.

Możesz wypróbować kod tutaj (ClojureScript REPL).

Dzięki @cliffrootza wygaszenie 2 bajtów!


Rozszerzony kod:

(defn random-digits [n]
  (let [num-vector
        (subvec
          (shuffle (range 10))
          0 n)]
    (if (= (num-vector 0) 0)
      (recur n)
      (int (apply str num-vector)))))

Wyjaśnienie:

Będę przeglądać wiersze jeden po drugim, używając przykładowego wejścia 8 .


(defn random-digits [n] ...)

Całkiem proste, definiuje funkcję za random-digitspomocą jednego wywołanego argumentun . W mojej odpowiedzi użyłem anonimowej funkcji ( #(...)), aby zapisać bajty.


(let [num-vector ...] ...)

Przyjrzyjmy się wewnątrz let, od wewnątrz:

(shuffle (range 10))

W ClojureScript (i Clojure) (range n)jest podobny do Pythona range(n): daje listę z każdą liczbą od0 do n - 1( 9w tym przypadku).

shufflepobiera 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:

[1 0 8 3 6 7 9 2 4 5]

(subvec {see above} 0 n)

(subvec vector start end)pobiera wektor (tylko wektor) i zwraca wektor, który ma wszystkie elementy od indeksu startdo end. W tym przypadku bierzemy elementy z 0elementu th do podanego argumentu random-digits. Jeśli zastosujemy to do naszego przykładu, otrzymamy:

[1 0 8 3 6 7 9 2]

(if (= (num-vector 0) 0)
  (recur n)
  (int (apply str num-vector)))

To if instrukcja sprawdza, czy pierwszym elementem num-vectorjest 0.

Jeśli to jest 0 , to wywołujemy funkcję ponownie z argumentem n, używając recur.

Jeśli nie jest to 0:


(int (apply str num-vector))

(apply function list)pobiera listę i umieszcza je w funkcji jako argumenty. Na przykład:

(apply + [2 3 4])

Przemienia się w:

(+ 2 3 4)

Co równa się 9.

(str items)zamienia każdy element w itemsciąg, a następnie łączy je.intkonwertuje wszystko na liczbę całkowitą. Jeśli zastosujemy to do naszego przykładu, otrzymamy:

   (int (apply str [1 0 8 3 6 7 9 2]))
=> (int (str 1 0 8 3 6 7 9 2))
=> (int "10836792")
=> 10836792

Co jest naszą ostateczną odpowiedzią.

clismique
źródło
2
Uwielbiam ClojureScript za pozwolenie (int string)zamiast (Integer/parseInt string):)
Cliffroot 25.04.17
1
@cliffroot Mam na myśli, że możesz to zrobić read-stringw Clojure, ale nie jest to o wiele lepsze ...
clismique
2 bajty zapisane #(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))przemieszcza apply strczęść na końcu, umożliwia porównanie się 0zamiast \0i zastosowania subveczamiast takepozwala na wykorzystanie wektora jako funkcję i aby usunąćfirst
cliffroot
@cliffroot Huh, nie wiedziałem, że shufflezmienił kolekcję w vec. Dzięki! Będę jednak musiał napisać nowe wyjaśnienie ...
clismique
5

Python 2, 89 81 80 bajtów

from random import*
lambda n:choice([i for i in range(10**n)if`set(`i`)`[5*n:]])

Wypróbuj online

mbomb007
źródło
Nie sądzę, że potrzebujesz wartości początkowej dla tego zakresu.
Dennis
Miły! To spowolni. : D Szkoda, że ​​nie mogę użyć generatora zamiast listy.
mbomb007
Tylko o 11%. Wrzuć wiadro do golfa kodu.
Dennis
Tak, powinienem użyć 99**n, żeby mieć pewność, że dostanę je wszystkie. : D
mbomb007 24.04.17
Patrzyłem na robienie tego w ten sposób, ale dostałem 80, używając if`set(`i`)`[5*n:]].
Jonathan Allan
5

R, 45 bajtów

k=0
i=scan()
while(!k[1])k=sample(0:9)[1:i]
k
Neil
źródło
Myślę, że możesz po prostu ustawić, k=0ponieważ 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ą.
Giuseppe,
@Giuseppe Dzięki za wkład, zaktualizowałem obie sugestie (na obu postach), dzięki.
Neil,
Czy while(!k[1])zadziałałoby zapisanie 2 bajtów?
BLT
@BLT Zaktualizowano, dziękuję.
Neil,
3

Narzędzia Bash + GNU, 46

seq 1e$[$1-1] 1e$1|egrep -v '(.).*\1'|shuf -n1

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.

Cyfrowa trauma
źródło
na pytanie, n = 10 nawet nie musi działać, a tym bardziej być szybkim
ysth
3

Java 7, 150 147 145 134 bajtów

String c(int n){String r="";for(int l,x;(l=r.length())<n;)if(l<1&(x=(int)(Math.random()*10))>0|(l>0&!r.contains(""+x)))r+=x;return r;}

-2 bajty dzięki @TheLethalCoder

(stary) Objaśnienie:

String c(int n){                           // Method with integer parameter and String return-type
  String r="";                             //  Result-String
  for(int l=0,x;l<n;l=r.length()){         //  Loop until the length of the result-String is equal to the parameter integer
    x=new java.util.Random().nextInt(10);  //   Random digit
    if((l<1&x>0)                           //   If the length is zero and the random digit is not zero
       |(l>0&!r.contains(""+x)))           //     or the length is at least 1, and the result-String does not contain this random digit yet
      r+=x;                                //    Append the random digit to the result-String
  }                                        //  End of for-loop
  return r;                                //  Return result-String
}                                          // End of method

Kod testowy:

Wypróbuj tutaj.

class M{
  String c(int n){String r="";for(int l,x;(l=r.length())<n;)if(l<1&(x=(int)(Math.random()*10))>0|(l>0&!r.contains(""+x)))r+=x;return r;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c(4));
    System.out.println(m.c(10));
  }
}

Przykładowe dane wyjściowe:

7194
8672953041
Kevin Cruijssen
źródło
Nie możesz tutaj użyć wyrażenia lambda ? tj. n->...czy to jest Java 8+?
TheLethalCoder
1
Możesz także pożyczyć lewę, której właśnie użyłem w mojej odpowiedzi, ustawić długość w kontroli porównania, for(int l,x;(l=r.length())<n;)a więc powinieneś zapisać bajt.
TheLethalCoder
1
@TheLethalCoder Ach, oczywiście, dzięki. Świetna praca zespołowa! ;) Tak, n->...jest Java 8. Osobiście wolę kodegolfa w Javie 7, mimo że 8 jest zawsze krótsza.
Kevin Cruijssen
2

Perl 6 , 44 bajtów

{(->{+[~] (^10).pick($_)}...*>9 x$_-1).tail}

Spróbuj

Rozszerzony:

{  # bare block with implicit parameter 「$_」
  (

    ->{  # pointy block lambda with no parameters

      +                # turn the following into a numeric
      [~]              # concatenate the following

        (^10).pick($_) # grab $_ digits at random from 0..9
    }

    ...                # keep doing that until

    * > 9 x $_-1       # one of them is big enough

  ).tail # return the last one (only valid one)
}
Brad Gilbert b2gills
źródło
2

PHP, 67 bajtów

Wersja online

Wszystkie wersje bazują na losowaniu cyfr od 0 do 9

for($a=range(0,9);!$a[0];)shuffle($a);for(;$i<$argn;)echo$a[+$i++];

71 bajtów

for($s="0123456789";!$s[0];)$s=str_shuffle($s);echo substr($s,0,$argn);

73 bajtów

for($a=range(0,9);!$a[0];)shuffle($a);echo join(array_slice($a,0,$argn));
Jörg Hülsermann
źródło
2

MATL , 15 bajtów

`4Y2GZr1)48=]8M

Wypróbuj w MATL Online!

Wyjaśnienie

`        % Do...while
  4Y2    %   Push predefined literal '0123456789'
  G      %   Push input n
  Zr     %   Random sample of n unique characters from that string
  1)     %   Pick the first
  48=    %   Is it 48? This is the loop condition
]        % End. If top of the stack evaluates to true: next iteration
8M       % Push the latest random sample. Implicitly display
Luis Mendo
źródło
2

Galaretka , 12 bajtów

9×!X+!Œ?’ḣƓḌ

Obecnie jeden bajt za moją drugą odpowiedzią na żelki, ale naprawdę podoba mi się ten.

Wypróbuj online!

Jak to działa

9×!X+!Œ?’ḣƓḌ  Main link. No arguments.

9             Set the argument and the return value to 9.
  !           Yield 9!
 ×            Compute 9 × 9!.
   X          Pick; pseudo-randomly select an integer j from [1, ..., 9 × 9!].
     !        Yield 9!
    +         Compute k := j + 9!.
              The result will belong to [9! + 1, 10!].
      Œ?      Get the permutation P of R := [1, ..., r], with minimal r, such that
              P is the lexicographically k-th permutation of R.
              Since k belongs to [9! + 1, 10!], r = 10 and this generates a per-
              mutation between [2,1,3,4,5,6,7,8,9,10] and [10,9,8,7,6,5,4,3,2,1].
        ’     Subtract 1 from all integers in P.
          Ɠ   Read an integer n from STDIN and yield it.
         ḣ    Head; keep the first n digits of the permutation.
           Ḍ  Undecimal; convert from base 10 to integer.
Dennis
źródło
2

APL (Dyalog) , 27 19 17 bajtów

Wymaga ⎕IO←0ustawienia domyślnego w wielu systemach.

10⊥⊢↑{?⍨10}⍣{×⊃⍺}

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 dodatnie
aż ...
⊃⍺ pierwsza cyfra z ostatniej próby
× jest dodatni

Adám
źródło
1

Python 2 , 100 93 92 90 bajtów

Dzięki @ mbomb007 za golenie 2 bajtów

from random import*
def f(n):k=randint(10**~-n,10**n-1);return(n==len(set(`k`)))*k or f(n)

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.

Julian Wolf
źródło
return(n==len(set(`k`)))*k or f(n). Wypróbuj online
mbomb007 24.04.17
1

Pyth , 11 bajtów

jk<{+OS9.ST
jk<{+OS9.STQ implicit Q

       9     9
      S      [1,2,3,4,5,6,7,8,9]
     O       random element

          T  10
        .S   random permutation of [0,1,2,3,4,5,6,7,8,9]

    +        add the results from the previous two paragraphs together
   {         deduplicate
  <        Q first (input) elements
jk           join by empty string

Używa tego samego algorytmu, co odpowiedź Dennisa .

Wypróbuj online!

Leaky Nun
źródło
1

Perl, 48 bajtów

1until$_=1+int rand 10**$n-1,/.{$n}/&&!/(.).*\1/

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.

ysth
źródło
1

Partia, 156 bajtów

@set/af=9,r=x=0
@for /l %%i in (1,1,%1)do @call:c
@echo %r%
@exit/b
:c
@set/a"d=9-%random%%%f,e=x>>d&1
@if %e%==1 goto c
@set/a"r=r*10+d,f=10,x|=1<<d

xzachowuje maskę bitową używanych cyfr. fwskazuje liczbę dostępnych cyfr (odliczanie od 9). Cyfry losowe są generowane do momentu znalezienia nieużywanej cyfry. n=10może być obsługiwany dla 165 bajtów:

@set/af=9,r=x=0
@for /l %%i in (1,1,%1)do @call:c
@echo %r:~1%
@exit/b
:c
@set/a"d=9-%random%%%f,e=x>>d&1
@if %e%==1 goto c
@set r=%r%%d%
@set/a"f=10,x|=1<<d

( rzawiera 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 z n=10(wersja numeryczna faktycznie zajęła 166 bajtów!):

@set/ar=%random%%%9+1,x=0
@for /l %%i in (2,1,%1)do @set/a"x|=1<<d"&call:c
@echo %r%
@exit/b
:c
@set/a"d=%random%%%10,e=x>>d&1
@if %e%==1 goto c
@set r=%r%%d%

Oryginalne podejście do 170 bajtów działało również dla n=10:

@set/ar=%random%%%9+1
@for /l %%i in (2,1,%1)do @call:c
@echo %r%
@exit/b
:c
@set/ad=%random%%%10
@call set s=%%r:%d%=%%
@if not "%s%"=="%r%" goto c
@set r=%r%%d%

Używa manipulacji ciągiem w celu wykrycia zduplikowanych cyfr.

Neil
źródło
1

Bash , 66 bajtów

a=0;while [[ $a == 0* ]];do a=`shuf -i0-9 -n$1|xargs`;done;echo $a

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!

marcosm
źródło
1

Pyth, 15 28 bajtów

=+YhO9VtQ#KOTI!hxYK=+YKB;jkY

Wypróbuj tutaj

Maria
źródło
1
Witamy w PPCG i świetna robota, posługując się językiem golfowym od samego początku :-) Widzę 2 małe problemy: 1) wydaje się, że druga cyfra jest zawsze 0, więc myślę, że będziesz chciał zmienić ^TttQna ^TtQ(-1 bajt, premia!). 2) wszystkie cyfry na wyjściu muszą być unikalne, więc będziesz musiał jakoś to wymusić.
ETHprodukcje
@ETHproductions Arg !! Dzięki za zwrócenie na to uwagi. Naprawiłem to.
Maria,
1

C #, 127 132 128 126 125 bajtów

n=>{var s="";for(int l,r;(l=s.Length)<n;)if((l<1&(r=new System.Random().Next(10))>0)|(l>0&!s.Contains(r+"")))s+=r;return s;};

Wypróbuj online!

Borrowed the idea from @KevinCruijssen's answer to initialise the random, r, in the if 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:

n=>{var s="";while(s.Length<n){int r=new System.Random().Next(10);if(s.Length<1&r>0)s+=r;else if(!s.Contains(r+""))s+=r;}return s;};
TheLethalCoder
źródło
Nie sądzę, żeby to było poprawne. Powiedzmy, że pierwsza liczba całkowita jest przypadkowy 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"do sjako pierwszą cyfrę.
Kevin Cruijssen
@KevinCruijssen Naprawiono i kontynuowano
grę w
1
@KevinCruijssen Ah Rozpracowałem to, w twoim przykładzie nie kończysz .Next(10)... z ;. Więc nie ma dalszych ulepszeń, ale dobry pomysł.
TheLethalCoder
1
I have just posted it. And oops, you're right I missed that semi-colon.. You can still golf it like this though: 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;}; :)
Kevin Cruijssen
1
@KevinCruijssen I just borrowed the idea from your answer as you was writing that comment! Nice improvement thanks
TheLethalCoder
1

C (gcc), 123 122 100 95 104 103 99 97 bytes

This one generating an actual random number

j;f(n){for(int i,k=n,s[10]={j=0};n;s[i+=i?0:k==n]=!s[i]?j+=i*pow(10,--n):1)i=rand()%10;return j;}

Try it online!

C (gcc), 87 85 bytes

Here it is printing a string of digits.

f(n){for(int i,k=n,s[10]={0};n;s[i+=i?0:k==n]=!s[i]?--n,putchar(48+i):1)i=rand()%10;}

Try it online!

cleblanc
źródło
1

PHP, 65 63 bytes

while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;

takes input from STDIN; run with -nR.

create random number between 1 and 10^N inclusive;
repeat while count of distinct characters is < N.

Titus
źródło
1
while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x; -2 Bytes
Jörg Hülsermann
0

Mathematica 65 60 Bytes

0For[a=11,Max@DigitCount@a>1,a=RandomInteger[10^{#-1,#}]]+a&

Here is a faster version but adds 9 bytes:

FromDigits@Join[f=(s=RandomSample)[r=Range@9,1],s[r/.f[[1]]->0,#-1]]&
Kelly Lowder
źródło
0

Java 9 JShell, 86 bytes

n->new Random().longs(0,10).limit(n-1).reduce(new Random().nextInt(9)+1,(a,b)->a*10+b)

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:

jshell> Function<Integer,Long> f =
   ...> n->new Random().longs(0,10).limit(n-1).reduce(new Random().nextInt(9)+1,(a,b)->a*10+b)
f ==> $Lambda$27/633070006@5702b3b1

And then:

jshell> f.apply(6)
$26 ==> 746202

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).

David Conrad
źródło
0

C, 96 93 bytes

f(n){char d[11],i=0,r;for(;i++^10;d[i-1]=d[r=rand()%i],d[r]=47+i);*d^48?d[n]=0,puts(d):f(n);}

Fisher-Yates shuffle initialization until the first digit isn't zero.

Is uniform, assuming rand()%i is uniform. (Since for most i RAND_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.

2501
źródło
0

Axiom, 191 bytes

g(a:NNI):Complex INT==(a<1 or a>9=>%i;r:List NNI:=[];b:=a;repeat(a=0=>break;d:=random()$INT rem 10;a=b and d=0=>0;~member?(d,r)=>(a:=a-1;r:=cons(d,r)));reduce(+,[r.i*10^(i-1)for i in 1..#r]))

ungolf it, test result

-- Return one number of 'a' different random digits if 0<a<10
f(a:NNI):Complex INT==
    a<1 or a>9=>%i
    r:List NNI:=[];b:=a
    repeat
       a=0=>break
       d:=random()$INT rem 10
       a=b and d=0  =>0
       ~member?(d,r)=>(a:=a-1;r:=cons(d,r))
    reduce(+,[r.i*10^(i-1)for i in 1..#r])

(4) -> [[i,g(i)] for i in 0..10]
   (4)
   [[0,%i], [1,9], [2,76], [3,135], [4,6810], [5,48675], [6,415768],
    [7,7461539], [8,98421537], [9,825046739], [10,%i]]
                                          Type: List List Complex Integer
(5) -> [[i,g(i)] for i in [3,3,3,3,3,3,3,3,3]]
   (5)
   [[3,653],[3,128],[3,254],[3,268],[3,914],[3,594],[3,276],[3,240],[3,398]]
RosLuP
źródło
0

Ruby, 53 52 bytes

Shuffle until the first digit is not 0, then combine the digits and convert to an integer.

->n{a=*0..9;a.shuffle!while a[0]==0;eval a[0,n]*''}

Try it online!

Value Ink
źródło