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


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.