Хорошо связанный вызов


40

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

Первая ссылка

Или я мог бы написать abbcac

Вторая ссылка

После того, как я нарисовал эти линии, я пытаюсь нарисовать замкнутые петли вокруг кусков, чтобы моя петля не пересекала ни одну из линий, которые я только что нарисовал. Например, в первом случае мы можем нарисовать только один цикл вокруг всего, но во втором мы можем нарисовать цикл вокруг только b s (или всего остального)

Петля нарисована

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

Обратите внимание, что некоторые строки могут быть нарисованы несколькими способами. Например, bbbb можно нарисовать обоими из следующих способов (и третий не входит):

Способ 1 или Способ 2

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

задача

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

Кроме того, ваша программа должна быть хорошо связанной строкой, означающей

  • Каждый символ появляется четное количество раз в вашей программе.

  • Он должен вывести истинное значение, когда передал сам.

Ваша программа должна быть в состоянии произвести правильный вывод для любой строки, состоящей из символов из печатного ASCII или вашей собственной программы. С каждым персонажем появляется четное количество раз.

Ответы будут оцениваться как их длины в байтах с меньшим количеством байтов, что является лучшим показателем.

намек

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

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

abcbac -> True
abbcac -> False
bbbb -> False
abacbc -> True
abcbabcb -> True
abcbca -> False

1
Тестовый пример: abcbca -> False.
Эрджан Йохансен

Я думаю, что ваша подсказка содержит лишнее there.
Джонатан Фрех

2
Итак, чтобы быть ясным: имеет ли строка общее четное число каждого символа, не имеет значения, является ли строка хорошо связанной. Это требование относится только к исходному коду программ. Это, конечно, только вопрос семантики, поскольку программы могут иметь неопределенное поведение для введенных строк, имеющих нечетное общее число любого символа (и по крайней мере одна представленная программа использует это преимущество).
Deadcode

Какие символы могут быть на входе?
xnor

@xnor Я добавил это к вызову. Надеюсь, это прояснит это.
Пшеничный волшебник

Ответы:


19

Regex (ECMAScript 2018 или .NET), 140 126 118 100 98 82 байта

^(?!(^.*)(.+)(.*$)(?<!^\2|^\1(?=(|(<?(|(?!\8).)*(\8|\3$){1}){2})*$).*(.)+\3$)!?=*)

Это намного медленнее, чем 98-байтовая версия, потому что ^\1слева от просмотра и, следовательно, оценивается после него. Смотрите ниже простое переключение, которое восстанавливает скорость. Но из-за этого два приведенных ниже TIO ограничены выполнением меньшего набора тестов, чем раньше, и .NET один слишком медленно проверяет свое регулярное выражение.

Попробуйте онлайн! (ECMAScript 2018)
Попробуйте онлайн! (.СЕТЬ)

Чтобы отбросить 18 байт (118 → 100), я бесстыдно украл действительно хорошую оптимизацию из регулярного выражения Нейла, которая избавляет от необходимости помещать заглядывание внутрь отрицательного заднего обзора (в результате получается 80-байтовое неограниченное регулярное выражение). Спасибо тебе, Нил!

Это устарело, когда было отброшено еще 16 невероятных байтов (98 → 82) благодаря идеям jaytea , которые привели к 69-байтовому неограниченному регулярному выражению! Это намного медленнее, но это гольф!

