41
\$\begingroup\$

Numbers that are easy to remember yet theoretically not easily made

Your challenge is to make a program/function in any language that generates uniformly random numbers that fit these criteria:

  1. Length is 5 digits

  2. There are two separate repeated digit pairs

  3. One set of repeated digits is at the beginning or end and the digits are next to each other

  4. The odd number out is surrounded by the other pair of digits

  5. The two digit pairs and the other number should all be unique

  6. Your program may support numbers with leading zeroes or not, at your discretion. If leading zeroes are supported, they must be included in the output: 06088, not 6088. If leading zeroes are not supported, then numbers like 06088 should not be generated at all.

Test Cases

Accepted Outputs:

55373
55494
67611
61633
09033
99757
95944
22808
65622
22161

Not accepted outputs:

55555
77787
85855
12345
99233
12131
abcde
5033

More acceptable test cases can be found at this pastebin link.

These were made with this python program:

import random
for i in range(100):

    if random.randint(0,100) >= 50: #Put pair touching at beginning if true
        temp = []                      #working array
        temp.append(random.randint(0,9))  #append random digit
        temp.append(temp[0])              #append the same digit again

        x = random.randint(0,9)
        while x == temp[0]:
            x = random.randint(0,9)
        temp.append(x)                    #append another unique digit

        y = random.randint(0,9)
        while y == temp[0] or y == temp[2]:
            y = random.randint(0,9)
        temp.append(y)                  #append another unique digit, and the previous unique digit
        temp.append(x)

    else:  #Put touching pair at end
        temp = []                      #working array  
        temp.append(random.randint(0,9))  #append random digit

        #While not unique, try again
        x = random.randint(0,9)
        while x == temp[0]:
            x = random.randint(0,9)
        temp.append(x)                    #append another unique digit


        temp.append(temp[0])              #append the same 0th digit again


        y = random.randint(0,9)
        while y == temp[0] or y == temp[1]:
            y = random.randint(0,9)
        temp.append(y)                  #append another unique digit twice
        temp.append(y)

    tempstr = ""
    for i in temp:
        tempstr += str(i)
    print tempstr

This is , so shortest answer in bytes wins!

\$\endgroup\$
  • 5
    \$\begingroup\$ I suggest "Possible outputs (probability>0)" and "Not possible outputs (probability=0)" rather than "Truthy" and "Falsy"—this seems more in line with what I think you're asking (and with the Python). \$\endgroup\$ – Khuldraeseth na'Barya Mar 9 '18 at 4:29
  • 9
    \$\begingroup\$ Do we have to print an output like 09033 with a leading zero? \$\endgroup\$ – xnor Mar 9 '18 at 4:57
  • 3
    \$\begingroup\$ If the probability is uniform, can you specify that in the question. By default, random does not mean uniformly so \$\endgroup\$ – Jo King Mar 9 '18 at 5:35
  • 3
    \$\begingroup\$ maybe add 99233, for conveniewnce to understand \$\endgroup\$ – l4m2 Mar 9 '18 at 5:51
  • 3
    \$\begingroup\$ Welcome to PPCG! Nice first challenge. \$\endgroup\$ – Jonathan Allan Mar 9 '18 at 13:19

21 Answers 21

21
\$\begingroup\$

05AB1E, 11 bytes

žh.r3£ûÁÂ)Ω

Try it online!

Explanation

žh            # push "0123456789"
  .r          # random shuffle
    3£        # take the first 3
              # EX: 152
      û       # palendromize
              # EX: 15251
       Á      # rotate right
              # EX: 11525
        Â)    # pair with its reverse
              # EX: [11525, 52511]
          Ω   # pick one at random
\$\endgroup\$
  • \$\begingroup\$ I wonder if Emigna ha... sees top answer +1. \$\endgroup\$ – Magic Octopus Urn Mar 13 '18 at 19:43
9
\$\begingroup\$

CJam (16 bytes)

YmrG*98+ZbA,mrf=

Online demo

Note: I've assumed that by "unique" OP really means "distinct".

