Mapper un nombre aléatoire sur pi

27

Une représentation en double précision d'une décimale ne peut garantir qu'une précision de 15 décimales, donc pi est approximé comme:

3.141592653589793

Vous pouvez voir que le chiffre 3est en position 1, 10, 16, le chiffre 1est en position, 2, 4etc.

Défi

Votre tâche consiste à créer un programme ou une fonction qui crée un double aléatoire entre 0 et 1 et mappe les valeurs de ce nombre sur la valeur de pi. Pour ce faire, placez les différents chiffres dans les nombres aléatoires à la position que le chiffre a dans pi. Si le chiffre n'est pas trouvé dans pi, vous le sauterez, et chaque chiffre dans pi qui n'est pas dans le nombre aléatoire sera représenté par un x. Chaque valeur ne peut être utilisée qu'une seule fois, en commençant par la gauche.

Quelques exemples le rendront probablement plus clair. Dans les exemples suivants, le premier nombre est pi, le second est le nombre aléatoire et le dernier est la sortie souhaitée.

3.141592653589793
0.111111111111111
x.1x1xxxxxxxxxxxx

3.141592653589793
0.531000000000000
3.1xx5xxxxxxxxxxx

3.141592653589793
0.123456789123456
3.141592653x8x7xx

3.141592653589793
0.967552381459391
3.14159265358979x