Обратите внимание, что (|(отсутствие операций для обеспечения регулярного связывания регулярного выражения приводит к очень медленной оценке его в .NET. Они не имеют этого эффекта в ECMAScript, потому что необязательные совпадения нулевой ширины рассматриваются как несоответствия .

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

Без дополнительных символов, необходимых для того, чтобы он прошел ограничения ( 101 69 байт):

^(?!(.*)(.+)(.*$)(?<!^\2|^\1(?=((((?!\8).)*(\8|\3$)){2})*$).*(.)+\3))

Это медленно, но это простое редактирование (всего 2 дополнительных байта) восстанавливает всю потерянную скорость и многое другое:

^(?!(.*)(.+)(.*$)(?<!^\2|(?=\1((((?!\8).)*(\8|\3$)){2})*$)^\1.*(.)+\3))

^
(?!
    (.*)               # cycle through all starting points of substrings;
                       # \1 = part to exclude from the start
    (.+)               # cycle through all ending points of non-empty substrings;
                       # \2 = the substring
    (.*$)              # \3 = part to exclude from the end
    (?<!               # Assert that every character in the substring appears a total
                       # even number of times.
        ^\2            # Assert that our substring is not the whole string. We don't
                       # need a $ anchor because we were already at the end before
                       # entering this lookbehind.
    |                  # Note that the following steps are evaluated right to left,
                       # so please read them from bottom to top.
        ^\1            # Do not look further left than the start of our substring.
        (?=
            # Assert that the number of times the character \8 appears in our
            # substring is odd.
            (
                (
                    ((?!\8).)*
                    (\8|\3$) # This is the best part. Until the very last iteration
                             # of the loop outside the {2} loop, this alternation
                             # can only match \8, and once it reaches the end of the
                             # substring, it can match \3$ only once. This guarantees
                             # that it will match \8 an odd number of times, in matched
                             # pairs until finding one more at the end of the substring,
                             # which is paired with the \3$ instead of another \8.
                ){2}
            )*$
        )
        .*(.)+         # \8 = cycle through all characters in this substring
        # Assert (within this context) that at least one character appears an odd
        # number of times within our substring. (Outside this negative lookbehind,
        # that is equivalent to asserting that no character appears an odd number
        # of times in our substring.)
        \3             # Skip to our substring (do not look further right than its end)
    )
)

Я написал его с использованием молекулярного просмотра ( 103 69 байт), прежде чем преобразовать его в просмотр с переменной длиной:

^(?!.*(?*(.+)(.*$))(?!^\1$|(?*(.)+.*\2$)((((?!\3).)*(\3|\2$)){2})*$))

^
(?!
    .*(?*(.+)(.*$))       # cycle through all non-empty substrings;
                          # \1 = the current substring;
                          # \2 = the part to exclude from the end
    (?!                   # Assert that no character in the substring appears a
                          # total even number of times.
        ^\1$              # Assert that our substring is not the whole string
                          # (i.e. it's a strict substring)
    |
        (?*(.)+.*\2$)    # \3 = Cycle through all characters that appear in this
                          # substring.
        # Assert (within this context) that this character appears an odd number
        # of times within our substring.
        (
            (
                ((?!\3).)*
                (\3|\2$)
            ){2}
        )*$
    )
)

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

(?*(.+)(.*$))(?!^\1$|(?*(.)+.*\2$)((((?!\3).)*(\3|\2$)){2})*$)\1

При использовании с regex -xml,rs -o, это идентифицирует строгую подстроку ввода, которая содержит четное число каждого символа (если таковой существует). Конечно, я мог бы написать программу без регулярных выражений, чтобы сделать это для меня, но где было бы в этом удовольствие?


8
WTF это все еще в гольфе
только ASCII

@ Только для ASCII и до сих пор в гольфе ...
Quintec

11

Желе, 20 байт

ĠẈḂẸẆṖÇ€Ạ
ĠẈḂẸ
ẆṖÇ€Ạ

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

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

Следующая строка сначала Ġгруппирует индексы по их значению. Если затем взять длину каждого подсписка в результирующем списке ( ), мы получим количество раз, которое появляется каждый символ. Чтобы проверить, являются ли какие-либо из них нечетными , мы получаем последнее значение для каждого счетчика и спрашиваем, существует ли истинное (ненулевое) значение.

Следовательно, эта вспомогательная ссылка возвращает ли подстроку нельзя .

В основной ссылке мы берем все подстроки input ( ), отключаем последнюю (чтобы мы не проверяли, можно ли обвести всю строку), и запускаем вспомогательную ссылку ( Ç) для подстроки ach. В результате получается, что все подстроки нельзя обвести.


Так что, да, это тоже будет моим решением, но, к сожалению, это скучно ... :(
Эрик Игрок в гольф

8

J , 34 байта

2:@':.,|~*'>1(#.,)*/@(1>2|#/.~)\.\

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

-8 байт благодаря FrownyFrog

оригинал

J , 42 байта

(*#'.,012&|@~#')=1#.[:,([:*/0=2&|@#/.~)\.\

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

объяснение

(*#'.,012&|@~#') = 1 #. [: , ([: */ 0 = 2&|@#/.~)\.\

(*#'.,012&|@~#')                                       NB. this evaluates to 1
                                                       NB. while supplying extra
                                                       NB. chars we need.  hence...
                 =                                     NB. does 1 equal...
                   1 #.                                NB. the sum of...
                        [: ,                           NB. the flatten of...
                             (                  )\.\   NB. the verb in parens applied
                                                       NB. to every suffix of every
                                                       NB. prefix, ie, all contiguous 
                                                       NB. substrings
                             ([: */ 0 = 2&|@#/.~)      NB. def of verb in paren:
                                             /.~       NB. when we group by each
                                                       NB. distinct char...
                              [: */                    NB. is it the case that
                                                       NB. every group...
                                           @#          NB. has a length...
                                    0 = 2&|            NB. divisible by 2...

1
@Deadcode Поскольку обработка, которая сводится к выполнению противоположного теста для всей строки, как и для любой другой подстроки, кажется безопасной верой, что большинство решений не допустят этого. При тестировании abcтолько запись Perl не «проваливается» на ней. (У него есть и другие проблемы.)
Орджан Йохансен

1
@ ØrjanJohansen Вы неправильно поняли. Я сказал, что строки с нечетным общим числом любого символа (который только дисквалифицирует исходный код программы, а не строки с хорошими связями) могут быть хорошо связаны, и эта программа возвращает ложные значения для некоторых из этих строк с хорошими связями. Вопрос явно допускает это неопределенное поведение, поэтому программа действительна. Джона, я думаю, это действительно интересно, что твоя программа делает это, и я восхищаюсь, что ты нашел метод, который работает таким образом. Я бы с удовольствием объяснил. Этот вид программирования мне совершенно чужд, поэтому я не понимаю комментарии и код.
Deadcode

1:@':.,02|~*'=1(#.,)*/@(0=2|#/.~)\.\
FrownyFrog

1
2:@':.,|~*'>1(#.,)*/@(1>2|#/.~)\.\также кажется действительным
FrownyFrog

6

Python 3.8 (предварительная версия) , 66 байт

lambda l,b={id}:len({str(b:=b^{c})for(c)in l})<len(l)#,<^fmnost{}#

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

Эра Выражений Назначения на нас. С PEP 572, включенным в Python 3.8, игра в гольф никогда не будет прежней. Вы можете установить раннюю версию 3.8.0a1 для разработчиков здесь .

Выражения присваивания позволяют использовать :=для присваивания переменной inline при оценке этого значения. Например, (a:=2, a+1)дает(2, 3) . Это, конечно, может быть использовано для хранения переменных для повторного использования, но здесь мы идем на шаг дальше и используем их как накопитель в понимании.

Например, этот код вычисляет кумулятивные суммы [1, 3, 6]

t=0
l=[1,2,3]
print([t:=t+x for x in l])

Обратите внимание, что при каждом прохождении по списку накопленная сумма tувеличивается наx и новое значение сохраняется в списке, созданном для понимания.

Точно так же b:=b^{c}обновляет набор символов, bчтобы переключать, включает ли он символ c, и оценивает новое значение b. Таким образом, код [b:=b^{c}for c in l]перебирает символы cв lи накапливает набор символов видели нечетное количество раз в каждом непустом префиксе.

Этот список проверяется на наличие дубликатов, вместо этого он задает понимание набора и определяет, не превышает ли его длина длину s, что означает, что некоторые повторы были свернуты. Если это так, то повторение означает, что в той части, которую sвидели между этими временами, каждый символ встречался с четным числом чисел, что делало строку плохо связанной. Python не допускает, чтобы наборы наборов были недоступны, поэтому вместо них внутренние наборы преобразуются в строки.

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

Для ограничения источника непарные символы вставляются в комментарии в конце. Написание, for(c)in lа не for c in lотменяет лишние скобки бесплатно. Мы помещаем idв исходный набор b, который безвреден, поскольку он может начинаться как любой набор, но пустой набор не может быть записан так, {}потому что Python создаст пустой словарь. Поскольку буквы iи dявляются одними из тех, кто нуждается в сопряжении, мы можем поставить функцию idтам.

Обратите внимание, что код выводит отрицательные логические значения, поэтому он будет корректно выдавать Falseсам себя.



5

Python 2 , 74 байта

bmn0=f=lambda s,P={0},d=[]:s<" "if(P in d)else+f(s[f<s:],P^{s[0^0]},[P]+d)

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

Выполняет итерацию по строке, отслеживая Pнабор символов, видимых нечетное количество раз. В списке dхранятся все прошлые значения P, и, если текущее значение Pуже указано d, это означает, что в символах, которые были видны с того времени, каждый символ появлялся четное число раз. Если это так, проверьте, прошли ли мы весь ввод: если у нас есть, примите, потому что вся строка спарена, как и ожидалось, и отклоните в противном случае.

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

bmn0=f=lambda s,P={0},d=[]:s<" "if(P in d)else+f(s[f<s:],P^{s[0^0]},[P]+d)
_____              _              _      _    _    ___        ___    

В f<sпринимает значение в 0то время как на пары f, воспользовавшись именем функции также быть fтак , что она определяется (по времени функция называется) . В 0^0поглощает ^символ.

0В P={0}неудачно: в Python {}вычисляется в пустой Словаре , а не пустое множество , как мы хотим, и здесь мы можем поставить в любом элементе несимвольного и будет безвредными. Я не вижу ничего лишнего, чтобы вставить, и вставил 0и продублировал это bmn0, стоя 2 байта. Обратите внимание, что начальные аргументы оцениваются, когда функция определена, поэтому переменные, которые мы определяем сами, не могут быть здесь вставлены.


4

Perl 6 , 76 байт

*.comb[^*X+(^*).map(^*)].grep({$_&[&]($_)}).none.Bag{*}.none%2#*^+XBob2rec%#

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

Любая лямбда, которая возвращает None Junction of None Junction, которая может быть увеличена до истинного / ложного значения. Я бы порекомендовал не удалять это, ?что увеличивает возвращаемый результат, в противном случае вывод становится довольно большим .

Это решение немного сложнее, чем нужно, из-за того, что несколько задействованных функций не связаны между собой, например ..,all , >>, и %%т.д. Без ограничений источника, это может быть 43 байта:

*.comb[^*X.. ^*].grep(?*).one.Bag{*}.all%%2

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

Объяснение:

*.comb                     # Split the string to a list of characters
      [^*X+(^*).map(^*)]   # Get all substrings, alongside some garbage
                        .grep({$_&[&]($_)})        # Filter out the garbage (empty lists, lists with Nil values)
                                           .none                 # Are none of
                                                .Bag{*}          # The count of characters in each substring
                                                       .none%2   # All not divisible by 2

                                               #*^+XBob2rec%#    And garbage to even out character counts

3

Perl 5 -p, 94, 86, 78 байт

m-.+(?{$Q|=@q&grp,$\|=$&eq$_^!grep+/^/&(@m=$g=~/\Q$_/g),($g=$&)=~/./g})(?!)-}{

Output 0, если хорошо связан 1 в противном случае.

78 байт

86 байт

94 байта

Как это работает

  • -pс }{завершающим трюком для вывода$\ в конце
  • m-.+(?{.. })(?!)-, чтобы выполнить код над всей непустой подстрокой ( .+сначала совпадает со всей строкой, а после выполнения кода между (?{... })возвратами из-за принудительного сбоя(?!)
  • $Q|=@q&grp, мусор из-за ограничения источника
  • $\|=целочисленное поразрядное или присваивание, если есть почти 1, $\будет 1 (true), по умолчанию оно пустое (false)
  • $&eq$_случай, когда sbustring - целая строка, поразрядно записывается ^с "отсутствием нечетных символов"
  • ($g=$&)=~/./gскопировать $gсовпавшую подстроку в (потому что она будет перезаписана после следующего совпадения с регулярным выражением) и вернуть массив символов подстроки.
  • /^/ мусор, который оценивается в 1
  • grep1 &(@m=$g=~/\Q$_/g),для каждого символа в подстроке получить массив символов в $gсоответствии самому себе, массив в скаляре оценивает его размер и grepфильтровать символы с нечетным вхождением 1&xэквивалентноx%2==1

Я не думаю, что это удовлетворяет исходному ограничению: я считаю нечетное количество открытых скобок, например
msh210

@ msh210 Разве это не главное? Если есть четное число, оно не очень хорошо связано
Quintec

@Quintec Одним из требований , предъявляемых к быть хорошо связаны, что есть есть четное число каждого символа.
Эрджан Йохансен

мой первый ответ имел требование, но после попытки игры в гольф потерял его. обновляется, но можно играть в гольф.
Науэль Фуйе

1
все источники здесь удовлетворяют ограничениям на источники, также код возвращает 0, если он хорошо связан, и четное число каждого символа
Науэль Фуий

3

Сетчатка , 150 96 байт

^(?!(.*)(.+)(.*)$(?<!^\2|^\1(?:(^?(?:(?!\6).)*\6){2})*(|(?!\6).)*(?!.+\6.*\3$)(.){1,}\3)(?!,<)?)

Попробуйте онлайн! Ссылка включает в себя тестовые случаи, в том числе и себя. Редактировать: с помощью @Deadcode отыграли оригинальное регулярное выражение, а затем добавили немного меньше, чтобы сохранить исходный макет. Объяснение:

^(?!(.*)(.+)(.*)$

Утвердите, что не \3существует подстроки, которая соответствует следующим ограничениям.

(?<!^\2|

Утверждают, что подстрока не является всей исходной строкой.

^\1(?:(^?(?:(?!\6).)*\6){2})*(|(?!\6).)*(?!.+\6.*\3$)(.){1,}\3)(?!,<)?)

Утверждают, что нет \6такого персонажа , который:

  • он не появляется между самим символом (исключительным) и концом подстроки
  • оно появляется четное число раз между началом подстроки и самой собой (исключая)

Для того , чтобы передать ограничение компоновки источника, я заменил ((((с (?:(^?(?:(и ((с (|(. У меня все еще оставалось одно ограничение источника ))и оставались символы !()1<{}, поэтому я изменил +на {1,}и вставил бесполезные, (?!,<)?чтобы использовать остальные.


2
Это, кажется, не удовлетворяет ограниченным требованиям источника.
Эрджан Йохансен

@ ØrjanJohansen Наконец-то я нашел правильное решение. Хотя там много мусора, так что может быть что-то более короткое доступно ...
Нил

3

C # (интерактивный компилятор Visual C #) , 208 206 200 198 байт

x=>!x.GroupBy(c=>c).Any(g=>g.Count()%2>0)&!Enumerable.Repeat(x.Count,x.Count*x.Count).Where(
(l,i)=>i%l>0&!x.Skip(i/l).Take(i%l).GroupBy(c=>c).Any(g=>g.Count()%2>0)
).Any()/*>!oyAnC0EmeablR*WhiS/T*/

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

-2 байта благодаря @KevinCruijssen!

Наконец-то он опустился ниже 200, так что я, возможно, пока играю в гольф :) Я закончил тем, что создал второй TIO, чтобы проверить все на основе предыдущего ответа.

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

Вещи, которые сделали эту задачу сложной:

  • Оператор равенства == не разрешен
  • Оператор увеличения / назначения ++ не был разрешен
  • All()Функция Linq была запрещена

Код комментария ниже:

// anonymous function that takes an IList as input
x=>
  // the first condition makes sure the string even
  // counts of each character
  !x.GroupBy(c=>c).Any(g=>g.Count()%2>0)&
  // the second condition generates all proper substrings of x
  // and tests for any that contain even character counts
  // the string length `l` is repeated `l*l` times
  !Enumerable.Repeat(x.Count,x.Count*x.Count)
    .Where((l,i)=>
      // check that the substring length is greater than 0
      i%l>0&
      // use skip/take to generate a substring
      // and check for a character count thats odd
      // negate the result meaning we have found
      // a substring that invalidates the input
      !x.Skip(i/l).Take(i%l)
        .GroupBy(c=>c).Any(g=>g.Count()%2>0)
    )
    // if any invalid substrings are found
    // then the result in invalid
    // the comment string at the end is needed
    // to make the program well-linked
    .Any()/*>!oyAnC0EmeablR*WhiS/T*/

Вы можете удалить два пробела в последнем комментарии.
Кевин Круйссен

@KevinCruijssen - хороший :) Я забыл, что уже добавил пробел. Я должен был бросить еще один в источник.
Дана


2

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

sᶠb∋p~j&sᶠb∋p~j&

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

Отпечатки false.для правдивых случаев иtrue. ложных случаев. Версия TIO слишком медленная, чтобы справиться сама с собой, но она явно хорошо связана, поскольку представляет собой строку с уникальными символами, повторяемыми дважды.

объяснение

    Input is a string: "abcacbaa"
sᶠ  Find all substrings: ["abcacbaa","abcacba","abcacb",..,"a"]
b   Behead (now the proper substrings remain): ["abcacba","abcacb",..,"a"]
∋   Take one of them: "abcacb"
p   Permute it: "abcabc"
~j  It is some string repeated twice: "abc"
&   Get the input again: "abcacbaa"
    Then repeat the above.
    If the constraints can be satisfied, the result is true, otherwise false.

1

05AB1E , 22 20 байт

Œε¢Pà}KŒIKεSIS¢ÈP}àÈ

Выводится, 1если строка хорошо связана, и 0если строка плохо связана.

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

Базовая программа ŒsKεsS¢ÈP}à( 11 байт ) выдает результаты, 0если они хорошо связаны, а 1если нет. Трейлинг È(is_even) является полупериодом, который инвертирует вывод, поэтому 1для строк с хорошей связью и 0для строк с плохой связью. Другие части не могут выполнить правила соревнования.

Œε¢Pà}K         # No-ops: substrings, map, count, product, maximum, close map, remove
                # Due to the last remove, we're back at the (implicit) input again
Π              # Take the substrings of the input
 IK             # Remove the input itself from that list of substrings
   ε            # Map each substring to:
    S           #  No-op: transform the substring into a list of characters
     IS         #  Get the input-string as a list of characters
       ¢        #  Count the occurrence of each character in the current substring
        È       #  Check which counts are even (1 if truthy; 0 if falsey)
         P      #  Take the product of that
              # After the map: check if any are truthy by taking the maximum
            È   # Semi no-op: check if this maximum is even (0 becomes 1; 1 becomes 0)
                # (and output the result implicitly)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.