Легко запомнить номера

41

Числа, которые легко запомнить, но теоретически нелегко

Ваша задача состоит в том, чтобы создать программу / функцию на любом языке, которая генерирует равномерно случайные числа, соответствующие этим критериям:

  1. Длина составляет 5 цифр

  2. Есть две отдельные пары повторяющихся цифр

  3. Один набор повторяющихся цифр находится в начале или в конце, и цифры находятся рядом друг с другом

  4. Нечетное число вне окружено другой парой цифр

  5. Две пары цифр и другое число должны быть уникальными

  6. Ваша программа может поддерживать числа с ведущими нулями или нет по вашему усмотрению. Если ведущие нули поддерживаются, они должны быть включены в выходные данные: 06088, а не 6088. Если начальные нули не поддерживаются, то числа, подобные 06088, вообще не должны генерироваться.

Тестовые случаи

Принятые выходы:

55373
55494
67611
61633
09033
99757
95944
22808
65622
22161

Не принятые результаты:

55555
77787
85855
12345
99233
12131
ABCDE
5033

Более приемлемые тестовые примеры можно найти по этой ссылке .

Они были сделаны с помощью этой программы Python:

импортировать случайный
для меня в диапазоне (100):

    if random.randint (0,100)> = 50: # Поместить пару в начало, если это правда
        temp = [] # рабочий массив
        temp.append (random.randint (0,9)) #append случайная цифра
        temp.append (temp [0]) # снова приложить ту же цифру

        x = random.randint (0,9)
        пока x == temp [0]:
            x = random.randint (0,9)
        temp.append (x) #append еще одна уникальная цифра

        y = random.randint (0,9)
        в то время как y == temp [0] или y == temp [2]:
            y = random.randint (0,9)
        temp.append (y) #append еще одна уникальная цифра и предыдущая уникальная цифра
        temp.append (х)

    еще: # Положите касающуюся пару в конце
        temp = [] # рабочий массив  
        temp.append (random.randint (0,9)) #append случайная цифра

        # Пока не уникально, попробуйте еще раз
        x = random.randint (0,9)
        пока x == temp [0]:
            x = random.randint (0,9)
        temp.append (x) #append еще одна уникальная цифра


        temp.append (temp [0]) # снова повторить ту же 0-ую цифру


        y = random.randint (0,9)
        в то время как y == temp [0] или y == temp [1]:
            y = random.randint (0,9)
        temp.append (y) #append еще одна уникальная цифра дважды
        temp.append (у)

    tempstr = ""
    для меня в темп:
        tempstr + = str (i)
    печать tempstr

Это , поэтому выигрывает самый короткий ответ в байтах!

drham
источник
5
Я предлагаю «Возможные выходные данные (вероятность> 0)» и «Невозможные выходные данные (вероятность = 0)», а не «Истина» и «Ложь» - это, кажется, больше соответствует тому, что, по-моему, вы спрашиваете (и Python ).
Хулдрасет на'Барья
9
Нужно ли печатать вывод типа 09033 с начальным нулем?
xnor
3
Если вероятность одинакова, можете ли вы указать это в вопросе. По умолчанию randomэто не значит, что все одинаково
Джо Кинг
3
возможно, добавьте 99233, для удобства, чтобы понять
l4m2
3
Добро пожаловать в PPCG! Хороший первый вызов.
Джонатан Аллан

Ответы:

21

05AB1E , 11 байт

žh.r3£ûÁÂ)Ω

Попробуйте онлайн!

объяснение

ž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
источник
Интересно, Эмигна ха ... видит топ ответ +1.
Волшебный Осьминог Урна
9

CJam (16 байт)

YmrG*98+ZbA,mrf=

Онлайн демо

Примечание: я предположил, что под «уникальным» ОП действительно подразумевается «отличный».

Также для 16 байтов:

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

рассечение

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"

Другие варианты генерируются с использованием [1 0 1 2 2]и затем выбирают либо результат, либо его реверс.

Питер Тейлор
источник
9

Perl 5 , 81 63 56 байт

Вырезать 7 байтов с вдохновением от @DomHastings

Построение номера по соответствующей схеме.

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

Попробуйте онлайн!


Perl 5 , 89 байт

Выбирает случайные 5-значные числа, пока не найдет то, которое соответствует критериям.

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

Попробуйте онлайн!

Xcali
источник
Хороший трюк с использованием хэш-ключей для случайности! Я думаю, что это эквивалентно для -8, хотя я мог пропустить крайний случай ... Попробуйте онлайн!
Дом Гастингс
1
Хэш-рандомизация. Brilliant! короче
Тон Хоспель
Вопрос в том, является ли time%2он достаточно случайным или нет , поскольку в некотором смысле он находится под контролем пользователя.
Xcali
@Xcali Похоже, что все в порядке, если вы используете его только один раз, поэтому я думаю, что вы должны быть хорошими.
FryAmTheEggman
8

Python 2 , 80 байт

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

Попробуйте онлайн!

Выводит список цифр.

