EASY to memorize numbers

41

4

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!

drham

Posted 2018-03-09T04:03:02.313

Reputation: 515

Does every possible easy to memorize number have to be able to appear as output? Should the random choice be uniform? – Jonathan Frech – 2018-03-09T04:25:58.243

@JonathanFrech Yes and yes – drham – 2018-03-09T04:28:45.500

5I 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). – Khuldraeseth na'Barya – 2018-03-09T04:29:51.777

9Do we have to print an output like 09033 with a leading zero? – xnor – 2018-03-09T04:57:32.250

3

If the probability is uniform, can you specify that in the question. By default, random does not mean uniformly so

– Jo King – 2018-03-09T05:35:48.513

3maybe add 99233, for conveniewnce to understand – l4m2 – 2018-03-09T05:51:24.467

3Welcome to PPCG! Nice first challenge. – Jonathan Allan – 2018-03-09T13:19:09.893

@xnor, since some languages will most likely need to use numbers instead of arrays of numbers, you can decide whether or not you output numbers with leading zeroes. But do not output any numbers that are 4 or 3 in length because the zero(es) was/were chopped off – drham – 2018-03-09T15:47:23.100

@Downvoter what can I improve? – drham – 2018-03-09T21:34:48.427

"Outputs that have a pair of zeroes are not required to output the leading zero, but if omitted, make sure that you do not output something like 6088, chopping the first zero off." ... um, what? – mbomb007 – 2018-03-09T22:59:38.677

1@DLosc Yeah I'm sorry, I'm not quite sure how to word it. Your interpretation is correct. Please feel free to edit your alternate explanation in. – drham – 2018-03-09T23:49:25.033

@DLosc looks great, thanks – drham – 2018-03-10T07:08:29.083

It’s 0118-999-881-999-119-725......3 – Stan Strum – 2018-03-12T18:15:58.770

Answers

21

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

Emigna

Posted 2018-03-09T04:03:02.313

Reputation: 50 798

I wonder if Emigna ha... sees top answer +1. – Magic Octopus Urn – 2018-03-13T19:43:00.947

9

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!

Xcali

Posted 2018-03-09T04:03:02.313

Reputation: 7 671

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!

– Dom Hastings – 2018-03-09T06:22:07.667

1

Hash randomization. Brilliant! shorter

– Ton Hospel – 2018-03-09T07:17:35.680

The question is whether or not time%2 is sufficiently random, since it is, in a sense, under the control of the user. – Xcali – 2018-03-09T19:12:03.713

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

– FryAmTheEggman – 2018-03-09T21:43:53.060

9

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.

Peter Taylor

Posted 2018-03-09T04:03:02.313

Reputation: 41 901

8

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.

ovs

Posted 2018-03-09T04:03:02.313

Reputation: 21 408

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.

– xnor – 2018-03-09T21:02:54.297

7

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.

J. Sallé

Posted 2018-03-09T04:03:02.313

Reputation: 3 233

Input cannot be given – drham – 2018-03-09T20:11:55.883

@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. – J. Sallé – 2018-03-09T20:13:59.720

The fact that g is called in the input section is just a quirk of how APL is set to run on TIO – H.PWiz – 2018-03-09T20:14:46.590

(4∨?2) saves a byte over 1 4[?2] – H.PWiz – 2018-03-09T20:21:22.387

1You can also save bytes by not assigning to f and using a train. I'll leave that to you though :) – H.PWiz – 2018-03-09T20:27:30.680

@H.PWiz got it :) Thanks for the tip. – J. Sallé – 2018-03-09T20:57:59.897

OK that works I guess – drham – 2018-03-09T20:59:33.030

(1↓⌽,⊢) -> 1↓,∘⌽⍨ – ngn – 2018-03-10T01:55:08.527

typo: GDC -> GCD – ngn – 2018-03-10T12:01:20.460

6

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

Kevin Cruijssen

Posted 2018-03-09T04:03:02.313

Reputation: 67 575

136 bytes – Olivier Grégoire – 2018-03-09T11:41:36.140

@OlivierGrégoire Did you post this at the correct challenge?.. :S It does look familiar, but it's certainly not this challenge.. – Kevin Cruijssen – 2018-03-09T12:04:49.053

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;} – Olivier Grégoire – 2018-03-09T12:55:34.870

