Все квадраты, которые соответствуют последовательности символов подстановки [закрыто]


9

Это было вдохновлено частью задачи команды № 6 конкурса ARML 2016 года.

Вот проблема:

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

w = wildcard
s = string
# s matches w iff
for all 0 >= i > wildcard.length, w[i] == '?' or s[i] == w[i]

Куда '?' это персонаж по вашему выбору.

С точки зрения регулярных выражений, просто представьте, что '?'это так '.'.

Задача состоит в том, чтобы найти все квадратные числа (требование до 1 миллиона), чьи десятичные строковые представления соответствуют этой последовательности символов подстановки. «Подстановочный знак» может быть любым символом ASCII по вашему выбору, если, конечно, это не цифра.

Так , например, 4096спички 4**6и , 4*9*но 4114не соответствует ни.

вход

Ввод будет дан как последовательность, соответствующая регулярному выражению [0-9?]+. Это может быть строка, массив символов или байтовый массив символов в ASCII.

Вывод

Выходными данными будет список / набор / массив чисел, которые вы хотите разделить, которые являются идеальными квадратами и соответствуют последовательности символов подстановки.

Примеры допустимых входных данных:

1234567*90
1234567?90
1234567u90
['1', '2', '3', '4', '5', '6', '7', '*', '9', '0']
[49, 50, 51, 52, 53, 54, 55, 42, 57, 48]
[1, 2, 3, 4, 5, 6, 7, '*', 9, 0]

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

[1, 4, 9]
1 4 9
1, 4, 9
1-4-9

и т.п.

Характеристики

  • Вы не можете использовать встроенные функции для поиска списка квадратов в определенном диапазоне.
  • Применяются стандартные лазейки
  • Вы должны быть в состоянии обработать до 1 000 000 (1 миллион)
  • Если предоставляется вход 1******, это правильно для печати [1000000]. Также правильно печатать[1000000, 1002001, 1004004, 1006009, 1008016, 1010025, ...]
  • Последовательности подстановочных знаков никогда не начинаются с подстановочного знака; то есть они всегда будут соответствовать строкам одинаковой длины.

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

4**6  ->  [4096, 4356]
1**1  ->  [1521, 1681]
1**  ->  [100, 121, 144, 169, 196]
9****9  ->  [908209, 915849, 927369, 935089, 946729, 954529, 966289, 974169, 986049, 994009]
9*9***  ->  [919681, 929296]
1**0*  ->  [10000, 10201, 10404, 10609, 12100, 14400, 16900, 19600]
9***4  ->  [91204, 94864, 97344]

выигрыш

Самая короткая (действительная) (рабочая) подача до 14 февраля, тай-брейк за самую раннюю подачу.


1
Я думаю, что хорошее начало для ?прояснения этого вопроса - указать, что должен выбрать ответчик.
FryAmTheEggman

2
Почему 25правильный ответ для, ***но не для *2*?
Нил

3
Я думаю, что было бы чище, если бы числа никогда не имели ведущих нулей, поэтому соответствовали только последовательности их длины.
xnor

@Neil Это было бы проблемой с моим собственным решением. Я приму предложение Кснора.
HyperNeutrino

Может ли ввод быть массивом из однозначных целых чисел и специального символа, такого как {4, "w", "w", 6}(или еще лучше {4, w, w, 6}), а не массивом символов, таким как {"4", "w", "w", "6"}?
Грег Мартин

Ответы:


0

05AB1E , 22 байта

Вероятно, здесь есть много возможностей для улучшения.
Любой не цифра в порядке подстановочного знака.

3°LnvyS¹)ø€Æ0QPyg¹gQ&—

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

Объяснение, чтобы прийти после дальнейшего игры в гольф.


Похоже, это работает для всех входов. Отличная работа.
HyperNeutrino

1

Mathematica, 44 байта

Print@@@IntegerDigits[Range@1*^3^2]~Cases~#&

Входные данные представляют собой список цифр с _(без кавычек) в качестве подстановочного знака. например{4, _, _, 6}

объяснение

Range@1*^3

Создать список {1, 2, 3, ... , 1000}

... ^2

Квадрат это. (список всех квадратов от 1 до 1 000 000)

IntegerDigits[ ... ]

Разбейте каждый квадрат на список цифр.

... ~Cases~#

