Zamapuj liczbę losową na pi

27

Podwójna precyzja reprezentacji dziesiętnej może zagwarantować dokładność tylko 15 miejsc po przecinku, dlatego wartość pi jest przybliżana jako:

3.141592653589793

Możesz zobaczyć, że cyfra 3jest w pozycjach 1, 10, 16, cyfra 1jest w pozycjach 2, 4itp.

Wyzwanie

Twoim zadaniem jest utworzenie programu lub funkcji, która utworzy losową podwójną liczbę od 0 do 1 i odwzoruje wartości tej liczby na wartość pi. Robisz to, umieszczając różne cyfry w liczbach losowych w miejscu, w którym cyfra ma liczbę pi. Jeśli cyfra nie zostanie znaleziona w pi, pominiesz ją, a każda cyfra w pi, która nie jest liczbą losową, będzie reprezentowana przez x. Każda wartość może być użyta tylko raz, zaczynając od lewej.

Kilka przykładów prawdopodobnie to wyjaśni. W poniższych przykładach pierwsza liczba to pi, druga to liczba losowa, a ostatnia to pożądana wartość wyjściowa.

3.141592653589793
0.111111111111111
x.1x1xxxxxxxxxxxx

3.141592653589793
0.531000000000000
3.1xx5xxxxxxxxxxx

3.141592653589793
0.123456789123456
3.141592653x8x7xx

3.141592653589793
0.967552381459391
3.14159265358979x

Zasady:

  • Funkcja nie powinna pobierać żadnych danych wejściowych (możliwy wyjątek wyjaśniono w punkcie 3)
  • Dane wyjściowe powinny składać się tylko z ciągu wyjściowego z opcjonalnym znakiem nowej linii (akceptowana jest również pojedyncza spacja)
  • Jeśli twój program nie ma wbudowanej wartości Pi i / lub RNG, możesz na stałe wpisać Pi i przyjąć liczbę losową jako dane wejściowe. Nie można na stałe zakodować losowej liczby ani wziąć Pi jako danych wejściowych.
  • Zarówno zapisana na stałe wartość Pi, jak i 15 losowych cyfr (możesz pominąć, 0.ponieważ wiesz, że będzie to od 0 do 1), zostaną uwzględnione w liczbie bajtów.
  • Jeśli twój język nie ma wymaganej precyzji, możesz użyć mniejszej precyzji pod następującymi ograniczeniami
    • Cyfry Pi muszą być dokładne z dokładnością do posiadanej dokładności
    • Nie możesz wypisać więcej wartości, niż masz pewność, że są poprawne, tzn. Nie możesz wypisać 15 cyfr, jeśli precyzja pozwala tylko na 8 dokładnych miejsc po przecinku.
    • Zakodowana wartość Pi będzie liczyła się jako 16 bajtów (nie potrzebujesz przecinka dziesiętnego), nawet jeśli twój program obsługuje tylko 8 cyfr.
    • Wartość wejściowa dla liczby losowej będzie liczona jako 15 bajtów (nie potrzebujesz 0.. Jest tak, ponieważ języki o niskiej precyzji nie powinny mieć nieuczciwej przewagi.
    • Program musi obsługiwać precyzję co najmniej 5 miejsc po przecinku.
    • Edycja: Aby potwierdzić odpowiedź: Liczba losowa powinna być jakoś wydrukowana, ale ta operacja nie musi być uwzględniona w liczbie bajtów. Na przykład, jeśli możliwe jest wstawienie znaku print rna końcu skryptu, ta część nie zwiększy wyniku.
    • Nie można odjąć bajtów, jeśli jest to część innej niezbędnej operacji. To znaczy print pi, r, jeśli kod jest , możesz tylko odjąć , r.
    • Jeśli musisz wstawić części do kilku miejsc w kodzie, dołącz obie wersje (tę, która drukuje liczbę losową i tę, która nie zawiera komentarza, na przykład: _pi _oNosą potrzebne do wydrukowania liczby losowej. _pRobi xxx i _oNorobi yyy. _pi _oNonie zostaną uwzględnione w liczbie bajtów.

Najkrótszy kod w bajtach wygrywa.


Tabela liderów

Fragment kodu na dole tego postu generuje katalog na podstawie odpowiedzi a) jako listy najkrótszych rozwiązań dla każdego języka oraz b) jako ogólnej tabeli wyników.

Aby upewnić się, że Twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

## Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:

## Perl, 43 + 2 (-p flag) = 45 bytes

Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

