Mnożę źródło, a ty (prawdopodobnie) zwielokrotniasz wynik!

18

Zadanie

Zadanie polega na napisaniu programu, który wypisze spójną, ale poza tym dowolną liczbę całkowitą dodatnią x (tak ściśle większą niż 0). Oto haczyk: gdy źródło jest powtarzane N razy (kod jest dołączany / łączony N1 do siebie), program powinien mieć 1N prawdopodobieństwo wyprowadzeniaNxa pozostałe prawdopodobieństwoN1N wyjściaxniezmienione.

Przykład

Załóżmy, że twoim początkowym źródłem jest XYZliczba całkowita 3. Następnie:

  • Dla N=2 : XYZXYZpowinno wyprowadzać 3 z prawdopodobieństwem 12 (50% czasu) i23=6z prawdopodobieństwem12 również (50% czasu).

  • Dla N=3 : XYZXYZXYZnależy wyprowadzić 3 z prawdopodobieństwem 23 (66,666% czasu) i33=9z prawdopodobieństwem13 (33,333% czasu)

  • Dla N=4 : XYZXYZXYZXYZnależy wyprowadzić 3 z prawdopodobieństwem 34 (75% czasu) i43=12 z prawdopodobieństwem14 (25% czasu)

i tak dalej....

Zasady

  • Musisz zbudować pełny program . Wyjście musi zostać wydrukowane do STDOUT.

  • Twój program powinien teoretycznie wypisywać każdą możliwą wartość z podanymi wyżej prawdopodobieństwami, ale niewielkie odchylenie od tego z powodu realizacji losowej jest w porządku ( pod warunkiem, że implementacja nie ma innego rozkładu - nie możesz użyć rozkład normalny, aby zapisać bajty ) .

  • Program powinien (znowu teoretycznie) praca dla dowolnie dużej wartości N , ale ograniczenia techniczne dzięki precyzyjnym są w porządku dla dużych N .

  • Dane wyjściowe muszą znajdować się w bazie 10 (wysyłanie danych do jakiejkolwiek innej bazy lub z notacją naukową jest zabronione). Dozwolone są spacje końcowe / początkowe i zera wiodące.

  • Początkowe źródło musi (oczywiście) mieć co najmniej 1 bajt. Być może nie przyjąć nowej linii między kopiami źródle. Program nie powinien pobierać danych wejściowych (lub mieć nieużywane, puste dane wejściowe).

  • To jest , więc wynikiem odpowiedzi jest długość (oryginalnego) źródła w bajtach, przy czym niższy wynik jest lepszy.

Uwaga: To wyzwanie jest (znacznie) trudniejszą wersją tego wyzwania .

Pan Xcoder
źródło
Czy program może odczytać kod źródłowy?
mój zaimek to monicareinstate
3
@ ktoś Tak, jest to dozwolone.
Pan Xcoder,

Odpowiedzi:

16

R , 66 35 bajtów

-29 bajtów dzięki digEmAll .

-2 bajty dzięki Giuseppe .

+0->A
x=!0:F
F=F+1
sample(F*x+!x,1)

Wypróbuj online!

Sprawdź rozkład dla N = 4.

Kluczem jest przypisanie w prawo ->. Kiedy kod zostanie pomnożony N razy, pierwsze N1 wywołań samplezostanie przypisanych Ai wydrukowane zostanie tylko ostatnie połączenie.

Oryginalne, bardziej skomplikowane rozwiązanie:

R , 66 bajtów

T->TT
F=F+1
TT=0
`?`=function(x)if(x)sample(c(1,F),1,,c(1,F-1))
?T

Wypróbuj online!

Wypróbuj online (powtórzone 3 razy)!

Wykorzystuje dwie sztuczki: 1) wywołuje główną funkcję ?będącą przedmiotem zainteresowania , dzięki czemu możemy ją wywoływać bez kończenia programu za pomocą nawiasu, oraz 2) używać zmiennych Ti TT, z kodem, który zaczyna się Ti kończy na ?T.

