Создайте список с номерами до 50000


24

Snake Number Challenge

Интересно, сколько змеевых чисел существует от 1 до 50000?

Змея на Nokia

Змеиные цифры в этой игре - это числа, которые можно набирать на традиционной цифровой клавиатуре (формат ниже), перемещая одну клавишу вверх, вниз, влево или вправо.

7 8 9
4 5 6
1 2 3
 0

Например, если вы начнете с цифры 5, вы можете выбрать 4, 6, 8 или 2 в качестве следующего допустимого шага - однако 7, 3, 9 и 1 являются недопустимыми, поскольку они расположены по диагонали к текущей клавише. , Итак, если у вас есть 5, то 2, ваш следующий жизнеспособный выбор ключа снова будет 0, 1, 3 или 5.

В этом упражнении Code Golf вы должны вывести список всех положительных чисел от 1 до 50k, а также окончательное количество всех чисел, которые соответствуют критерию.

правила

  1. Числа не могут начинаться с нуля.
  2. Числа должны быть целыми положительными целыми числами.
  3. Каждый последовательный номер, читаемый слева направо, должен «змейиться» вокруг цифровой клавиатуры.
  4. Змея не может путешествовать по диагонали через ключи
  5. Номер 0 доступен как из номеров 1, так и из 2.
  6. Числа не могут быть соединены (например: 22)

Примеры действительных номеров змеи:

12369
45201
1254
10102
1
12
987

Примеры неверных номеров

1238 - 8 is not connected
0001 - multiple leading 0s
0101 - leading 0
159  - snake cannot travel diagonally
4556 - duplicate 5

В соответствии с нормой Code Golfs, цель - наименьшее количество байтов!

Согласно моей математике и правилам, в вашем списке должно быть 670 действительных чисел змеи, а само 670 напечатано как последнее число.


2
Должен ли быть отсортирован вывод? Или это разрешено в любом порядке?
TSH

2
Поскольку вы просите нас вывести фиксированный и конечный набор целых чисел, я бы предложил включить полный список в спецификацию.
Лохматый


4
Это подмножество A215009 .
bigyihsuan

Было бы хорошо сначала напечатать 670 ?
Дана

Ответы:


14

K (нгн / к) , 60 57 байт