Règles:

  • La fonction ne doit prendre aucune entrée (une exception possible est expliquée au point 3)
  • La sortie doit être constituée uniquement de la chaîne de sortie, avec une nouvelle ligne facultative (un seul espace de fin est également accepté)
  • Si votre programme n'a pas de valeur Pi intégrée et / ou de RNG, vous pouvez coder en dur Pi et prendre le nombre aléatoire en entrée. Vous ne pouvez pas coder en dur le nombre aléatoire ou prendre Pi comme entrée.
  • La valeur codée en dur pour Pi et les 15 chiffres aléatoires (vous pouvez ignorer 0.car vous savez que ce sera entre 0 et 1) seront inclus dans le nombre d'octets.
  • Si votre langue n'a pas la précision requise, vous pouvez utiliser moins de précision sous les restrictions suivantes
    • Les chiffres de Pi doivent être précis jusqu'à la précision que vous avez
    • Vous ne pouvez pas produire plus de valeurs que ce qui est garanti, c'est-à-dire que vous ne pouvez pas produire 15 chiffres si la précision ne permet que 8 décimales précises.
    • La valeur codée en dur de Pi comptera comme 16 octets (vous n'avez pas besoin du point décimal), même si votre programme ne prend en charge que 8 chiffres.
    • La valeur d'entrée pour le nombre aléatoire comptera comme 15 octets (vous n'avez pas besoin 0.. C'est parce que les langues avec une faible précision ne devraient pas avoir un avantage injuste.
    • Le programme doit prendre en charge une précision de 5 décimales (au moins).
    • Modifier: Pour valider la réponse: Le nombre aléatoire doit être imprimé d'une manière ou d'une autre, mais cette opération ne doit pas être incluse dans le nombre d'octets. Ainsi, par exemple, s'il est possible d'insérer un print rà la fin du script, cette partie n'augmentera pas le score.
    • Vous ne pouvez pas soustraire les octets s'il fait partie d'une autre opération nécessaire. C'est à dire si le code est print pi, r, alors vous ne pouvez que soustraire , r.
    • Si vous devez insérer des pièces à plusieurs endroits dans le code, veuillez inclure les deux versions (celle qui imprime le nombre aléatoire et celle qui ne le fait pas avec un commentaire tel que: _pet _oNosont nécessaires pour imprimer le nombre aléatoire. _pFait xxx et _oNofait yyy. _pet _oNone sera pas inclus dans le nombre d'octets.

Le code le plus court en octets gagne.


Classement

L'extrait de pile au bas de cet article génère le catalogue à partir des réponses a) en tant que liste des solutions les plus courtes par langue et b) en tant que classement général.

Pour vous assurer que votre réponse apparaît, veuillez commencer votre réponse avec un titre, en utilisant le modèle Markdown suivant:

## Language Name, N bytes

Nest la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores dans le titre, en les barrant. Par exemple:

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

Si vous souhaitez inclure plusieurs nombres dans votre en-tête (par exemple, parce que votre score est la somme de deux fichiers ou que vous souhaitez répertorier les pénalités de drapeau d'interprète séparément), assurez-vous que le score réel est le dernier numéro de l'en-tête:

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

Vous pouvez également faire du nom de la langue un lien qui apparaîtra ensuite dans l'extrait de code:

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

Stewie Griffin
la source
2
Si vous utilisez un nombre aléatoire intégré, doit-il contenir 15 chiffres ou peut-il en avoir plus? Y a-t-il également des exigences pour sortir le nombre aléatoire? Sinon, il est un peu plus difficile de valider les réponses.
user81655
Aah, c'est un bon point! Le nombre aléatoire peut comporter plus de 15 chiffres. Je ferai un montage expliquant quoi faire avec le nombre aléatoire. Merci d'avoir commenté!
Stewie Griffin
Est-ce que " entre 0 et 1" aléatoire signifie 0 < random < 1ou 0 <= random <= 1?
Chris Degnen
@StewieGriffin, je suis confus. Est-ce à dire que nous pouvons utiliser 15 chiffres de pi et un nombre aléatoire de 16/17 chiffres?
Jakube
@Jakube, pour être honnête: j'ai lu la question un peu mal, j'ai donc répondu qu'il pourrait avoir plus de chiffres, donc la réponse à votre question est oui. Il est trop tard pour revenir sur cette réponse maintenant, car la plupart des réponses n'ont pas plafonné le nombre de chiffres aléatoires. Veuillez le limiter à 17 cependant.
Stewie Griffin

Réponses:

5

Pyth, 25 octets

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

Essayez-le en ligne: démonstration ou test montrant le nombre aléatoire

Explication:

 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
la source
14

LabVIEW, 53 primitives LabVIEW

Je fais correspondre des chaînes et je mets le nombre dans une chaîne x.xxx "vide" et je supprime le nombre de pi pour qu'il ne s'affiche plus.

le nombre aléatoire et les caractères simples ici sont un peu visibles, est-ce bien ou dois-je refaire l'enregistrement?

Eumel
la source
Il fait très clairement l'affaire même si quelques caractères sont un peu difficiles à voir, donc vous n'avez rien à refaire ... Belle réponse! =)
Stewie Griffin
6

Mathematica, 105 ou 147 caractères

Si un nombre aléatoire " entre 0 et 1" signifie 0 <= random <= 1, c'est-à-dire inclut 0 et 1.

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

(105 caractères)

Sinon, prendre un nombre aléatoire " entre 0 et 1" pour signifier 0 < random < 1.

Boucle pour obtenir 15 entiers aléatoires, pas tous nuls. Sélectionnez le complément de 0 à 9, c'est-à-dire les nombres de 0 à 9 qui ne figurent pas dans la liste aléatoire. Convertissez ces entiers en chaînes et remplacez les caractères correspondants dans une chaîne pi.

(147 caractères)

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

Chiffres aléatoires: -

FromDigits[r]

820307536180783
Chris Degnen
la source
Terminé. Les sauts de ligne ne sont inclus que pour la lisibilité.
Chris Degnen
2
Sort toujours comme 149 octets pour moi (avec des sauts de ligne, 146 sans). Il n'y a rien de mal à ajouter à la fois une version golfée et une version non golfée. Voici quelques conseils de golf: Trueest 1>0, RandomIntegerpeuvent utiliser la notation infixe {0,9}~RandomInteger~15. Vous pouvez probablement enregistrer certains octets en donnant une rcertaine valeur et en utilisant la condition de au Whilelieu d'utiliser Break.Alors, vous Forpouvez enregistrer un autre octet While. Bien que je ne vois pas du tout pourquoi vous avez besoin de la boucle si vous supposez plutôt le nombre aléatoire dans la plage [0,1).
Martin Ender
@ MartinBüttner J'aime 1>0:-)
Chris Degnen
Je lis habituellement un nombre aléatoire "entre 0 et 1" pour signifier 0 <aléatoire <1.
Chris Degnen
5

JavaScript (ES6), 89 87 octets

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

Explication

Edit: la chaîne aléatoire n'est plus tronquée comme le précise l'affiche.

Boucle dans chaque chiffre de pi et supprime le chiffre du nombre aléatoire s'il a été trouvé, sinon remplace le chiffre dans pi par 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
    ))