Fjest licznikiem iteracji. ?jest redefiniowane jako funkcja, która przyjmuje argument boolowski: jeśli wejście ?jest TRUE(lub T), wykonuje wymagane losowe próbkowanie; jeśli dane wejściowe to FALSE(lub 0), to nic nie robi. Wartość parametru TTjest zdefiniowana jako 0, więc ?Tpobiera próbki, ale ?TTnic nie robi.

Gdy źródło jest powtarzane, wygląda to tak:

T->TT
F=F+1
TT=0
`?`=function(x)if(x)sample(c(1,F),1,,c(1,F-1))
?TT->TT
F=F+1
TT=0
`?`=function(x)if(x)sample(c(1,F),1,,c(1,F-1))
?T

więc środkowe połączenie ?TTgeneruje tylko ?Tlosowe połączenie.

Robin Ryder
źródło
5
Nie sądzę, że kiedykolwiek widziałem, że jest ->używany w golfie kodowym w sytuacji, w której <-nie może być; To jest takie fajne!!
Giuseppe,
PS W pewnym momencie dam mu nagrodę.
Giuseppe,
2
Absolutnie niesamowite!
digEmAll,
@digEmAll Dużo fajniejsze, dzięki!
Robin Ryder,
11

Python 3 , 81 79 bajtów

+0if[]else 1
from random import*
try:n+=1
except:n=1
print([1,n][random()*n<1])

Wypróbuj online!

-1 bajt dzięki @Nishioka

Jest to jedno rozwiązanie Python 3, które nie ma bezpośredniego dostępu do źródła programu. Wykonanie tego w Pythonie 3 jest trudniejsze niż w Pythonie 2, ponieważ normalne instrukcje drukowania kończą się nawiasami zamykającymi, więc nie ma wielu opcji zmiany ich zachowania w następnym bloku początkowego źródła. Ciekawie byłoby zobaczyć bardziej kreatywne rozwiązania w Pythonie 3.

Joel
źródło
-1 bajt:+0 if[]else 1
Nishioka,
@Nishioka Thanks. Zaktualizowano
Joel
4

Python 3 , 78 76 75 bajtów

Korzystając z tej samej sztuczki, co w opublikowanym linku , tutaj jest Python (z x = 1).

from random import*;n=len(*open(__file__))//75;print(1+~-n*(random()<1/n))#

Wypróbuj online!

-2 bajki dzięki panu Xcoderowi za jego (n-1)formułę, ~-nktóra ma wyższy priorytet niż *
-1 bajt dzięki Nishioce

Pâris Douady
źródło
1
Dla mnie wygląda dobrze! import random;n=len(*open(__file__))//76;print(1+~-n*(random.random()<1/n))#powinien działać dla -2 bajtów
Mr. Xcoder,
1
Nigdy nie widziałem takiego sposobu robienia n-1! Podoba mi się, dziękuję :)
Pâris Douady
1
-1 bajt: tio.run/##K6gsycjPM/7/…
Nishioka
Kolejny -1 bajt, ale z nieco innym podejściem: tio.run/##K6gsycjPM/7/…
Nishioka
tak, robię to z powodu random()<1/n;-)
Pâris Douady
3

Gaia , 17 15 14 13 bajtów

Øgl13÷:(1w&+ṛ

Wypróbuj online!

Przypadkowo zauważyłem zachowanie Øgwczoraj, przeglądając dokumenty, co ogromnie pomogło.

Giuseppe
źródło
3

Perl 5, 28 26 bajtów

-2 bajty dzięki @Grimy

1 if!++$x;say 1<rand$x||$x

TIO

Nahuel Fouilleul
źródło
26:1 if!++$x;say 1<rand$x||$x
Grimmy
dzięki, niezła odmiana
Nahuel Fouilleul
2

Runiczne Zaklęcia , 31 bajtów

UwR'10<;$\
I+:'RA0)?/1$;
1
l;
y