Also for 16 bytes:

98ZbA,mrf=W2mr#%
98ZbA,mrf=_W%]mR

Dissection

Ymr    e# Select a random number from [0 1]
G*98+  e# Multiply by 16 and add 98 to get 98 or 114
Zb     e# Base conversion in base 3 to get [1 0 1 2 2] or [1 1 0 2 0]
A,mr   e# Shuffle the numbers from 0 to 9
f=     e# Map "select the item at this index"

The other variants generate using [1 0 1 2 2] and then select either the result or its reverse.

\$\endgroup\$
9
\$\begingroup\$

Perl 5, 81 63 56 bytes

Cut 7 bytes with inspiration from @DomHastings

Constructing the number from the appropriate pattern.

@q{0..9}++;say+(keys%q)[.5>rand?(2,2,0,1,0):(0,1,0,2,2)]

Try it online!


Perl 5, 89 bytes

Picks random 5 digit numbers until it finds one that meets the criteria.

$_=sprintf'%05d',0|rand 1E5until(/(.)\1(.)(.)\2/||/(.)(.)\1(.)\3/)&&$1-$2&$2-$3&$1-$3;say

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Nice trick using the hash keys for randomness! I think this is equivalent for -8, although I might have missed an edge case... Try it online! \$\endgroup\$ – Dom Hastings Mar 9 '18 at 6:22
  • 1
    \$\begingroup\$ Hash randomization. Brilliant! shorter \$\endgroup\$ – Ton Hospel Mar 9 '18 at 7:17
  • \$\begingroup\$ The question is whether or not time%2 is sufficiently random, since it is, in a sense, under the control of the user. \$\endgroup\$ – Xcali Mar 9 '18 at 19:12
  • \$\begingroup\$ @Xcali It seems to be consensus that it is fine as long as you only use it once so I think you should be good. \$\endgroup\$ – FryAmTheEggman Mar 9 '18 at 21:43
8
\$\begingroup\$

Python 2, 80 bytes

from random import*
a,b,c=sample(range(10),3)
print[a,a,b,c,b][::choice((-1,1))]

Try it online!

Outputs a list of digits.

Python 2, 83 bytes

from random import*
a,b,c=sample('0123456789',3)
print(a*2+b+c+b)[::choice((-1,1))]

Try it online!

Output is a number.