Python 2 , 83 байта

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

Попробуйте онлайн!

Выход - это число.

овс
источник
Если по умолчанию разрешена неоднородная случайность (вопрос не уточняется), вы можете сохранить байты, также проверяя обратное: попробуйте онлайн! Редактировать: Неважно, я вижу, единообразие было отредактировано в спецификации. Интересно, можно ли спасти этот подход?
xnor
7

APL (Dyalog Unicode) , 22 21 20 18 17 байт

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

Попробуйте онлайн!

Если это приемлемо для вывода цифры всегда в том же формате, это может быть сокращено до 12 байт, либо 1⌽1↓,∘⌽⍨3?10или 3⌽1↓,∘⌽⍨3?10.

Сохранил байт, удалив ненужное .

Благодаря H.PWiz сохранен байт, а затем еще 2 байта благодаря их подсказке.

Сохраненный байт благодаря ngn.

Функция предполагает ⎕IO←0( I ndex O rigin).


Как?

(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. (30=3; 31=1.)
                    This yields either 1 1 2 3 2 or 2 3 2 1 1.
Ж. Салле
источник
Вход не может быть дан
drham
@drham нет ввода в функцию. В этом случае поле TIO Inputиспользуется для вызова функции g. Кроме того, значение g←не учитывается при подсчете байтов, поскольку это необязательно, оно используется только для вызова функции.
Ж. Салле
Тот факт, что gвызывается в разделе ввода, является всего лишь особенностью того, как APL настроен для работы на
TIO
(4∨?2)сохраняет байт больше1 4[?2]
H.PWiz
1
Вы также можете сохранить байты, не назначая fи не используя поезд. Я оставлю это для вас , хотя :)
H.PWiz
6

Ява 8, 145 136 125 119 байт

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

-9 байт благодаря @ OlivierGrégoire.
-11 байт благодаря @RickHitchcock .
-6 байт благодаря @Nevay .

Объяснение:

Попробуйте онлайн.

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
Кевин Круйссен
источник
136 байт
Оливье Грегуар,
@ OlivierGrégoire Вы разместили это на правильном вызове? ..: S Это выглядит знакомо, но это, конечно, не этот вызов ..
Кевин Круйссен,
Эта штуковина сломала мою связь ... В любом случае, вот гольф:v->{String r="";for(;!r.matches("(.)\\1(.).\\2|(.).\\3(.)\\4")|r.chars().distinct().count()!=3;r=(int)(Math.random()*1e5)+"");return r;}
Оливье Грегуар,
1
Я думаю, что ваше регулярное выражение может быть сокращено до (.).*\\1(.).*\\211 байтов.
Рик Хичкок
1
119 байт:v->{String r;for(;!(r=(int)(Math.random()*1e5)+"").matches("((.).?\\2){2}")|r.chars().distinct().count()<3;);return r;}
Nevay
5

Желе , 23 байта

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

Попробуйте онлайн!

HyperNeutrino
источник
Хорошо, я бы проголосовал, но я не могу
drham
7
@drham :) спасибо. Вы должны быть в состоянии скоро, как только большинство активных участников проснется, ваш вопрос, вероятно, получит много голосов. хороший первый вызов и добро пожаловать в PPCG, кстати!
HyperNeutrino
5

Желе , 12 11 байт

ØDẊ⁽0yṃ,U$X

Попробуйте онлайн!


объяснение


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

(*) Правильный аргумент - ['0','1','2',...,'9']случайный список , состоящий из 10 элементов. Таким образом, число 13122будет преобразовано в биективное основание 10 ( [1,3,1,2,2]) и индекс в список (так что если список есть l, возвращаемое значение атома [l[1],l[3],l[1],l[2],l[2]], где Jelly использует индексирование на основе 1)

user202729
источник
(та же идея, что и в ответе 05AB1E, пришла независимо)
user202729
... 05AB1E получает 6 голосов за способность связать Желе, а Желе только 2 голоса из-за невозможности выиграть 05AB1E?
user202729
2
я проголосовал за твой ответ. -> РЕЧЬ 100 <---
L_Church
4

JavaScript (ES6), 79 байт

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

Попробуйте онлайн!

Как?