Найдите те, которые соответствуют шаблону, указанному на входе.

Print@@@ ...

Распечатайте их.


Похоже, это работает для всех тестовых случаев. Отличная работа.
HyperNeutrino

1

Брахилог , 23 байта

@e:{@$|,}a#0:{c.~^#I,}f

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

объяснение

@e                        Split into a list of characters
  :{@$|,}a                Replace each digit char by the corresponding digit, and each things
                            that are ot digits into variables
          #0              All elements of the resulting list must be digits
            :{       }f   Output is the result of finding all...
              c.            ...concatenations of those digits which...
               .~^#I,       ...result in a number which is the square of an integer #I

Другой формат ввода, 13 байтов

В зависимости от того, что вы считаете допустимым в качестве входных данных, вы можете сделать это:

#0:{c.~^#I,}f

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

это в основном вторая часть ответа выше, со списком в качестве входных данных, содержащим цифры и переменные, в которых используются подстановочные знаки.

Я не считаю это действительным, потому что в Brachylog есть только 26 имен переменных (заглавные буквы), поэтому это не сработает, если у вас будет более 26 wilcards.


Похоже, это работает для всех входов. Отличная работа. Тем не менее, я считаю, что это 24 байта, потому что требуется 1-байтовый аргумент. Я не уверен, как оценка для этого будет работать, хотя.
HyperNeutrino

1
@AlexL. Аргумент используется только для указания имени выходной переменной (вы можете использовать другую заглавную букву, если хотите). Это похоже на ответы в Прологе / языках с функциями, в которых назван предикат / функция, но вы фактически не учитываете байты, которые вы используете при вызове.
фатализировать

Ладно. Я не уверен, стоит ли оценивать его как 24, поскольку аргумент необходим (иначе он просто возвращается true.), но я не использовал языки, которые требуют этого раньше. Я попытаюсь найти какую-то ссылку, чтобы определить, как я должен набрать это, но было бы разумно, чтобы было забито как 23, так что я буду держать это при этом.
HyperNeutrino

1

Perl 6 , 30 26 байтов

Спасибо @ b2gills за -4 байта!

{grep /^<$_>$/,map * **2,^1e4}

{grep /^<$_>$/,(^1e4)»²}

Использует точку как символ подстановки, так что ввод может использоваться как регулярное выражение:

{                            }   # a lambda
                         ^1e4    # range from 0 to 9999
               map * **2,        # square each value
 grep /      /,                  # filter numbers that match this regex:
        <$_>                     #   lambda argument eval'ed as sub-regex
       ^    $                    #   anchor to beginning and end

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

Вариант, который принимает звездочку как подстановочный знак (как было предложено в предыдущей редакции описания задачи), составляет 42 байта:

{grep /^<{.trans("*"=>".")}>$/,(^1e4)»²}

Я пересмотрел правила, и вы можете выбрать любой символ подстановки. Я оцениваю это как 38 байт.
HyperNeutrino

Хм, как ты это используешь? Я ничего не знаю о Perl.
HyperNeutrino

@AlexL .: Спасибо, я обновил ответ (и добавил объяснение тоже). Это лямбда; Вы можете вызвать его напрямую (например { ... }("9*9***")) или назначить его переменной / символу для дальнейшего использования. Обратите внимание, что Perl 6 - это отдельный язык от Perl, поэтому он не будет работать с интерпретатором Perl.
смс

Раньше я sudo apt-get install rakudoполучал предполагаемый интерпретатор Perl6 ... Когда я кладу perl6команду в свой терминал, он запускает то, что кажется интерпретатором Perl6, но я не знаю, как его использовать. Я знаю, что это лямбда, но я не знаю, как это назвать.
HyperNeutrino

@AlexL .: Я добавил ссылку «Попробуйте онлайн», которая показывает его как полный скрипт, который вы можете запускать как perl6 foo.p6. Вы также можете протестировать его в оболочке, напримерperl6 -e 'say {grep /^<$_>$/,map * **2,^1e4}( "9.9..." )'
smls

1

Рубин, 54 байта

Функция, которая принимает строковый аргумент. Попробуйте онлайн.

