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 .


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.


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.


-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


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


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






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

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


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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.