Losowość to dobra zabawa. Wyzwania bez sensu są zabawne.
Napisz funkcję, która, biorąc pod uwagę całkowitą wejście n
, wyjście wola do zestawu (nieuporządkowana, niepowtarzalny) z dokładnie n
losowych liczb całkowitych między 1
a n^2
(włącznie) takich, że suma wszystkich liczb całkowitych jest równy n^2
.
Losowość nie musi być jednorodna, pod warunkiem że każdy prawidłowy zestaw ma niezerową szansę wystąpienia.
Najkrótsza odpowiedź w bajtach (na każdy język) wygrywa.
Przykłady
Input (n) = 1, Target (n^2) = 1
Sample of possible outputs:
1
Input = 2, Target = 4
Sample of possible outputs:
3, 1
1, 3
Input = 3, Target = 9
Sample of possible outputs:
6, 1, 2
3, 5, 1
4, 3, 2
Input = 4, Target = 16
Sample of possible outputs:
1, 3, 5, 7
2, 4, 1, 9
8, 3, 1, 4
Input = 5, Target = 25
Sample of possible outputs:
11, 4, 7, 1, 2
2, 3, 1, 11, 8
6, 1, 3, 7, 8
Input = 8, Target = 64
Sample of possible outputs:
10, 3, 9, 7, 6, 19, 8, 2
7, 16, 2, 3, 9, 4, 13, 10
7, 9, 21, 2, 5, 13, 6, 1
Zadanie premiowe: Czy istnieje wzór do obliczania liczby prawidłowych permutacji dla danego n
?
code-golf
random
combinatorics
Skidsdev
źródło
źródło
Odpowiedzi:
Brachylog (v2), 15 bajtów (losowo) lub 13 bajtów (wszystkie możliwości)
Losowy
Wypróbuj online!
Podanie funkcji (widoczne w TIO z opakowaniem czyniącym z niego pełny program).
Wyjaśnienie
Wszystkie możliwości
Wypróbuj online!
Podanie funkcji, które generuje wszystkie możliwe wyniki.
Wyjaśnienie
Jestem dość zaskoczony, że to
∧≜
działa (normalnie musiałbyś pisać∧~≜
, aby brutalnie wymusić wyjście, a nie wejście), ale okazuje się, że≜
ma założenie wejściowe = wyjście, więc nie ma znaczenia, w którą stronę Uruchom.Zadanie premiowe
Aby uzyskać wgląd w sekwencję liczby możliwości, stworzyłem inne opakowanie TIO, które uruchamia program na kolejnych liczbach całkowitych w celu podania sekwencji liczb wyjściowych:
Podróż do OEIS odkrywa, że jest to już znana sekwencja, A107379 , opisana podobnie jak w pytaniu (najwyraźniej otrzymujesz tę samą sekwencję, jeśli ograniczysz ją do liczb nieparzystych). Strona zawiera kilka wzorów dla sekwencji (choć żadna nie jest szczególnie prosta; druga wygląda jak bezpośrednia formuła wartości, ale nie rozumiem zapisu).
źródło
x^(n*(n-1)/2)
rozszerzania szeregowegoProduct_{k=1..n} 1/(1 - x^k)
” (niestety wcale nie bezpośredni)A≠≜₁ᵐ
) Powoduje, że czas wykonywania jest średnio znacznie szybszy.05AB1E , 11 bajtów
Wypróbuj online lub sprawdź wszystkie przypadki testowe .
Wyjaśnienie:
źródło
Python (2 lub 3), 85 bajtów
Wypróbuj online!
źródło
R ,
68, 7548 bajtów (losowo) i 70 bajtów (deterministycznie)@ Metoda próbkowania odrzucenia Giuseppe:
Wypróbuj online!
Oryginał golfa:
Wypróbuj online!
*!!1:2
Firma jest uniknięcie dziwny sposóbsample
działania, gdy pierwszy argument ma długość 1.źródło
p
bezpośrednio jako indeksu zamiast obliczania go i ponowne użycie powinno zaoszczędzić trochę bajtów.function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
48 ...sample(2,1)
co się dziejen=2
. Więcrep
tylko gwarantuje, że tak się nigdy nie stanie. Może być lepszy sposób, ale to było szybkie i byłem wściekłysample
.x*!!1:2
nad,rep(x,2)
jeśli twoje meta-pytanie otrzyma odpowiedź przeczącą.Galaretka , 9 bajtów
Wypróbuj online!
Wygeneruj wszystkie n-kombinacje z listy [1..n²], przefiltruj, aby zachować te z sumą n², a następnie wybierz losową.
źródło
Java 10,
250242222 bajtów-20 bajtów dzięki @nwellnhof .
Uważaj, nadchodzi Java. Jest „tylko” pięć razy tak długo, jak pozostałe cztery odpowiedzi łącznie, więc nieźle jak sądzę… rofl.
To działa
n=1
poprzezn=25
(łącznie) w czasie krótszym niż 2 sekundy, choć, więc prawdopodobnie będę pisać zmodyfikowaną wersję do wersji to wyzwanie prędkości (który jest obecnie jeszcze w Sandbox), jak również.Wypróbuj online.
Wyjaśnienie:
W pseudo-kodzie wykonujemy następujące czynności:
1) Generowanie tablicę wielkości
n+1
zawierający:0
,n
kwadratu, an-1
ilość losowych liczb całkowitych w przedziale[0, n squared)
2) Sortuj tej tablicy
3) tworzą drugą tablicę wielkości
n
zawierający forward różnic parTe pierwsze trzy kroki dadzą nam tablicę zawierającą
n
losowe liczby całkowite (w zakresie[0, n squared)
sumy don
kwadratu.4a) Jeśli nie wszystkie losowe wartości są unikalne lub jedna z nich ma wartość 0: spróbuj ponownie od kroku 1
4b) W przeciwnym razie zwróć tablicę różnic w wyniku
Co do faktycznego kodu:
źródło
n=25
w mniej niż 2 sekundy robi wrażenie! Będę musiał przeczytać wyjaśnienie i zobaczyć, jak to działa. Czy to wciąż metoda bruteforce?[0, n squared)
najpierw uzyskać losowe wartości z zakresu , a następnie oblicza różnice między tymi posortowanymi wartościami losowymi (w tym wiodącymi0
i końcowymin squared
. Więc jestem pewien, że te różnice są również jednolite. Ale znowu , Nie jestem pewien, jak to udowodnić. Jednorodność losowości nie jest tak naprawdę moją wiedzą specjalistycznąd
czy coś mi brakuje?Perl 6 , 41 bajtów
Wypróbuj online!
(1 .. $_²)
to zakres liczb od 1 do kwadratu liczby wejściowej.pick($_)
losowo wybiera odrębny podzbiór tego zakresuxx *
nieskończenie replikuje poprzednie wyrażeniefirst *.sum == $_²
wybiera pierwszy z tych zestawów liczb, który sumuje się do kwadratu liczby wejściowejźródło
Pyth,
1312 bajtówWypróbuj online tutaj . Zauważ, że interpreter online napotyka błąd MemoryError dla danych wejściowych większych niż 5.
Edycja: zapisano bajt, przyjmując alternatywne podejście. Poprzednia wersja:
Of&qQlT{IT./*
źródło
Python 3 ,
136 134 127 121114 bajtówWypróbuj online!
Komentator mnie poprawił, a teraz osiąga maksymalną głębokość rekurencji na f (5) zamiast f (1). Znacznie bliżej bycia prawdziwą konkurencyjną odpowiedzią.
Widziałem to zrobić f (5) jeden raz , a ja pracuję nad próbując wdrożyć to z shuffle.
Próbowałem utworzyć wyrażenia lambda
s=...
, ale to nie pomogło w bajtach. Może ktoś inny może coś z tym zrobić:s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)
Dzięki Kevinowi za golenie kolejnych 7 bajtów.
źródło
f(1)
, jedyną możliwą tablicą, która powinna być generowalna,n=1
jest[1]
również wiele dodatkowych białych spacji do usunięcia tutaj. Pamiętaj, że jest to wyzwanie dla golfa, więc celem jest osiągnięcie najniższej liczby bajtówrange(1,n)
->range(n)
Uważam, że powinien rozwiązać problem.return len(s)==n and sum(s)==n*n and s or f(n)
( Wypróbuj online 114 bajtów ).APL (Dyalog Unicode) , 20 bajtów SBCS
Anonimowy przedrostek lambda.
Wypróbuj online!
{
…}
„Dfn”;⍵
jest argumentem⍵*2
rozwiąż arguments←
przypisać dos
(dla s quare)⍵?
znajdźn
losowe wskaźniki od 1…s
bez zamianyc←
przypisać doc
(dla c iidate)+/
zsumuj jes=
porównać dos
:
jeśli równec
zwrócić kandydata⋄
jeszcze∇⍵
powrócić do argumentuźródło
APL (Dyalog Classic) , 18 bajtów
Wypróbuj online!
wykorzystuje
⎕io←1
⍳
generuje liczby1 2 ... n
(
...)⍣(
...)
stosuj funkcję po lewej stronie, aż funkcja po prawej stronie zwróci wartość true≢
długość, tjn
≢?≢×≢
wybierz losowon
różne liczby całkowite od 1 don
2+.-∘≢
odejmij długość od każdej liczby i sumy0=
jeśli suma wynosi 0, przestań zapętlać, w przeciwnym razie spróbuj ponownieźródło
MATL ,
1813 bajtówWypróbuj online!
źródło
Japt, 12 bajtów
Spróbuj
źródło
à
powinno być w porządku.Java (JDK) , 127 bajtów
Wypróbuj online!
Pętla nieskończona, aż zestaw z kryteriami się dopasuje.
Mam nadzieję, że masz czas, ponieważ jest bardzo powolny! Nie może nawet dojść do 10 bez przekroczenia limitu czasu.
źródło
if(r.size()==n&s==0)
naif(r.size()+s==n)
.s>0
, aby rozmiar mógł być większy niżn
. Ok, w takim przypadku to naprawdę nie działa.n
jest stała, ale niestety zarównos
ir.size()
są zmiennymi, które mogą być zarówno poniżej lub powyżej0
in
odpowiednio.Partia,
182145 bajtówObjaśnienie: Oblicza minimalny i maksymalny dopuszczalny wybór, biorąc pod uwagę, że liczby mają być wybierane w kolejności malejącej, i wybiera losową wartość z zakresu. Przykład danych wejściowych
4
:źródło
JavaScript,
647291261260259251239 bajtówDzięki @Veskah za -10 bajtów w oryginalnej wersji i „Och tak, wyprowadzasz wszystkie zestawy, podczas gdy wyzwanie prosi o zwrócenie losowego”
Wypróbuj online!
Utwórz tablicę
n^2
indeksów opartych na 1, losowo sortuj tablicę, wycinajn
elementy z tablicy. Podczas gdy suma losowych elementów nie jest równan^2
pętli tablicy losowych elementów; jeśli suma elementów tablicy jest większa niż,n^2
a bieżący element-1
nie jest równy zero lub bieżący element-1
nie znajduje się w bieżącej tablicy, odejmij1
; jeśli suma tablicy jest mniejsza niż,n^2
a bieżącego elementu+1
nie ma w tablicy, dodaj1
do elementu. Jeśli suma tablic jest równan^2
pętli przerwania, tablica wyjściowa.źródło
k++
while
pętle prawdopodobnie można by również zredukować do treści pojedynczej funkcji, która akceptuje parametry; i może zastąpićif..else
twierdzenia operatorami warunkowymi (trójskładnikowymi) ; wśród innych części kodu, które można by bardziej niż w przypadku golfa dostosować; ieg, usuwanielet
oświadczeń.if..else
n
?” . testowania jeśli algorytm konsekwentnie zwrócony oczekiwany wynik dlan^2
tablic wyjściowych generowanych w jednym wywołaniu funkcji, jednocześnie biorąc pod uwagę podobieństwa w tej kwestii N N ^ N-wymiarowej macierzy wypełniony N .Japt , 20 bajtów
Wypróbuj online!
Niezwykle mocno wykorzystuje losowość „nierównomierną”, prawie zawsze wypisuje pierwsze
n
liczby nieparzyste, które się sumująn^2
. Teoretycznie może wypisać dowolny inny prawidłowy zestaw, chociaż byłem w stanie to potwierdzić tylko dla małychn
.Wyjaśnienie:
źródło
Rubinowy , 46 bajtów
Wypróbuj online!
źródło
C (gcc) ,
128125 bajtówWypróbuj online!
-3 bajty dzięki pułapce cat
UWAGA: prawdopodobieństwo jest bardzo dalekie od jednolitości. Zobacz wyjaśnienie, co mam na myśli, i lepszy sposób przetestowania, czy to działa (przez zbliżenie dystrybucji do jednolitego [ale nadal daleko od niego]).
W jaki sposób?
Podstawową ideą jest wybieranie tylko rosnących liczb, aby nie martwić się duplikatami. Za każdym razem, gdy wybieramy liczbę, mamy niezerową szansę na „pominięcie”, jeśli jest to dopuszczalne.
x
k
y
x
Niemniej jednak logiką jest szansa na odrzucenie każdego,
y
który spełnia powyższe równanie.Kod
Sztuczka, którą wspomniałem, aby lepiej przetestować kod, polega na zastąpieniu
rand()&&
gorand()%2&&
tak, aby istniało 50-50 szans na pominięcie dowolnego y, a nie 1RAND_MAX
szansa na użycie dowolnego y.źródło
p(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;
zamiast){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
Czysty , 172 bajty
Wypróbuj online!
źródło
Python (2 lub 3), 84 bajtów
Wypróbuj online!
Trafia maksymalną głębokość rekurencji przy około l (5)
źródło
Kotlin , 32 bajty
Wypróbuj online!
źródło
Mathematica 40 bajtów
źródło
RandomChoice@IntegerPartitions[#^2,{#}]&
Wolfram Language (Mathematica) , 49 bajtów
Wypróbuj online!
Wersja w golfa autorstwa @ J42161217.
Wolfram Language (Mathematica) , 62 bajty
Wypróbuj online!
Jak to działa
Głównie na podstawie tego pytania Math.SE . Aby podzielić partycjen2 na n odrębnych części, uzyskaj partycje n2−(n2−n)/2=(n2+n)/2 0⋯n−1 n−1⋯0
Odpowiedź na zadanie premiowe
Tak. Definiowaćpart(n,k) n k
Możesz to zrozumieć jako „Jeśli partycja zawiera 1, usuń ją; w przeciwnym razie odejmij 1 od każdego terminu”. Więcej wyjaśnień tutaj w innym pytaniu Math.SE . W połączeniu z warunkami początkowymipart(n,1)=1 n<k⇒part(n,k)=0
czyli w Mathematica:
Wypróbuj online!
źródło
(While[Tr[s=RandomSample[Range[#^2],#]]!=#^2];s)&