(x;#x:{*/1=3!5&+/x*x:+1_-':(+0 1,'2*!3 3)@10\x}#1+!50000)

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

!50000список 0..49999

1+ добавить 1 ко всем

{ }# фильтр с функцией в { }

10\x десятичные цифры аргумента

( )@ использовать в качестве индексов в ...

  • !3 3 пара списков: (0 0 0 1 1 1 2 2 2;0 1 2 0 1 2 0 1 2)

  • 2* умножить все на 2

  • 0 1,'приставить 0к первому списку и 1ко второму

  • +транспонировать (пара списков -> список пар). это дает нам приблизительные координаты кнопки.

-':вычтите из каждой пары предыдущую пару. использовать 0 0как воображаемый элемент перед первым.

1_ брось первый

+ транспонирования

x*x:квадрат (назначить xи умножить на x). вот xпара списков - ∆xs и ∆ys

+/ суммировать два списка (элемент за элементом)

5& мин с 5

3! мод 3

1= логический список, где он равен 1

*/ продукт (логическое «и»)

(x;#x: )составить пару результата и длину ( #) результата


9

Желе ,  24  23 байта

5ȷ4µDo1.’d3ZIASĊ’ẸµÐḟṄL

Полная программа, которая печатает список всех результатов, а затем количество результатов.

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

Как?

5ȷ4µDo1.’d3ZIASĊ’ẸµÐḟṄL - Main Link: no arguments
5ȷ4                     - 5*10^4 = 50000
   µ              µÐḟ   - filter discard those for which this is truthy:
                        -                  e.g.: 8520        ... or           4559 
    D                   -   decimal digits       [8,5,2,0]                    [4,5,5,9]
      1.                -   literal 1.5
     o                  -   logical OR           [8,5,2,1.5]                  [4,5,5,9]
        ’               -   decrement            [7,4,1,0.5]                  [3,4,4,8]
         d3             -   div-mod by 3         [[2,1],[1,1],[0,1],[0,0.5]]  [[1,0],[1,1],[1,1],[2,2]]
           Z            -   transpose            [[2,1,0,0],[1,1,1,0.5]]      [[1,1,1,2],[0,1,1,2]]
            I           -   deltas               [[-1,-1,0],[0,0,-0.5]]       [[0,0,1],[1,0,1]]
             A          -   absolute value       [[1,1,0],[0,0,0.5]]          [[0,0,1],[1,0,1]]
              S         -   sum (vectorises)     [1,1,0.5]                    [1,0,2]
               Ċ        -   ceiling              [1,1,1]                      [1,0,2]
                ’       -   decrement            [0,0,0]                      [0,-1,1]
                 Ẹ      -   any?                 0 (i.e. keep)                1 (i.e. discard)
                     Ṅ  - print and yield
                      L - length
                        - implicit print

Я хотел бы знать, как это работает. Есть ли шанс, что вы могли бы дать срыв?
MightBeAlon

1
@MightBeAlon сделает позже ...
Джонатан Аллан

Мне любопытно, как 1.оценивать 1.5?
Воплощение Невежества

@EmbodimentofIgnorance во время синтаксического анализа пропущенной цифры после точки рассматривается как пять. Смотрите последнее условие else parse_literal в interpreter.py
Джонатан Аллан

7

Python 3 , 140 байт

f=lambda s:''==s[1:]or s[1]in'10021234562216565878 43 749 9   5  8'[int(s[0])::10]and f(s[1:])
print(*filter(f,map(str,range(1,50000))),670)

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

Я уверен, что кто-то сможет сделать это с помощью выражения вместо строки поиска.


7

Python 2 , 101 байт

print[n for n in range(1,50000)if all(`n`[i:i+2]in`0x20b33ec8bc49a10589e76b15`for i in range(4))],670

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

Шестнадцатеричное число является десятичным 10120214525632365878969854741, которое кодирует каждую упорядоченную пару цифр, которые могут появляться рядом друг с другом.


5

JavaScript (V8) ,  112 106  104 байта

Сохранено 2 байта благодаря @NahuelFouilleul

Полная программа.

for(n=0;++n<5e4;)[...n+''].every(x=>'6589632145201478'.match(x+p+'|'+p+(p=x)),p='')&&print(n)
print(670)

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

Или 96 байт, если мы можем вывести числа в обратном порядке:

for(n=5e4;n--;)[...n+''].every(x=>'6589632145201478'.match(x+p+'|'+p+(p=x)),p='')&&print(n||670)

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


работает также удаление последнего, 3возможно, потому что 36уже в строке
Науэль Фуйе

@NahuelFouilleul Хороший улов. Благодарность!
Арно

1
также 6589632145201478на один байт короче
Науэль Фуйе

4

Stax , 37 35 байт

ü╞╡~▄ⁿ♪eµïê◙ü╔ï▼ΔJr¥æ≤PH╟♀I♣Δz8─¶Γ╞Ç▓

Запустите и отладьте его на staxlang.xyz!

Это было так мило и коротко, пока не стало.

Распакованный (42 байта) и пояснения

49999{E2B{{om"#qYY>!(AFI"%A|E2B{{om-C_Qf%p
49999{                                 f      Filter range [1..49999]:
      E2B                                       All adjacent pairs of digits
         {{om                                   Each sorted
             "#qYY>!(AFI"%A|                    Literal 2012365478963258741
                            E2B{{om             Pairs of digits, each sorted
                                   -            Set difference
                                    C           Cancel block execution if any remain
                                     _Q         Print current value
                                        %p    Print length

2012365478963258741 кодирует клавиатуру. Посмотрите на пары соседних цифр. Возможно, если бы я мог получить прилично короткую альтернативу, которая идет в обоих направлениях для каждой пары, я мог бы сократить восемь байтов{{om .

Без этого конечного 670 достаточно простого фильтра: f..!вместо {..C_Qf%p. Там может быть лучший способ справиться с этой нерегулярностью. В любом случае это поведение диапазона фильтра недокументировано.


Извините за пробелы в документации. FWIW, этот будет в следующем выпуске, 1.1.7. Вы можете увидеть предварительный просмотр на stax.tomtheisen.com , но это секрет, поэтому никому не говорите. ;)
рекурсивный

3

PHP , 145 байт

for(;$i++<5e4;$f&&print$i._)for($f=1,$l=b;''<$d=("$i")[$$i++];$l=$d)$f&=$l>a||strstr([12,240,1053,26,157,2468,359,48,579,68][$l],$d)>'';echo 670;

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

Для каждого числа от 1 до 50 000 проверяет каждую цифру этого числа слева направо. Если все цифры находятся в списке действительных цифр предыдущей цифры, этот номер печатается. В конце печатается жесткий код 670, так как он занимает меньше байтов, чем фактически подсчитывает.


3

05AB1E , 23 байта

ŽÅKLʒSÌYX;:3‰üαï€OP}=g=

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

Порт Джонатана Аллана желе ответ .


1
Ах, умно просто сжать 50000 в 3 байта. Я использовал ₄50*или 4°5*когда делал попытку раньше. И сначала я был смущен , почему у вас €OPвместо того , чтобы просто OP, но потом я понял , одиночные значные номера (будучи пустой список после того , как üα) затем будет [] → 0 → 0вместо [] → [] → 1. :)
Кевин Круйссен

1
@KevinCruijssen Почему, 4°5*когда вы можете 5°;? Хотя мне больше нравится ZAK. И да, тот крайний случай для однозначных чисел - боль.
Гримми

3

Perl 5 ( -M5.01), 96 , 92 байта

-4 байта благодаря @Xcali

$r=join"|",map$t++."[^$_]",12,240,1350,26,157,2648,359,48,579,68;map/$r/||say,1..5e4;say 670

TIO



спасибо, действительно, слишком сложно, потому что первый ответ был положительный матч
Науэль Фуйе

3

JavaScript (SpiderMonkey) , 179 173 151 129 байт

[12,240,1350,26,157,2468,359,48,579,68].map((_,i,l)=>i&&(f=(v,t)=>print(v)|v<5e3&&[...l[t]+''].map(k=>f(v+k,k)))(i,i)),print(670)

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

-22 байта спасибо Дане -22 байта спасибо Дане

объяснение:

[12,240,1350,26,157,2468,359,48,579,68] 
// an array where keys are current position and values, the possible destinations
.map((_,i,l)=>                    // loop over it
    i&&(                          // if key is not 0
        f=(v,t)=>                 // create a function
                 print(v)|        // which print the value
                          v<5e3&& // and if the limit is not attained
                                 [...l[t]+''].map(k=>f(v+k,k)) 
                    // recurcively call itself with for each destinations
                                                              )(i,i)),
                    // make the first call with each digit
print(670) // finally print 670

@dana также дала решение 123 байта, если мы можем сначала напечатать 670

[21,420,5310,62,751,8642,953,84,975,86].map((_,i,a)=>(f=(v,t)=>print(i?v:640)|i&v<5e3&&[...a[t]+''].map(k=>f(v+k,k)))(i,i))

@Arnauld спасибо, я забыл это правило
Джонатжано



123, если 640 может быть напечатан первым.
Дана


2

Stax , 28 26 байт

Δh┤♣É╦&·é╝n$K»à¶▲v═NÆ;↨m≥8

Запустите и отладьте его

Распакованный, размазанный и прокомментированный, это выглядит так.

G               Call to unbalanced trailing '}', then resume here
670P            Print 670
}               Call target
219J            219 squared (47961)
f               Filter 1-based range by the rest of the program; implicitly output
  $2B           Convert to string and get adjacent pairs; e.g. 213 -> ["21", "13"]
  O             Push 1 under list of pairs
  F             Iterate over pairs, using the rest of the program
    o           Order each pair; e.g. "21" -> "12"
    "{<f:[/T8Z" string literal with code points [123 60 102 58 91 47 84 56 90]
    $           concate as string i.e. "12360102589147845690"
    s#          How many times does the current pair appear in the constant string?
    *           Multiply this by running total.  Any zero will cause the result to be zero.

Запустите этот

Секретный соус в буквальном смысле слова "{<f:[/T8Z". После объединения всех кодовых точек, вы получите 12360102589147845690. Восходящие пары в этой строке являются допустимыми движениями змеи.


1
15JJвместо того, 219Jчтобы работать, но я не думаю, что вы можете сыграть в гольф любой байт оттуда, если нет константы в 1 байт для 15.
Арно


1

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

≔ΦI…·¹×⁵⁰φ⬤ι№”)¶∧XRτ_ΠGêR⁵m⎇λ”✂ιμ⁺²μ¹θθILθ

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

≔ΦI…·¹×⁵⁰φ

Процесс инклюзивного диапазона от 1до 50,000преобразованного в строку.

⬤ι№”)¶∧XRτ_ΠGêR⁵m⎇λ”✂ιμ⁺²μ¹θ

Отфильтруйте те, у которых есть пары цифр, не содержащиеся в сжатой строке 01478963202125458565236987410.

θILθ

Выведите оставшийся массив и его длину.



1

Perl 6 , 64 байта

{670,grep {[+&](:36<12HGX91H8VCL3MG0FDVQ>X+>m:ov/../)%2},1..5e4}

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

объяснение

{670,grep {...},1..5e4}  # Meet questionable output requirements

# Actual decision problem

     :36<12HGX91H8VCL3MG0FDVQ>  # Bit field of allowed transitions
                                # encoded in base 36
                                 m:ov/../  # All 2-digit substrings
                              X+>  # Right shift by each substring
                                   # (implicitly converted to an integer)
[+&](                                    )  # Binary and
                                          %2  # Modulo 2

Жаль, что он ~>еще не реализован, иначе вы могли бы сделать это только с помощью строковых операторов, а битовое поле - это строка
Джо Кинг,

1

Pyth , 68 65 45 байт

l
f.Am}dCtB+J`65874589632012541_PJCtB`TS50000

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

Вдохновение для пересмотренного процесса поиска пришло от ответа Халдрасет на'Барьи в Stax , иди дать им голос!


Редактировать 2: переписано, чтобы сохранить кучу байтов, предыдущая версия:

l
f.Am}ed@c"12 024 0135 26 157 2468 359 48 579 68";shdCtB`TS50000

Редактировать: Гольф 3 байта с помощью поиска строк, предыдущая версия:

l
f.Am}ed@sMMc"12 024 0135 26 157 2468 359 48 579 68";hdCtBjT;S50000
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.