Stewie Griffin
źródło
2
Jeśli używasz wbudowanej liczby losowej, czy musi ona zawierać 15 cyfr, czy może zawierać więcej? Czy są też jakieś wymagania, aby wypisać liczbę losową? Jeśli nie, utrudnia to sprawdzenie poprawności odpowiedzi.
user81655,
Ach, to dobra uwaga! Liczba losowa może mieć więcej niż 15 cyfr. Dokonam edycji wyjaśniającej, co zrobić z liczbą losową. Dzięki za komentarz!
Stewie Griffin,
Czy losowe „ od 0 do 1” oznacza 0 < random < 1lub 0 <= random <= 1?
Chris Degnen,
@StewieGriffin Jestem zdezorientowany. Czy to oznacza, że ​​możemy użyć 15 cyfr liczby pi i 16/17 cyfrowej liczby losowej?
Jakube,
@Jakube, szczerze mówiąc: przeczytałem pytanie nieco źle, dlatego odpowiedziałem, że może mieć więcej cyfr, więc odpowiedź na twoje pytanie brzmi „tak”. Jest już za późno, by wrócić do tej odpowiedzi, ponieważ większość odpowiedzi nie ogranicza liczby losowych cyfr. Proszę jednak ograniczyć go do 17.
Stewie Griffin,

Odpowiedzi:

5

Pyth, 25 bajtów

 u&p?}HGH\x.-GH`.n0<`O017

Wypróbuj online: demonstracja lub test pokazujący losową liczbę

Wyjaśnienie:

 u&p?}HGH\x.-GH`.n0<`O017  
                .n0         the constant pi
               `            convert it into a string
                     O0     random number in the range [0.0, 1.0)
                    `       convert to string
                   <   17   only use the first 17 chars (zero, point and 15 digits)
 u                          for each char H in the pi-string:
    ?}HGH\x                    if H in G (the random number string) then H else "x"
   p                           print this char without newline
  &                            and
           .-GH                remove the digit H once from G
<space>                     suppress the output (u returns the unused digits in G)
Jakube
źródło
14

LabVIEW, 53 LabVIEW Prymitywy

Dopasowuję ciągi znaków i umieszczam liczbę w „pustym” ciągu x.xxx i usuwam liczbę z pi, aby nie wyświetlała się ponownie.

losowa liczba i pojedyncze znaki tutaj są dość widoczne, czy wszystko w porządku, czy muszę powtórzyć nagranie?

Eumel
źródło
Wyraźnie wykonuje to zadanie, nawet jeśli kilka znaków jest nieco trudnych do zobaczenia, więc nie musisz niczego powtarzać ... Ładna odpowiedź! =)
Stewie Griffin,
6

Matematyka, 105 lub 147 znaków

Jeżeli liczba losowa „ między 0 a 1” oznacza 0 <= random <= 1, tzn. Obejmuje 0 i 1.

StringReplace[ToString@InputForm@N@Pi,
Thread[ToString/@Complement[Range@9,RandomInteger[{0,9},15]]->"x"]]

(105 znaków)

W przeciwnym razie, biorąc pod uwagę liczbę losową „ od 0 do 1” 0 < random < 1.

Pętla, aby uzyskać 15 losowych liczb całkowitych, nie wszystkie zero. Wybierz dopełnienie z zakresu od 0 do 9, tzn. Te liczby od 0 do 9, których nie ma na liście losowej. Konwertuj te liczby całkowite na ciągi i zamień pasujące znaki w ciągu pi.

(147 znaków)

While[True,r=RandomInteger[{0,9},15];
If[Union@r!={0},Break[]]];
StringReplace[ToString@InputForm@N@Pi,
Thread[ToString/@Complement[Range@9,r]->"x"]]

3.1x15x265358x7x3

Losowe cyfry: -

FromDigits[r]

820307536180783
Chris Degnen
źródło
Gotowy. Podziały linii uwzględniane są tylko dla czytelności.
Chris Degnen,
2
Wciąż pojawia się jako 149 bajtów dla mnie (z łamaniem linii, 146 bez). Nie ma nic złego w dodaniu zarówno wersji golfowej, jak i golfowej. Kilka wskazówek golfa: Truejest 1>0, RandomIntegermożna użyć notacji Infix {0,9}~RandomInteger~15. Prawdopodobnie możesz zapisać niektóre bajty, podając rpewną wartość i faktycznie wykorzystując warunek Whilezamiast zamiast opcji Break.Następnie możesz Forzapisać kolejny bajt While. Chociaż nie rozumiem, dlaczego w ogóle potrzebujesz pętli, jeśli zamiast tego przyjmiesz losową liczbę w zakresie [0,1).
Martin Ender
@ MartinBüttner Lubię 1>0:-)
Chris Degnen
Zwykle czytałbym liczbę losową „od 0 do 1”, co oznacza 0 <losowo <1.
Chris Degnen
5

JavaScript (ES6), 89 87 bajtów

_=>(r=[...Math.random()+""],Math.PI+"").replace(/./g,d=>(r[i=r.indexOf(d)]=_,~i?d:"x"))