\$\endgroup\$
  • \$\begingroup\$ If non-uniform randomness is allowed by default (the question doesn't specify), you can save bytes by sampling the reversedness as well: Try it online! Edit: Never mind, I see uniformity was edited into the spec. I wonder if this approach can still be salvaged. \$\endgroup\$ – xnor Mar 9 '18 at 21:02
7
\$\begingroup\$

APL (Dyalog Unicode), 22 21 20 18 17 bytes

(3∨?2)⌽1↓,∘⌽⍨3?10

Try it online!

If it's acceptable to output the numbers always in the same format, this can be shortened to 12 bytes, either 1⌽1↓,∘⌽⍨3?10 or 3⌽1↓,∘⌽⍨3?10.

Saved a byte by removing the unnecessary .

Saved a byte thanks to H.PWiz, and then 2 more bytes due to their tip.

Saved a byte thanks to ngn.

The function assumes ⎕IO←0 (Index Origin).


How?

(3∨?2)⌽1↓,∘⌽⍨3?10 ⍝ Anonymous function.
              3?10  ⍝ Deal 3 (distinct) random numbers from 0 to 9. (Assume 1 2 3)
             ⍨     ⍝ Use that as both arguments for:
          ,∘⌽      ⍝ Rotate (⌽), then concatenate (,).
                   ⍝ Yields 3 2 1 1 2 3.
        1↓         ⍝ Drop the first element. Our vector is now 2 1 1 2 3
      ⌽            ⍝ Rotate the vector to the left using as argument:
(  ?2)             ⍝ Roll 0 or 1 and...
 3∨                ⍝ Do the GCD between 3 and the result. (3∨0=3; 3∨1=1.)
                   ⍝ This yields either 1 1 2 3 2 or 2 3 2 1 1.
\$\endgroup\$
  • \$\begingroup\$ Input cannot be given \$\endgroup\$ – drham Mar 9 '18 at 20:11
  • \$\begingroup\$ @drham there is no input to the function. In this case, the TIO field Input is used to call the function g. Also, the g← is not counted in the byte count because it's not necessary, it's only being used to call the function. \$\endgroup\$ – J. Sallé Mar 9 '18 at 20:13
  • \$\begingroup\$ The fact that g is called in the input section is just a quirk of how APL is set to run on TIO \$\endgroup\$ – H.PWiz Mar 9 '18 at 20:14
  • \$\begingroup\$ (4∨?2) saves a byte over 1 4[?2] \$\endgroup\$ – H.PWiz Mar 9 '18 at 20:21
  • 1
    \$\begingroup\$ You can also save bytes by not assigning to f and using a train. I'll leave that to you though :) \$\endgroup\$ – H.PWiz Mar 9 '18 at 20:27
6
\$\begingroup\$

Java 8, 145 136 125 119 bytes

v->{String r;for(;!(r=(int)(Math.random()*1e5)+"").matches("((.).?\\2){2}")|r.chars().distinct().count()<3;);return r;}

-9 bytes thanks to @OlivierGrégoire.
-11 bytes thanks to @RickHitchcock.
-6 bytes thanks to @Nevay.

Explanation:

Try it online.

v->{            // Method with empty unused parameter and String return-type
  String r;     //  Result-String
  for(;!(r=(int)(Math.random()*1e5)+"")
                //  Generate a random number in the range [0; 100000) and set it to `r`
        .matches("(.).*\\1(.).*\\2")
                //   And continue doing this as long as it doesn't match the regex above,
       |r.chars().distinct().count()<3;);
                //   or doesn't have three distinct digits
  return r;}    //  Return the result
\$\endgroup\$
  • \$\begingroup\$ 136 bytes \$\endgroup\$ – Olivier Grégoire Mar 9 '18 at 11:41
  • \$\begingroup\$ @OlivierGrégoire Did you post this at the correct challenge?.. :S It does look familiar, but it's certainly not this challenge.. \$\endgroup\$ – Kevin Cruijssen Mar 9 '18 at 12:04
  • \$\begingroup\$ The bitly thingy broke my link... Anyways, here's the golf: v->{String r="";for(;!r.matches("(.)\\1(.).\\2|(.).\\3(.)\\4")|r.chars().distinct().count()!=3;r=(int)(Math.random()*1e5)+"");return r;} \$\endgroup\$ – Olivier Grégoire Mar 9 '18 at 12:55
  • 1
    \$\begingroup\$ I think your regex can be shortened to (.).*\\1(.).*\\2, saving 11 bytes. \$\endgroup\$ – Rick Hitchcock Mar 9 '18 at 16:36
  • 1
    \$\begingroup\$ 119 bytes: v->{String r;for(;!(r=(int)(Math.random()*1e5)+"").matches("((.).?\\2){2}")|r.chars().distinct().count()<3;);return r;} \$\endgroup\$ – Nevay Mar 12 '18 at 18:31
5
\$\begingroup\$

Jelly, 23 bytes

⁵Ḷṗ3⁼Q$ÐfXµḢ;`;ŒBW;U$µX

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Nice, I would upvote, but I can't \$\endgroup\$ – drham Mar 9 '18 at 4:18
  • 7
    \$\begingroup\$ @drham :) thanks. you should be able to soon, once most active members wake up your question will probably get a lot of upvotes. good first challenge and welcome to PPCG by the way! \$\endgroup\$ – HyperNeutrino Mar 9 '18 at 4:26
5
\$\begingroup\$

Jelly, 12 11 bytes

ØDẊ⁽0yṃ,U$X

Try it online!


Explanation


ØDẊ⁽0yṃ,U$X    Niladic link, generate a random string.
ØD             List of digits, ['0','1','2',...,'9'].
  Ẋ            Random shuffle.
   ⁽0y         Number 13122.
      ṃ        Base decompression. (*)
       ,U$     Pair with its upend (reverse).
          X    Choose one (it or its reversed) randomly.

(*) The right argument of is the list ['0','1','2',...,'9'], randomly shuffled, have 10 elements. So the number 13122 will be converted to bijective base 10 ([1,3,1,2,2]) and index into the list (so if the list is l, the return value of the atom is [l[1],l[3],l[1],l[2],l[2]], where Jelly uses 1-based indexing)

\$\endgroup\$
  • \$\begingroup\$ (same idea as the 05AB1E answer, came up with independently) \$\endgroup\$ – user202729 Mar 9 '18 at 7:44
  • \$\begingroup\$ ... 05AB1E get 6 upvotes because of being able to tie Jelly, Jelly only get 2 upvotes because of being unable to win 05AB1E? \$\endgroup\$ – user202729 Mar 9 '18 at 11:16
  • 2
    \$\begingroup\$ i upvoted your answer. --> SPEECH 100 <--- \$\endgroup\$ – L_Church Mar 9 '18 at 11:46
4
\$\begingroup\$

JavaScript (ES6), 79 bytes

f=([,,d,a,b,c]=[...Math.random()+f])=>a-b&&a-c&&b-c?d&1?a+a+b+c+b:b+c+b+a+a:f()

Try it online!

How?

Math.random() gives a random float in [0..1). We use +f to force coercion to a string. We ignore the leading zero and the decimal point by doing [,, (destructuring assignment of the first two characters to nothing) and collect the first 4 decimal digits into d, a, b, and c.

If a, b and c are 3 distinct integers, we build the final output in either AABCB or BCBAA format (using the parity of d to decide). Otherwise, we try again until they are.

In the highly improbable event of Math.random() returning a value without enough decimal places, at least c will be set to a non-digit character, forcing the test to fail and the recursive call to occur. If a, b and c are valid integers then d is guaranteed to be a valid integer as well, so this one doesn't need to be tested.

\$\endgroup\$
  • \$\begingroup\$ Both && can be &. Also, how does [,,a,b,c,d] work? I've never seen an input like [,, before. \$\endgroup\$ – Kevin Cruijssen Mar 9 '18 at 15:12
  • 1
    \$\begingroup\$ @KevinCruijssen A bitwise AND would fail for instance for a=4, b=2, c=1 because 4-2&4-1&2-1 == 2&3&1 == 0. I've added a short explanation about the variable assignment. \$\endgroup\$ – Arnauld Mar 9 '18 at 15:34
  • \$\begingroup\$ Ah of course. I just tried && to & in TIO and it gave correct outputs, so I assumed it was possible. Didn't realize & instead of && would filter out otherwise valid outputs. And thanks for the added explanation about the destructuring assignment, never seen it before. \$\endgroup\$ – Kevin Cruijssen Mar 9 '18 at 15:51
  • \$\begingroup\$ This is just awesome +1 \$\endgroup\$ – Luis felipe De jesus Munoz Mar 9 '18 at 20:23
4
\$\begingroup\$

Perl 6, 42 bytes

[~] (^10).pick(3)[0,|(<0 2 1>,<1 0 2>).pick,2]

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Dirty, 33 bytes

Uses the --numeric-output flag so it's readable, otherwise it would output a string of control characters with code-points corresponding to the digits.

10⭧[1w#%D⅋№3⤱≠1ẅ&]1wẂ⭿⭣1u∅#1∧◌ŪW‼

Try it online!

Explained:

10⭧              put 10 on the right stack
[1w#%D⅋№3⤱≠1ẅ&] loop until there are 3 distinct positive numbers below 10 in the top stack
1wẂ              clean-up the right and top stacks
⭿               copy the top and bottom of the top stack to each-other
⭣                swap the first two elements of the top stack
1u               rotate the top stack by 1
∅#1∧◌ŪW          reverse the top stack half of the time
‼                print the top stack
\$\endgroup\$
2
\$\begingroup\$

Charcoal, 34 bytes

≔‽χθ≔‽Φχ⁻ιθη↑I⟦θθη‽Φχ×⁻ιθ⁻ιηη⟧¿‽²‖

Try it online! Link is to verbose version of code. Explanation:

  χ                                 Predefined variable 10
 ‽                                  Random element from implicit range
≔  θ                                Assign to variable `q`
       χ                            Predefined variable 10
      Φ                             Filter on implicit range
         ι                          Current value
          θ                         Variable `q`
        ⁻                           Subtract
     ‽                              Random element
    ≔      η                        Assign to variable `h`
                    χ               Predefined variable 10
                   Φ                Filter on implicit range
                       ι  ι         Current value
                        θ           Variable `q`
                           η        Variable `h`
                      ⁻  ⁻          Subtract
                     ×              Multiply
                  ‽                 Random element
               θθ                   Variable `q`
                 η          η       Variable `h`
              ⟦              ⟧      Wrap 5 values into array
             I                      Cast array elements to string
            ↑                       Make array print horizontally
                                ²   Literal 2
                               ‽    Random element from implicit range
                              ¿     If
                                 ‖  Reflect
\$\endgroup\$
2
\$\begingroup\$

Retina, 40 bytes


10*
Y`w`d
V?`
Lv$7`.(.)
$1$<'$'
O?`...?

Try it online!

Can print strings with leading zeros.

Explanation


10*

Initialise the string to 10 underscores.

Y`w`d

Cyclically transliterate word characters to digits. This is a bit weird. The w and d are short for the following strings, respectively:

w: _0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
d: 0123456789

Cyclic transliteration means that first, both strings are repeated to the length of the their LCM:

_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_012345...
0123456789012345678901234567890123456789012345678901234567890123456789...

Since the string lengths 53 and 10 are coprime, each copy of _ is paired with a different digit. And now cyclic transliteration will replace the ith copy of _ with the ith pairing in that expanded list. So we end up with the following string:

0369258147

All of that to save a single byte over the literal string 0369258147, so yay I guess? :D

Anyway, we've got a string of all 10 digits now.

V?`

This shuffles the digits. So the first three digits will be a uniformly random selection of three distinct digits.

Lv$7`.(.)
$1$<'$'

We match the string ...ABC and turn it into BABCC. The way we do this is kinda crazy though and again saves only one byte compared to a more straightforward approach. We first match all overlapping (v) pairs of characters, capturing the second one (.(.)). Then we retain only the 8th match (7, zero-based) which is AB in ...ABC. Then we replace ($) it with: B ($1), ABC ($<' which is the suffix of the match-separator left of the match), C ($' which is the suffix of the match itself).

O?`...?

Finally, we match either 3 or 2 characters and shuffle the matches, giving us either BABCC or CCBAB at random.

\$\endgroup\$
2
\$\begingroup\$

R, 78 bytes

z=sample(0:9,3)[c(2,1:3,3)];cat(paste(`if`(runif(1)>.5,z,rev(z)),collapse=''))

Try it online!

sample picks 3 random values from 0:9, which are placed in a vector like so: a b a c c. Now we have a 50/50 chance to reverse this vector, and then concatenate and print.

\$\endgroup\$
  • \$\begingroup\$ Very nice! 62 bytes; looks like you're a little out of practice ;) \$\endgroup\$ – Giuseppe Mar 10 '18 at 14:28
  • \$\begingroup\$ I looked at using rt, but for some reason I thought it was longer.... \$\endgroup\$ – JAD Mar 10 '18 at 14:34
  • \$\begingroup\$ And the ( as no-op is a good find :) \$\endgroup\$ – JAD Mar 10 '18 at 14:34
  • \$\begingroup\$ @Giuseppe your asnwer can be golfed further to 55 bytes... TIO \$\endgroup\$ – JayCe Aug 8 '18 at 13:20
2
\$\begingroup\$

PHP, 73 72 66 bytes

<?=strtr(rand()%2?AABCB:BCBAA,ABC,join(array_rand(range(0,9),3)));

Edit: 66 bytes thanks to @David 's suggestion.

Try it online!

\$\endgroup\$
  • \$\begingroup\$ You can get it to 65 with this: <?=strtr(rand()%2?AABCB:BCBAA,ABC,rand(0,9).rand(0,9).rand(0,9)); \$\endgroup\$ – Davіd Mar 13 '18 at 21:01
  • \$\begingroup\$ @David Unfortunately your solution violates rule 5. It could be like rand(0,3).rand(4,6).rand(7,9), but then again is not "uniformly random". Btw. I wasn't familiar with rand()%2, so your comment helped me to slightly improve my solution anyway. \$\endgroup\$ – retrowaver Mar 13 '18 at 22:08
  • 1
    \$\begingroup\$ ah, yes, you're right. I didn't see that rule. I've got one that works now, at 66 bytes: <?=strtr(rand()%2?AABCB:BCBAA,ABC,join(array_rand(range(0,9),3)));. You can test that the array_rand's second parameter only returns unique results here (tested over 10000 iterations). \$\endgroup\$ – Davіd Mar 14 '18 at 13:59
  • \$\begingroup\$ @David thanks, just updated my post! \$\endgroup\$ – retrowaver Mar 14 '18 at 19:31
1
\$\begingroup\$

Red, 147, 146 125 bytes

func[][b: copy[]d:[1 1 2 3 2]if 1 = random 2[d: reverse d]while[4 > length? b][alter b(random 10)- 1]foreach a d[prin b/(a)]]

Try it online!

Ungolfed:

f: func[] [                       function with no arguments
    b: copy []                    an empty list
    d: [1 1 2 3 2]                preset digits at positons
    if 1 = random 2 [             generate 1 or 2 
        d: reverse d]             based on this choose to reverse the positions list
    while [4 > length? b] [       while we haven't chosen 3 different digits
        alter b (random 10) - 1   pick a random digit, if it's not in the list already
                                  append it to the list, otherwise remove it
    ]
    foreach a d [                 for each position
       prin b/(a)]                print the corresponding digit 
]
\$\endgroup\$
1
\$\begingroup\$

Wolfram Language (Mathematica), 59 bytes

{{#,##,#2},{#2,##,#3}}~r~1&@@(r=RandomSample)[0~Range~9,3]&

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Ruby, 60 59 bytes

->{a,b,c=[*0..9].sample 3;[[a,a,b,c,b],[b,c,b,a,a]].sample}

Try it online!

It returns a list of digits.

\$\endgroup\$
1
\$\begingroup\$

Python 3 +numpy, 69 bytes

from pylab import*
r=choice
i=r(2)
print(r(10,3,0)[[1-i,0,1,2,-1-i]])

Explanation

from pylab import*     
r=choice               # `choice` takes a range, number of samples, and wether repetition is allowed
i=r(2)                 # Single value in [0,1] to specify if repeated digits come on right or left
print(r(10,3,0)[[1-i,0,1,2,-1-i]])    # Construct output using index list and 3 random integers
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 126 119 bytes

-6 bytes from @ceilingcat

#define R time(0)%10
b,n,m,k;f(){b=R^8;for(n=R;m==n|k==m|k==n;m=R,k=R);printf("%d%d%d%d%d",b?n:m,b?n:k,m,b?k:n,b?m:n);}

Try it online!

\$\endgroup\$
0
\$\begingroup\$

J, 35 bytes

[:u:48+[:|.^:(?&2:)2 2 1 0 1{3?10"_

Try it online!

I'm sure it can be golfed much further.

Explanation:

  3?10             - generates 3 different digits
7 0 3

  2 2 1 0 1{       - constructs a list using digits positions 0, 1 and 2

  2 2 1 0 1{3?10   
3 3 0 7 0

  |.^:(?&2:)       - generates 0 or 1 and if 1, reverses the list 

  |.^:(?&2:)2 2 1 0 1{3?10
0 7 0 3 3

   u:48+              - converts to char by adding 48 to each digit
   u:48+|.^:(?&2:)2 2 1 0 1{3?10
07033
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.