Tester

Le test génère également le nombre aléatoire.

user81655
la source
Random () ne pouvait pas produire 15 zéros, ce qui correspondrait à 0.000 ... ou 1.000 ...? c'est-à-dire pas entre 0 et 1.
Chris Degnen
@ChrisDegnen Math.random()produit un certain nombre de plages de [0,1)sorte qu'il pourrait 0mais jamais 1. L'OP n'a pas précisé si la gamme était inclusive ou exclusive, j'ai donc supposé que tout ce qui était raisonnable était bien. C'est également la plage utilisée par les autres réponses. Cependant, vous m'avez fait savoir que si c'est exactement 0cela échouera car l' .in pi ne sera pas mis en correspondance et deviendra x. Cela a 1 chance sur 2 ^ 53 de se produire, mais j'ai quand même décidé de le corriger.
user81655
:-) Désolé pour ça.
Chris Degnen
La probabilité de frapper exactement 0 ou 1 pour un double aléatoire est négligeable, donc aux fins de ce défi, une plage [0,1]est fine (tout comme (0,1)).
Stewie Griffin
Agréable. Je propose une variante plus courte.
MST
3

CJam, 48 46 42 38 36 octets

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

Testez-le ici.

Et voici la version qui imprime à la fois π et le nombre aléatoire:

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

Testez-le ici.

Je ne tronque pas le nombre aléatoire à 15 décimales, comme le précise l'OP dans un commentaire.

Explication

L'idée est de transformer chaque caractère de la représentation sous forme de chaîne de π en une paire de ce caractère et x. Pour chaque caractère du nombre aléatoire, nous échangeons la première paire qui commence par ce caractère. À la fin, nous sortons le deuxième caractère de chaque paire.

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
la source
2

Lua, 231230 octets

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)

Explications

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

Malheureusement, lua ne m'aide pas du tout ici. math.pi autour du dernier chiffre de pi il retourne:

print(math.pi)
>> 3.1415926535898

Je dois tronquer ce nombre:

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

Le deuxième gros défaut pour faire ce défi était lua manque de string.replace (). Comme je fais cette action deux fois en utilisant s:sub(1,l-1)..c..s:sub(l+1), je voulais faire une fonction anonyme, pensant que ce serait plus court. Ce n'est pas le cas, donc je l'ai gardé écrit deux fois.

La raison pour laquelle je dois faire attention au point, c'est comment lua retourne sa position. Dans les expressions rationnelles, un point signifie "n'importe quel caractère", donc lorsque j'évalue le caractère .dans ma boucle, il correspond au premier caractère:

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 

Vous pouvez tester lua en ligne . Comme je n'amorce pas le PRNG, voici un code vous permettant d'exécuter plusieurs tests tout en surveillant les valeurs.

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
la source
2

Python 2.7, 117 110 octets

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

Testé sur la dernière application QPython Android, mais devrait fonctionner n'importe où.

Edit 1: changé str(pi)en backticks.

Pour tester:

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
la source
Bonne réponse! Les "apostrophes que SO utilise pour marquer le code" sont des backticks ou des symboles de bosquets, soit dit en passant :-)
cat
1

Python, 147 octets

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

Assez explicite: la fonction lambda convertit float en liste; nous parcourons ensuite la liste pi en essayant de supprimer chaque chiffre de la liste aléatoire. Si nous le pouvons, tant mieux, joignez-le à la réponse; sinon, ajoutez un «x» à la place.

Kieran Hunt
la source
str(t)vous donne seulement 11 chiffres de précision à partir de t, repr(t)vous donne tous tles 15 chiffres de.
Noodle9
1

Perl, 70 octets

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

Avec commentaires:

$_=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!

Cette version affichera pi, le nombre aléatoire et le résultat:

$_=$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"

Exemple de sortie:

3.14159265358979
0.877757977767946
x.x4x59x6xxx897x

J'espère que ça va:

  • pi contient 15 chiffres au total, y compris les 3, donc il ne dépasse pas la précision.
  • le dernier chiffre ( 9) est exact.
Kenney
la source