Wyjaśnienie

Edycja: Losowy ciąg nie jest teraz obcinany, jak wyjaśniono w plakacie.

Pętla przechodzi przez każdą cyfrę pi i usuwa cyfrę z liczby losowej, jeśli została znaleziona, w przeciwnym razie zamienia cyfrę w pi na x.

_=>(
    r=[...Math.random()+""],      // r = array of 15 digit random number chars
    Math.PI+"").replace(/./g,d=>( // for each digit d of pi, includes "." which is always
                                  //     in the random number
      r[i=r.indexOf(d)]=_,        // i = position of d within r, remove digit from r
                                  // "_" is the unused function argument (equals undefined)
      ~i?d:"x"                    // if found, leave the digit, else replace with x
    ))

Test

Test wypisuje również liczbę losową.

użytkownik 81655
źródło
Czy funkcja random () nie może wygenerować 15 zer, co odpowiada 0,000 ... lub 1,000 ...? tzn. nie pomiędzy 0 a 1.
Chris Degnen,
@ChrisDegnen Math.random()tworzy szereg zakresów, [0,1)więc może, 0ale nigdy 1. OP nie określił konkretnie, czy zakres jest obejmujący, czy wyłączny, więc założyłem, że wszystko, co jest rozsądne, jest w porządku. Jest to również zakres używany przez inne odpowiedzi. Jednak uświadomiłeś mi, że jeśli tak jest, 0zawiedzie, ponieważ .in pi nie zostanie dopasowany i stanie się x. Ma to szansę 1 na 2 ^ 53, ale i tak postanowiłem to naprawić.
user81655,
:-) przepraszam za to.
Chris Degnen,
Prawdopodobieństwo trafienia dokładnie 0 lub 1 dla losowego podwójnego jest znikome, więc na potrzeby tego wyzwania zasięg [0,1]jest w porządku (tak jest (0,1)).
Stewie Griffin,
Miły. Proponuję krótszy wariant.
MST,
3

CJam, 48 46 42 38 36 bajtów