->s{(0..1e3).map{|i|"#{i**2}"[/^#{s.tr ?*,?.}$/]}-[p]}

Вы можете сохранить байт, используя i * i вместо i ** 2
GB

Это не похоже на работу, потому что второй #делает оставшуюся часть комментария.
HyperNeutrino

@AlexL О, все работает хорошо. repl.it/FJCV
Value Ink

ооооо хорошо, я просто не знал, как проверить Руби. Мои извинения. Похоже, это работает для всего ввода. Отличная работа!
HyperNeutrino

0

Пакетный, 109 байтов

@for /l %%i in (0,1,999)do @set/aj=%%i*%%i&call copy nul %%j%%.%%j%%$>nul
@for %%s in (%1.%1$)do @echo %%~ns

Используется ?как подстановочный знак. Работает, создав 1000 файлов. Имя файла - это квадратное число, а расширение файла - это квадратное число с $суффиксом. Это связано с тем, что сопоставление с образцом в Batch считает трейлинг ?s необязательным, поэтому 1?будет совпадать 1и с 16; $поэтому заставляет матч , чтобы быть точным. Однако мы не хотим выводить $, поэтому мы просто выводим имя файла только без расширения.


0

JavaScript (ES6), 68 66 байт

РЕДАКТИРОВАТЬ: Обновил мое решение ниже, после того, как вдохновил ответ JungHwan Мин . Теперь он совместим с ES6.

Принимает ввод в формате '1..4'где .подстановочный знак.

Вместо итерации до 1e6 и квадратного укоренения эта итерация до 1e3 и квадратов.

p=>[...Array(1e3)].map((_,n)=>''+n*n).filter(n=>n.match(`^${p}$`))

JavaScript (ES7), 71 69 байт

p=>[...Array(1e6).keys()].filter(n=>n**.5%1?0:(''+n).match(`^${p}$`))

Создает массив чисел от 0 до 1e6, затем фильтрует его по квадратам и соответствует шаблону.

Это ужасно медленно, потому что оно всегда повторяется до 1e6.


Я не думаю **, что работает, потому что это дает мне "SyntaxError: expected expression, got '*'".
HyperNeutrino

@AlexL. Правила, похоже, изменились. Предыдущие правила предполагали, что я мог выбрать подстановочный знак.
Джордж Райт

Вам нужно только поддержать до 1e6...
HyperNeutrino

Кроме того, я изменил правила обратно; проблема не в правилах, а в том, что **оператора не существует, по крайней мере, в моей системе.
HyperNeutrino

@AlexL. Извините, я думал, что вы имели в виду вход **. Да, это ES7. Я обновлю заголовок. Вот список поддерживаемых в настоящее время браузеров developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Джордж Райт

0

Perl, 42 45 38 байт

РЕДАКТИРОВАТЬ: разъяснение Алекса, мы можем использовать точку в качестве символа подстановки, который сбрасывает операцию y //.

perl -pe 's|.*|@{[grep/^$&$/,map$_*$_,1..1e3]}|'

РЕДАКТИРОВАТЬ: решение, которое использует звездочку в качестве символа подстановки и ожидает последовательность символов подстановки на STDIN

perl -pe 'y/*/./;s|.*|@{[grep/^$&$/,map$_*$_,1..1e3]}|'

Этот, несомненно, оставляет много возможностей для улучшения, это довольно просто. Подстановочный знак ожидается в качестве аргумента командной строки с подстановочным знаком точки (что еще?).

say"@{[grep/^$ARGV[0]$/,map$_*$_,1..1e3]}"

Вопрос указывает, что подстановочные знаки даются в виде звездочек. Позволила ли более ранняя редакция вопроса выбрать собственный символ подстановки?
смс

1
@smls: в вопросе по-прежнему указывается выбрать собственный символ подстановки, хотя его нет в разделе правил: символ, используемый в качестве символа подстановки, не обязательно должен быть звездочкой, это может быть любой символ ASCII по вашему выбору, если только он не цифра, очевидно.
Emigna

Да, меня это смутило. Позже ясно сказано, что подстановочный знак должен быть звездочкой. Я думаю, что определение с регулярным выражением является ведущим. Я пересмотрю свое решение.
Даниэль

1
Хм, на самом деле, предложение, цитируемое @Emigna, довольно ясно, что мы можем выбрать наш собственный символ подстановки, не так ли?
смс

Чтобы уточнить, подстановочный знак может быть любым, что вы хотите. Я случайно перепутал правила при повторном объяснении.
HyperNeutrino

0

Python 3 - 98 97 байт

import re;print(re.findall(r"\b"+input()+r"\b",("\n".join([str(x*x) for x in range(1,1001)]))))

Требуется ввод наподобие «4..6».


Вы можете сохранить 3 байта, используя import reи re.findall; оптимизация с помощью from...import *фактически не оптимизирует его в этом случае.
HyperNeutrino

При условии ввода 1...., он дает 1 4 9и в 16 25качестве правильных ответов, что не является правильным. Пожалуйста, исправьте вашу программу.
HyperNeutrino

Исправьте случай, присоединившись к «\ n».
Карра

Это не работает для 1....... Это возвращается [], но это должно дать [1000000]. Это можно исправить стоимостью 0 байт, используя range(0, 1001)вместо range(0, 1000).
HyperNeutrino

Хороший вопрос, я только что проверил все контрольные примеры из описания :)
Carra

0

k - 28 символов

{s(&:)($:s:s*s:!1001)like x}

Пользы ? как символ подстановки. В likeфункции используется в ?качестве шаблона, и эта функция делает список первых 1001 квадратов (быть включены до оГО), отбрасывают их все строки, а затем проверяет , где они соответствуют шаблону.

    {s(&:)($:s:s*s:!1001)like x} "1??"
100 121 144 169 196

Я получаю эту ошибку за это type error {s(&:)($:s:s*s:!1001)like x} "1" at execution instance 2 of ":". Не могли бы вы предоставить ссылку на рабочий набор тестов или посмотреть, есть ли проблема?
HyperNeutrino

@AlexL. Это работает для меня в режиме kdb + k
C. Quilley

Хм. Я попробую проверить это с разными переводчиками.
HyperNeutrino

0

утилиты bash + Unix, 33 байта

dc<<<'0[2^pv1+lax]dsax'|grep ^$1$

Это использует "." в качестве символа подстановки.

Программа dc печатает квадратные числа в бесконечном цикле:

0     Push 0 on the stack.

[     Start a macro (called a).

2^    Square the number at the top of the stack.

p     Print the number at the top of the stack, followed by a newline.

v     Replace the number at the top of the stack (a square number) with its square root.

1+    Increment the number at the top of the stack.

lax   Run the macro again (looping).

]     End of the macro.

dsax  Store the macro in register a and run it.

Вывод dc передается в grep, который печатает только квадраты, которые соответствуют требуемому шаблону.

Это работает, когда я запускаю его в реальной системе Linux или OS X (но это не работает в TIO, возможно, потому что программа dc пытается рекурсировать вечно, и я подозреваю, что TIO не хватает места в стеке для рекурсии и / или имеет проблема с нескончаемой трубой).


Я запускаю это с Linux Mint 17.3 Rosa, и это не заканчивается. Я думаю, что проблема с бесконечной dcкомандой.
HyperNeutrino

Я подозреваю, что на самом деле проблема заключается в буферизации. У меня нет этой версии Linux, но вы можете попробовать заменить grep на grep --line-buffered (чтобы каждая строка печаталась, когда она отображается grep). [Конечно, это добавляет количество байтов.]
Митчелл Спектор

Я добавил аргумент grep, но это не имеет значения. Я пытался положить --line-bufferedпо обе стороны от ^$1$, но это не работает в любом случае.
HyperNeutrino

@ AlexL. Спасибо за попытку. Я не знаю, есть ли разница в ядре или в версии bash, которую я использую. Я заставил его работать в TIO, принудительно завершив ввод grep с помощью head, следующим образом: dc <<< '0 [2 ^ pv1 + lax] dsax' | head -1 sed s/./0/g<<<$1| grep ^ $ 1 $ Это использует длину шаблон для ограничения числа тестируемых номеров (4-символьные шаблоны проверяют только до 9999 и т. д.). Вот ссылка TIO
Митчелл Спектор

Спасибо за исправление. Я не думаю, что текущее решение на самом деле сработает (хотя я не очень разбираюсь в bash), потому что, похоже, ему нужно вычислить все значения, прежде чем вводить их grep. Тем не менее, поскольку в настоящее время это не самое короткое решение, я буду держать его на 33 байта для оценки. Похоже, работает для всех входов, так что хорошая работа!
HyperNeutrino
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.