42
\$\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\$
13
  • 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\$ Mar 9, 2018 at 4:29
  • 9
    \$\begingroup\$ Do we have to print an output like 09033 with a leading zero? \$\endgroup\$
    – xnor
    Mar 9, 2018 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, 2018 at 5:35
  • 3
    \$\begingroup\$ maybe add 99233, for conveniewnce to understand \$\endgroup\$
    – l4m2
    Mar 9, 2018 at 5:51
  • 3
    \$\begingroup\$ Welcome to PPCG! Nice first challenge. \$\endgroup\$ Mar 9, 2018 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\$
1
  • \$\begingroup\$ I wonder if Emigna ha... sees top answer +1. \$\endgroup\$ Mar 13, 2018 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\$
4
  • \$\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\$ Mar 9, 2018 at 6:22
  • 1
    \$\begingroup\$ Hash randomization. Brilliant! shorter \$\endgroup\$
    – Ton Hospel
    Mar 9, 2018 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, 2018 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\$ Mar 9, 2018 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\$
1
  • \$\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, 2018 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\$
9
  • \$\begingroup\$ Input cannot be given \$\endgroup\$
    – drham
    Mar 9, 2018 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, 2018 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, 2018 at 20:14
  • \$\begingroup\$ (4∨?2) saves a byte over 1 4[?2] \$\endgroup\$
    – H.PWiz
    Mar 9, 2018 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, 2018 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\$
6
  • \$\begingroup\$ 136 bytes \$\endgroup\$ Mar 9, 2018 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\$ Mar 9, 2018 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\$ Mar 9, 2018 at 12:55
  • 1
    \$\begingroup\$ I think your regex can be shortened to (.).*\\1(.).*\\2, saving 11 bytes. \$\endgroup\$ Mar 9, 2018 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, 2018 at 18:31
5
\$\begingroup\$

Jelly, 23 bytes

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

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Nice, I would upvote, but I can't \$\endgroup\$
    – drham
    Mar 9, 2018 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\$
    – hyper-neutrino
    Mar 9, 2018 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\$
3
  • \$\begingroup\$ (same idea as the 05AB1E answer, came up with independently) \$\endgroup\$
    – DELETE_ME
    Mar 9, 2018 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\$
    – DELETE_ME
    Mar 9, 2018 at 11:16
  • 2
    \$\begingroup\$ i upvoted your answer. --> SPEECH 100 <--- \$\endgroup\$
    – L_Church
    Mar 9, 2018 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\$
4
  • \$\begingroup\$ Both && can be &. Also, how does [,,a,b,c,d] work? I've never seen an input like [,, before. \$\endgroup\$ Mar 9, 2018 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, 2018 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\$ Mar 9, 2018 at 15:51
  • \$\begingroup\$ This is just awesome +1 \$\endgroup\$ Mar 9, 2018 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\$
4
  • \$\begingroup\$ Very nice! 62 bytes; looks like you're a little out of practice ;) \$\endgroup\$
    – Giuseppe
    Mar 10, 2018 at 14:28
  • \$\begingroup\$ I looked at using rt, but for some reason I thought it was longer.... \$\endgroup\$
    – JAD
    Mar 10, 2018 at 14:34
  • \$\begingroup\$ And the ( as no-op is a good find :) \$\endgroup\$
    – JAD
    Mar 10, 2018 at 14:34
  • \$\begingroup\$ @Giuseppe your asnwer can be golfed further to 55 bytes... TIO \$\endgroup\$
    – JayCe
    Aug 8, 2018 at 13:20
2
\$\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\$
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\$
4
  • \$\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\$
    – Ethan
    Mar 13, 2018 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, 2018 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\$
    – Ethan
    Mar 14, 2018 at 13:59
  • \$\begingroup\$ @David thanks, just updated my post! \$\endgroup\$
    – retrowaver
    Mar 14, 2018 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\$

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
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 and acknowledge that you have read and understand our privacy policy and code of conduct.

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