Wypróbuj online!

Używa tej samej struktury co ta odpowiedź, aby policzyć, ile razy źródło zostało zduplikowane:

Execution flow

Po prostu zamiast wypisywania n-tej liczby z listy, używamy tej wartości do losowego generowania liczby, jeśli wynikiem nie jest 0, drukuj 1, w przeciwnym razie drukuj tę liczbę.

Draco18s nie ufa już SE
źródło
2

Japt , 9 8 bajtów

(°Tö)ΪT

Przetestuj | Podwojone | Potrójna
weryfikacja dystrybucji 10000 przebiegów po 10 powtórzeniach

(°Tö)ΪT
(            :Prevent the operator that follows from being implicitly applied to the first input variable, U
 °T          :Increment T (initially 0) by 1
   ö         :Random element in the range [0,T)
    )        :Closing the parentheses here instead of after the T saves a byte as there would need to be a space here to close the random method
     Î       :Sign - 0 (falsey) or 1 (truthy)
      ªT     :Logical OR with current value of T

Oryginał, 13 11 10 9 bajtów

Zwróć uwagę na spację końcową.

NoÎp°T ö 

Przetestuj | Podwojone | Potrójna
weryfikacja dystrybucji 10000 przebiegów po 10 powtórzeniach

NoÎp°T ö 
N             :Initially, the (empty) array of inputs
 o            :Replace the last element with
  Î           :  Its sign (always 1)
   p          :Push
    °T        :  T (initially 0) incremented
       ö      :Random element of N
Kudłaty
źródło
2

JavaScript ( powłoka JavaScript 71 ), 78 bajtów

(async x=>x)().then(x=>f((''+f).length/78));f=x=>print(1-~x*Math.random()|0)//

Brak linku tio, spidermonkey na tio jest za stary ...

Firefox (Spidermonkey) uważa komentarz za część funkcji f. W rezultacie (''+f).lengthbędzie b+79ngdzie b <78, a (n + 1) to czasy kodu źródłowego powtórzone.

To buggy ( nie jestem pewien. Wolałbym, że to błąd specyfikacji JavaScript niż jakikolwiek interpreter ) zostało przesłane do BMO przez kogoś innego tuż po opublikowaniu tej odpowiedzi: https://bugzilla.mozilla.org/ show_bug.cgi? id = 1579792 . (Ani wątek Bmo, ani tweet nie są przeze mnie publikowane).

tsh
źródło
Co oznacza (async x=>x)()? Dlaczego jest asynchroniczny?
Tomáš Zato - Przywróć Monikę
@ TomášZato Jest dosłownie asynchroniczny. Tak więc wywołanie zwrotne x=>f(...)zostanie wywołane po fzdefiniowaniu funkcji .
tsh
1

C # (interaktywny kompilator Visual C #) , 133 114 112 bajtów

Jest to pierwszy (i mam nadzieję, że ostatni) raz, kiedy użyłem dyrektyw preprocesora C #.

#if!I
#define I
static int i;
class p{~p()=>Console.Write(new Random().Next(i)<1?i:1);}p s=new p();
#endif
i++;

Wypróbuj online!

mój zaimek to monicareinstate
źródło
1

Węgiel drzewny , 12 bajtów

⎚I⎇‽L⊞Oυω¹Lυ

Wypróbuj online! Na podstawie mojej odpowiedzi na powiązane pytanie. Wyjścia nz prawdopodobieństwem ¹/ₙ, w przeciwnym razie 1. Wyjaśnienie:

⎚               Remove output from previous iterations
       υ        Initially empty list
        ω       Empty string
     ⊞O         Push
    L           Length
   ‽            Random integer [0..length)
  ⎇             Ternary
         ¹      If nonzero then literal 1
          Lυ    If zero then the new length
 I              Cast to string for implicit print
Neil
źródło