P`'xf+1dmr`{1$f#:!1a/0=:)W+H<.%}/1f=

Sprawdź to tutaj.

A oto wersja, która wypisuje zarówno π, jak i liczbę losową:

P_p`'xf+1dmr`_oNo{1$f#:!1a/0=:)W+H<.%}/1f=

Sprawdź to tutaj.

Nie zmniejszam liczby losowej do 15 miejsc po przecinku, jak wyjaśniono w OP w komentarzu.

Wyjaśnienie

Chodzi o to, aby każdy znak w ciągu π zamieniać w parę tego znaku i x. Dla każdego znaku w liczbie losowej zamieniamy pierwszą parę, która zaczyna się od tego znaku. Na koniec wypisujemy drugi znak z każdej pary.

P`      e# Get string representation of π.
'xf+    e# Append "x" to each character.
1dmr`   e# Get string representation of random number in [0,1).
{       e# For each character in that string...
  1$    e#   Copy the list of pairs.
  f#    e#   For each pair, find the index of the current character. If the character is
        e#   not in the pair, we get -1 (truthy). If it is the first character of the pair,
        e#   we get 0 (falsy). If it is the second character, we get 1 (truthy).
  :!    e#   Logical NOT for each of the results. We get a 1 for every pair we could
        e#   potentially swap.
  1a/   e#   Split around those 1s.
  0=    e#   Keep only the first chunk.
  :)    e#   Turn all the 0s into that chunk into 1s.
  W+    e#   Append a -1.
  H<    e#   Truncate to 17 elements (the number of pairs).
  .%    e#   Apply % pairwise. This reverses the element at the position of the -1.
}/
1f=     e# Select the second character from each pair.
Martin Ender
źródło
2

Lua, 231 230 bajtów

m,s=math,""p,r=m.pi..s,s..m.random()p=p:sub(1,#p-1)p:gsub(".",function(c)s=s..(47>c:byte()and c or"x")end)r:gsub("[^%.]",function(c)l=p:find(c)if l then p,s=p:sub(1,l-1).."x"..p:sub(l+1),s:sub(1,l-1)..c..s:sub(l+1)end end)print(s)

Objaśnienia

function f()
  m,s=math,""
  p,r=m.pi..s,s..m.random()
  p=p:sub(1,#p-1)                       -- remove the last digit of math.pi

  p:gsub(".",function(c)
    s=s..(47>c:byte()and c or"x")      -- Construct a string full of "x" with a single dot
  end)

  r:gsub("[^%.]",function(c)            -- Iterate over each character but the dot in the random number
    l=p:find(c)                         -- if c isn't in pi, l=nil 
    if l                                -- which is one of the two falsy value in lua
    then
      p,s=p:sub(1,l-1).."x"..p:sub(l+1),-- If c is in pi, we replace it in p by an x
          s:sub(1,l-1)..c..s:sub(l+1)   -- and in s by its value
    end
  end)
  return s
end

Niestety, lua tutaj wcale mi nie pomaga. math.pi wokół ostatniej cyfry pi zwraca:

print(math.pi)
>> 3.1415926535898

Muszę skrócić ten numer:

stringPI=""..math.pi
print(stringPI:sub(1,#stringPI-1))
>> 3.141592653589

Drugim dużym domyślnym zadaniem, które wykonało to wyzwanie, był lua brak string.replace (). Ponieważ s:sub(1,l-1)..c..s:sub(l+1)wykonuję tę akcję dwukrotnie , chciałem wykonać anonimową funkcję, myśląc, że będzie ona krótsza. Tak nie jest, więc napisałem dwa razy.

Powodem, dla którego muszę uważać na kropkę, jest sposób, w jaki lua zwraca swoją pozycję. W wyrażeniach regularnych kropka oznacza „dowolny znak”, więc gdy oceniam znak .w mojej pętli, pasuje on do pierwszego znaku:

c="."  -- The value of the dot in the loop
found = stringPI:find(c)
print(stringPI)
print("location of \".\": "..found)
print("char at "..found..": "..stringPI:sub(found,found))

>> 3.141592653589
>> location of ".": 1   --Keep in mind that lua arrays are 1-based :)
>> char at 1: 3 

Możesz przetestować lua online . Ponieważ nie uruchamiam PRNG, oto kod pozwalający na uruchomienie kilku testów podczas oglądania wartości.

function f()m,s=math,""p,r=m.pi..s,s..m.random()print("Random number: "..r)p=p:sub(1,#p-1)p:gsub(".",function(c)s=s..(c:byte()<47 and c or"x")end)r:gsub("[^%.]",function(c)l=p:find(c)if l then p,s=p:sub(1,l-1).."x"..p:sub(l+1),s:sub(1,l-1)..c..s:sub(l+1)end end)return s end

for i=1,10
do
    print(f())
end
Katenkyo
źródło
2

Python 2.7, 117 110 bajtów

import math,random
n=list(`random.random()`)
print''.join(n.pop(n.index(d))if d in n else'x'for d in`math.pi`)

Testowany na najnowszej aplikacji QPython na Androida, ale powinien działać wszędzie.

Edycja 1: zmieniono str(pi)na backticks.

Dla testów:

import math,random
n=list(`random.random()`)
print `math.pi`
print ''.join(n)
print''.join(n.pop(n.index(d))if d in n else'x'for d in`math.pi`)
uryga
źródło
Niezła odpowiedź! Nawiasem mówiąc, „apostrofy, których SO używa do oznaczania kodu”, to znaki odwrotne lub gajowe :-)
kot
1

Python, 147 bajtów

import math as m,random as r
L=lambda t:[_ for _ in str(t)]
p=L(m.pi)
R=L(r.random())
A=""
print R #subtracted from byte count
for n in p:
    try:R.remove(n);A+=n
    except:A+='x'
print A

Dość oczywiste: funkcja lambda przekształca liczbę zmiennoprzecinkową na listę; następnie przeglądamy listę pi, próbując usunąć każdą cyfrę z listy losowej. Jeśli możemy, dobrze, dołączmy to do odpowiedzi; jeśli nie, dodaj zamiast niego „x”.

Kieran Hunt
źródło
str(t)daje tylko 11 cyfr precyzji t, repr(t)daje wszystkie t15 cyfr.
Noodle9
1

Perl, 70 bajtów

$_=4*atan2(1,1);s/\d/x$&/g;for$i(rand=~/\d/g){s/x$i/$i/}s/x./x/g;print

Z komentarzami:

$_=4*atan2(1,1);        # Perl doesn't have a Pi constant
s/\d/x$&/g;             # prepend a x to all digits in Pi
for $i (rand=~/\d/g)    # iterate the digits in the random number
{ s/x$i/$i/ }           # replace first occurrence of x-nr pair 
s/x./x/g;               # strip all remaining numbers
print                   # print!

Ta wersja wypisze pi, liczbę losową i wynik:

$_=$p=4*atan2(1,1);
s/\d/x$&/g;
$r=rand;
for $i ($r=~/\d/g)
{ s/x$i/$i/ }
s/x./x/g;
print "$p\n$r\n$_\n"

Przykładowe dane wyjściowe:

3.14159265358979
0.877757977767946
x.x4x59x6xxx897x

Mam nadzieję, że to w porządku:

  • pi zawiera łącznie 15 cyfr, w tym 3, więc nie przekracza dokładności.
  • ostatnia cyfra ( 9) jest dokładna.
Kenney
źródło