Math.random()дает случайное плавание в [0..1) . Мы используем +fдля принуждения к строке. Мы игнорируем ведущий ноль и десятичную точку, выполняя [,,( деструктурируя присвоение первых двух символов нулю ), и собираем первые 4 десятичных знака в d , a , b и c .

Если , b и c представляют собой 3 разных целых числа, мы создаем окончательный вывод в формате AABCB или BCBAA (используя четность d для принятия решения). В противном случае мы попробуем еще раз, пока они не будут.

В крайне маловероятном случае Math.random()возврата значения без достаточного количества десятичных разрядов, по крайней мере, c будет установлен в нецифровый символ, что приведет к сбою теста и выполнению рекурсивного вызова. Если а , б и c являются действительными целыми числами, то d также гарантированно является действительным целым числом, так что это не нужно проверять.

Arnauld
источник
Оба &&могут быть &. Кроме того, как [,,a,b,c,d]работает? Я никогда не видел вход, как [,,раньше.
Кевин Круйссен
1
@KevinCruijssen Побитовое И не получится, например, a=4, b=2, c=1потому что 4-2&4-1&2-1 == 2&3&1 == 0. Я добавил краткое объяснение о назначении переменной.
Арно
Ну конечно. Я просто попытался , &&чтобы &в TIO и он дал правильные выходы, поэтому я предположил , что это было возможно. Не понял, &вместо того, &&чтобы отфильтровать в противном случае действительные результаты. И спасибо за добавленное объяснение о назначении деструктуры, никогда не видела его раньше.
Кевин Круйссен
Это просто потрясающе +1
Луис Фелипе Де Иисус Муньос
2

Грязный , 33 байта

Использует --numeric-output флаг, чтобы он был читаемым, иначе он выведет строку управляющих символов с кодовыми точками, соответствующими цифрам.

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

Попробуйте онлайн!

Разъяснение:

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
источник
2

Древесный уголь , 34 байта

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

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

  χ                                 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
Нил
источник
2

Сетчатка , 40 байт


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

Попробуйте онлайн!

Может печатать строки с ведущими нулями.

объяснение


10*

Инициализируйте строку до 10 подчеркиваний.

Y`w`d

Циклически транслитерируйте символы слова в цифры. Это немного странно. Символы wи dявляются короткими для следующих строк соответственно:

w: _0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
d: 0123456789

Циклическая транслитерация означает, что сначала обе строки повторяются до длины их LCM:

_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_012345...
0123456789012345678901234567890123456789012345678901234567890123456789...

Поскольку длины строк 53 и 10 взаимно просты, каждая копия _соединяется с другой цифрой. И теперь циклическая транслитерация заменит i- ую копию _с i- й парой в этом расширенном списке. Таким образом, мы получаем следующую строку:

0369258147

Все это, чтобы сохранить один байт над литеральной строкой 0369258147 , так что, да, я думаю? : D

В любом случае, у нас есть строка из 10 цифр.

V?`

Это перемешивает цифры. Таким образом, первые три цифры будут равномерно случайным выбором трех различных цифр.

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

Мы сопоставляем строку ...ABCи превращаем ее в BABCC. То, как мы это делаем, довольно безумно, и опять же экономит только один байт по сравнению с более простым подходом. Сначала мы сопоставляем все пары символов перекрытия ( v), захватывая вторую ( .(.)). Тогда мы сохраняем только восьмой матч (с 7нуля), который находится ABв ...ABC. Затем мы заменяем ( $) на: B( $1), ABC( $<'который является суффиксом разделителя совпадений слева от совпадения) C( $'который является суффиксом самого совпадения).

O?`...?

Наконец, мы сопоставляем либо 3 или 2 символа и перетасовать спички, давая нам либо BABCCили CCBABв случайном порядке.

Мартин Эндер
источник
2

R , 78 байт

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

Попробуйте онлайн!

sample3 выбирает случайные значения из 0:9, которые расположены в векторе таким образом: a b a c c. Теперь у нас есть 50/50 шанс изменить этот вектор, а затем объединить и напечатать.

JAD
источник
Очень хорошо! 62 байта ; Похоже, вы немного потренировались;)
Джузеппе
Я смотрел на использование rt, но по какой-то причине я думал, что это дольше ....
JAD
И (как не-опера - хорошая находка :)
JAD
@Giuseppe ваш asnwer может быть golfed дополнительно до 55 байт ... Тио
Jayce
2

PHP, 73 72 66 байт

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

Редактировать: 66 байт благодаря предложению @David.

Попробуйте онлайн!

retrowaver
источник
Вы можете получить его до 65 с этим:<?=strtr(rand()%2?AABCB:BCBAA,ABC,rand(0,9).rand(0,9).rand(0,9));
Давид
@David К сожалению, ваше решение нарушает правило 5. Это может быть похоже rand(0,3).rand(4,6).rand(7,9), но, опять же, не «равномерно случайным». Btw. Я не был знаком с rand()%2, так что ваш комментарий помог мне немного улучшить мое решение в любом случае.
ретровер
1
ах да, ты прав. Я не видел это правило. У меня есть тот , который работает сейчас, в 66 байт: <?=strtr(rand()%2?AABCB:BCBAA,ABC,join(array_rand(range(0,9),3)));. Вы можете проверить, что array_randвторой параметр возвращает здесь только уникальные результаты (проверено более 10000 итераций).
Давид
@ Давид спасибо, только что обновил мой пост!
ретровер
1

Красный , 147, 146 125 байт

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

Попробуйте онлайн!

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 
]
Гален Иванов
источник
1

Python 3 + NumPy, 69 байт

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

объяснение

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
источник
0

J 35 байт

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

Попробуйте онлайн!

Я уверен, что это может быть гораздо дальше.

Объяснение:

  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
Гален Иванов
источник