@OlivierGrégoire Ah oops, the regex golf (except for || to |) I had already done locally, but after I fixed some things I forgot to post it.. Thanks for the 1e5 and | golf! – Kevin Cruijssen – 2018-03-09T13:01:44.820

1I think your regex can be shortened to (.).*\\1(.).*\\2, saving 11 bytes. – Rick Hitchcock – 2018-03-09T16:36:16.043

1119 bytes: v->{String r;for(;!(r=(int)(Math.random()*1e5)+"").matches("((.).?\\2){2}")|r.chars().distinct().count()<3;);return r;} – Nevay – 2018-03-12T18:31:15.957

5

Jelly, 23 bytes

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

Try it online!

HyperNeutrino

Posted 2018-03-09T04:03:02.313

Reputation: 26 575

Nice, I would upvote, but I can't – drham – 2018-03-09T04:18:14.810

7@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! – HyperNeutrino – 2018-03-09T04:26:19.590

5

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)

user202729

Posted 2018-03-09T04:03:02.313

Reputation: 14 620

(same idea as the 05AB1E answer, came up with independently) – user202729 – 2018-03-09T07:44:07.303

... 05AB1E get 6 upvotes because of being able to tie Jelly, Jelly only get 2 upvotes because of being unable to win 05AB1E? – user202729 – 2018-03-09T11:16:49.487

2i upvoted your answer. --> SPEECH 100 <--- – L_Church – 2018-03-09T11:46:25.047

4

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.

Arnauld

Posted 2018-03-09T04:03:02.313

Reputation: 111 334

Both && can be &. Also, how does [,,a,b,c,d] work? I've never seen an input like [,, before. – Kevin Cruijssen – 2018-03-09T15:12:01.840

1@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. – Arnauld – 2018-03-09T15:34:21.837

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. – Kevin Cruijssen – 2018-03-09T15:51:39.827

This is just awesome +1 – Luis felipe De jesus Munoz – 2018-03-09T20:23:05.847

4

Perl 6, 42 bytes

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

Try it online!

Sean

Posted 2018-03-09T04:03:02.313

Reputation: 4 136

2

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

Οurous

Posted 2018-03-09T04:03:02.313

Reputation: 7 916

2

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!

retrowaver

Posted 2018-03-09T04:03:02.313

Reputation: 21

You can get it to 65 with this: <?=strtr(rand()%2?AABCB:BCBAA,ABC,rand(0,9).rand(0,9).rand(0,9));

– Ethan – 2018-03-13T21:01:01.860

@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. – retrowaver – 2018-03-13T22:08:35.653

1

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

– Ethan – 2018-03-14T13:59:24.540

@David thanks, just updated my post! – retrowaver – 2018-03-14T19:31:31.407

2

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

Neil

Posted 2018-03-09T04:03:02.313

Reputation: 95 035

2

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.

Martin Ender

Posted 2018-03-09T04:03:02.313

Reputation: 184 808

2

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.

JAD

Posted 2018-03-09T04:03:02.313

Reputation: 2 898

Very nice! 62 bytes; looks like you're a little out of practice ;)

– Giuseppe – 2018-03-10T14:28:35.023

I looked at using rt, but for some reason I thought it was longer.... – JAD – 2018-03-10T14:34:20.890

And the ( as no-op is a good find :) – JAD – 2018-03-10T14:34:55.020

@Giuseppe your asnwer can be golfed further to 55 bytes... TIO

– JayCe – 2018-08-08T13:20:36.893

1

Wolfram Language (Mathematica), 59 bytes

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

Try it online!

alephalpha

Posted 2018-03-09T04:03:02.313

Reputation: 23 988

1

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 
]

Galen Ivanov

Posted 2018-03-09T04:03:02.313

Reputation: 13 815

1

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.

Eric Duminil

Posted 2018-03-09T04:03:02.313

Reputation: 701

1

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!

vazt

Posted 2018-03-09T04:03:02.313

Reputation: 311

1

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

user2699

Posted 2018-03-09T04:03:02.313

Reputation: 538

0

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

Galen Ivanov

Posted 2018-03-09T04:03:02.313

Reputation: 13 815