Что-то вроде этого:
ri
{s}seu~~ci{zs}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c{z}seu~~{w}seu~~sc~c{w}seu~~z{w}seu~~sc~c~
{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c
{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c
{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c
{s}seu~~c{a}seu~~|
{s}seu~~c{c}seu~~|
{t}seu~~sc{a}seu~~|
{s}seu~~c{a}seu~~|{w}seu~~z{w}seu~~sc~c
{s}seu~~sc{fb}seu~~||
{s}seu~~sc{i}seu~~|
{s}seu~~sc{fb}seu~~||
{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c{z}seu~~{w}seu~~sc~c{w}seu~~z{w}seu~~sc~c
{a}seu~~scs
{w}seu~~
{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{z}seu~~{w}seu~~sc~c
{fb}s{b}s{w}seu~~sc~
{s}seu~~sc{ee}seu~~||
{s}seu~~sc{z}seu~~|{w}seu~~{w}seu~~sc~{w}seu~~{w}seu~~sc~
{t}seu~~sc{a}seu~~|
{~}s{}s{w}seu~~sc~
{t}seu~~sc{c}seu~~|
{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{z}seu~~{w}seu~~sc~c~
s~
p
Все пробелы предназначены для ... "читабельности" ... и могут быть опущены в соответствии с регулярным выражением Линн.
Попробуйте онлайн!
объяснение
Регулярное выражение требует, чтобы мы решили проблему, используя только:
- Строчные буквы.
{}
, который можно использовать для создания блоков.
|
, в основном используется для побитового ИЛИ.
~
, "eval" и побитовое НЕ (также "массив массивов", но я не собираюсь его использовать).
Поскольку у нас есть, ~
если мы можем построить произвольные строки, мы можем запустить произвольный код. Однако поначалу не очевидно, как это сделать.
Первая часть головоломки состоит в том, что блоки представляют собой биты кода, которые не могут быть оценены и могут превращаться в строки s
. Так {abc}s
дает нам "{abc}"
. Далее мы можем использовать eu
для преобразования этих строк в верхний регистр.
{abc}seu e# gives "{ABC}"
Преимущество этого состоит в том, что заглавные буквы являются предварительно инициализированными переменными, поэтому мы можем получить много постоянных значений, создав такую строку и оценив ее дважды (один раз, чтобы превратить строку обратно в блок, и один раз в выполнить этот блок). Мы не можем получить все буквы, потому что некоторые, например x
, не являются действительными командами (поэтому CJam откажется анализировать блок, содержащий их). Мы не можем использовать f
как есть, потому что за ней должна следовать другая команда, но мы можем использовать fb
и затем ИЛИ два значения вместе. Аналогично, мы можем использовать ee
вместо e
. При том, что мы можем получить число 0
, -1
, 3
и 10
к 19
. Это -1
удобно, потому что если мы превратим его в строку ("-1"
), то в символ ('-
), а затем оцените его, мы можем получить либо вычитание, либо установить разницу. Как я уже сказал, мы не можем получить X
(для 1
), но мы можем принять абсолютное значение -1
с z
.
Мы также можем использовать, s
чтобы получить строку, содержащую пробел, и использовать, c
чтобы превратить ее в символ пробела :
{s}seu~~c
Это удобно, потому что оттуда мы можем получить много полезных команд в нижнем диапазоне ASCII, ИЛИ пространство с различными числами. Чтобы получить некоторые символы выше кодовой точки 48
, '0
вместо этого мы используем символ в качестве основы:
{t}seu~~si
Этого уже достаточно для создания произвольных строк, потому что мы можем получить '+
(сложение и объединение строк) из следующего фрагмента:
{s}seu~~c{b}seu~~|
И у нас есть литерал, 1
так что мы можем просто помещать пробелы, увеличивать их до нужного значения, а затем объединять их все вместе, но это немного скучно, и код станет массовым.
Вместо этого я сгенерировал [
и ]
оценил их, чтобы все символы, которые я нажимаю, автоматически помещались в строку. Вот эти две строки:
{s}seu~~ci{zs}seu~~c{a}seu~~|~{w}seu~~z{w}seu~~sc~c{z}seu~~{w}seu~~sc~c{w}seu~~z{w}seu~~sc~c~
...
{s}seu~~ci{z}seu~~{s}seu~~c{a}seu~~|~{z}seu~~{w}seu~~sc~c~
И, наконец, нам понадобится f
и ~
строка, которую мы генерируем. Хотя они уже являются допустимыми символами, у нас нет строковых литералов или символьных литералов, поэтому мы должны их сгенерировать, и создание больших кодовых точек из пространства немного раздражает. Вместо этого я использовал вычитание набора здесь, но вычитая два блока (чтобы избавиться от {}
):
{fb}s{b}s{w}seu~~sc~
...
{~}s{}s{w}seu~~sc~
Это почти все, что нужно сделать. Мы оценили [
. Мы толкаем все символы, полученные с помощью различных вычислений из нескольких встроенных констант мы имеем, |
, -
(через Eval) и +
(через Eval). Мы оценили ]
. Мы сплющиваем все это в строку, потому что в какой-то момент я добавил несколько строк или чисел в список. Мы оцениваем нашу произвольную строку с ~
.
Они ri...p
являются частью окончательной конечной программы, но я извлек их, потому что они не нуждаются в кодировании.
Наконец, это программа, которую мы на самом деле запускаем:
ri___*,:)/2/[1-1]f.%:~<p
ri e# Read input and convert to integer.
__ e# Make two copies.
_* e# Square the last copy.
, e# Turn into range [0 1 ... n^2-1].
:) e# Increment each to get [1 2 ... n^2].
/ e# Split into chunks of length n, creating a square.
2/ e# Split into pairs of lines.
[1-1] e# Push [1 -1].
f.% e# Use this to reverse the second line in each pair. If n was odd,
e# this will pair a -1 with the last line.
:~ e# Flatten the pairs back into the square.
< e# Truncate to n lines to get rid of that extraneous -1 for odd inputs.
p e# Pretty-print.
¦
работы убивает меня каждый раз, я попробовал это вчера, но сṚ
чемU
и решил, чтоḤ
не получилось.