이중 연결 데이터 분리


12

이중 링크리스트는 각 노드가 리스트의 다음 노드 value와 "링크"를 갖는 데이터 구조입니다 . 예를 들어, 값이 12, 99 및 37 인 다음 노드를 고려하십시오.previousnodes

여기서, 값 1299next갖는 노드는 값 9937을 갖는 각각의 노드를 가리킨다 . 값이 37 인next 노드는 목록의 마지막 노드이므로 포인터 가 없습니다 . 마찬가지로 값 9937 을 가진 previous노드 는 각각의 노드 1299를 가리 키지 만 12previous목록의 첫 번째 노드이므로 포인터 가 없습니다 .

설정

실제로, 노드의 "링크"는 메모리에서 이전 및 다음 노드의 위치에 대한 포인터로 구현됩니다. 우리의 목적 상 "메모리"는 노드의 배열이되고 노드의 위치는 배열의 인덱스가됩니다. 노드는 형식의 3 튜플로 생각할 수 있습니다 ( prev value next ). 위의 예는 다음과 같습니다.

그러나 대신 다음과 같이 보일 수 있습니다.

모든 노드에서 시작하여 previous링크 (빨간색 화살표의 원점으로 표시됨)를 따라 앞에 오는 노드로 이동하고 next링크 (녹색 화살표)로 연결하여 모든 노드의 값을 순서대로 가져 오는 후속 노드를 찾을 수 있습니다. [12, 99, 37].

위의 첫 번째 다이어그램은로 배열로 표현 될 수 있습니다 [[null, 12, 1], [0, 99, 2], [1, 37, null]]. 그러면 두 번째는입니다 [[2, 99, 1], [0, 37, null], [null, 12, 0]].

도전

노드 배열과 노드 색인을 입력으로 사용하여 동일한 이중 연결 목록에있는 노드 값을 목록 순서로 리턴하는 프로그램을 작성하십시오.

합병증

"메모리"가 항상 하나의 목록의 노드를 포함하지는 않습니다. 몇 가지 목록이 포함될 수 있습니다.

위의 배열에는 편의를 위해 색상으로 구분 된 세 개의 이중 연결 목록이 있습니다.

  1. 인덱스의 노드는 7, 10, 1, 4, 3, 12(만 보여 next혼란을 줄이기 위해 링크하는 것은, 클릭하면 확대) :

    이 배열과 인덱스가 주어지면 프로그램은 값을 순서대로 반환해야합니다 [0, 1, 1, 2, 3, 5, 8].

  2. 인덱스의 노드 9:

    색인이 주어지면 9프로그램이 리턴해야합니다 [99].

  3. 인덱스에서 노드 11, 8, 0, 6, 2:

    이러한 인덱스 중 하나가 주어지면를 반환해야합니다 [2, 3, 5, 7, 11].

규칙

입력

당신의 프로그램은 다음과 같이 입력받을 것입니다 :

  1. 편리한 배열, 예를 들어 배열의 배열, 길이가 3𝒏 인 정수의 "평평한"배열 등의 𝒏 노드 (위에 설명 된 3 튜플) 목록 (1 ≤ 𝒏 ≤ 1,000)

    : 3- 튜플 '요소들은 임의의 순서 일 수있다 ( prev value next ), ( next prev value )각 노드에 대해, 등등 prevnextnull(또는 다른 편리한 값, 예를 들면 -1), 이중 연결리스트의 첫 번째 또는 마지막 노드 또는 유효한 인덱스를 나타내는 편리한대로 0 또는 1을 기준으로합니다. value부호있는 32 비트 정수 또는 언어가 지원하는 가장 큰 정수 유형 중 작은 값입니다.

  2. 목록에서 노드의 인덱스 𝒑 (1). 표시된 노드는 이중 링크리스트의 첫 번째 노드, 마지막 노드, 중간 노드 또는 유일한 노드 일 수 있습니다.

입력 목록 (1) 은 병리학 적 데이터 (예 :주기, 여러 개의 다른 노드가 가리키는 노드 등)를 포함 할 수 있지만 입력 인덱스 (2)는 항상 올바르게 구성된 단일 출력이 될 수있는 노드를 가리 킵니다. 추론했다.

산출

프로그램은 인덱스 𝒑의 노드가 구성원 인 이중 링크리스트의 노드 값을리스트 순서대로 출력해야합니다. 출력은 편리한 형식 일 수 있지만 해당 데이터에는 노드 만 포함되어야합니다 value.

승리

이것은 입니다. 바이트 단위의 최단 답변이 이깁니다. 표준 허점이 적용됩니다.

테스트 사례

아래에서 각 테스트 사례는 다음과 같은 형식입니다.

X)
prev value next, prev value next, ...
index
value value value ...

... 여기 X에서 테스트 사례를 식별하는 문자, 두 번째 줄은 입력 목록, 세 번째 줄은 0 기반 입력 인덱스, 네 번째 줄은 출력입니다.

A) null 12 1, 0 99 2, 1 37 null
   1
   12 99 37

B) 2 99 1, 0 37 null, null 12 0
   1
   12 99 37

C) 8 5 6, 10 1 4, 6 11 null, 4 3 12, 1 2 3, 12 8 null, 0 7 2, null 0 10, 11 3 0, null 99 null, 7 1 1, null 2 8, 3 5 5
   4
   0 1 1 2 3 5 8

D) 8 5 6, 10 1 4, 6 11 null, 4 3 12, 1 2 3, 12 8 null, 0 7 2, null 0 10, 11 3 0, null 99 null, 7 1 1, null 2 8, 3 5 5
   0
   2 3 5 7 11

E) 8 5 6, 10 1 4, 6 11 null, 4 3 12, 1 2 3, 12 8 null, 0 7 2, null 0 10, 11 3 0, null 99 null, 7 1 1, null 2 8, 3 5 5
   9
   99

F) 13 80 18, 18 71 null, 5 10 19, 12 1 8, 19 21 null, 31 6 2, 17 5 26, 26 0 30, 3 -1 25, null 1 23, 27 6 17, 14 1 24, 28 -1 3, null 80 0, 20 4 11, 33 6 29, 24 9 33, 10 7 6, 0 67 1, 2 15 4, 32 1 14, null 1 31, 29 3 null, 9 -1 28, 11 5 16, 8 1 null, 6 3 7, null 8 10, 23 1 12, 15 5 22, 7 9 null, 21 3 5, null 3 20, 16 2 15
   18
   80 80 67 71

G) 13 80 18, 18 71 null, 5 10 19, 12 1 8, 19 21 null, 31 6 2, 17 5 26, 26 0 30, 3 -1 25, null 1 23, 27 6 17, 14 1 24, 28 -1 3, null 80 0, 20 4 11, 33 6 29, 24 9 33, 10 7 6, 0 67 1, 2 15 4, 32 1 14, null 1 31, 29 3 null, 9 -1 28, 11 5 16, 8 1 null, 6 3 7, null 8 10, 23 1 12, 15 5 22, 7 9 null, 21 3 5, null 3 20, 16 2 15
   8
   1 -1 1 -1 1 -1 1

H) 13 80 18, 18 71 null, 5 10 19, 12 1 8, 19 21 null, 31 6 2, 17 5 26, 26 0 30, 3 -1 25, null 1 23, 27 6 17, 14 1 24, 28 -1 3, null 80 0, 20 4 11, 33 6 29, 24 9 33, 10 7 6, 0 67 1, 2 15 4, 32 1 14, null 1 31, 29 3 null, 9 -1 28, 11 5 16, 8 1 null, 6 3 7, null 8 10, 23 1 12, 15 5 22, 7 9 null, 21 3 5, null 3 20, 16 2 15
   4
   1 3 6 10 15 21

I) 13 80 18, 18 71 null, 5 10 19, 12 1 8, 19 21 null, 31 6 2, 17 5 26, 26 0 30, 3 -1 25, null 1 23, 27 6 17, 14 1 24, 28 -1 3, null 80 0, 20 4 11, 33 6 29, 24 9 33, 10 7 6, 0 67 1, 2 15 4, 32 1 14, null 1 31, 29 3 null, 9 -1 28, 11 5 16, 8 1 null, 6 3 7, null 8 10, 23 1 12, 15 5 22, 7 9 null, 21 3 5, null 3 20, 16 2 15
   14
   3 1 4 1 5 9 2 6 5 3

J) 13 80 18, 18 71 null, 5 10 19, 12 1 8, 19 21 null, 31 6 2, 17 5 26, 26 0 30, 3 -1 25, null 1 23, 27 6 17, 14 1 24, 28 -1 3, null 80 0, 20 4 11, 33 6 29, 24 9 33, 10 7 6, 0 67 1, 2 15 4, 32 1 14, null 1 31, 29 3 null, 9 -1 28, 11 5 16, 8 1 null, 6 3 7, null 8 10, 23 1 12, 15 5 22, 7 9 null, 21 3 5, null 3 20, 16 2 15
   17
   8 6 7 5 3 0 9

K) 4 11 0, null 22 3, null 33 3, 1 44 4, 3 55 null, 7 66 7, 6 77 6
   3
   22 44 55

L) null -123 null
   0
   -123



입력이 세 개의 배열 (하나의 모든 선행 노드, 하나의 값 및 하나의 후속 노드를 포함)로 허용됩니까, 아니면 튜플의 개념과 너무 멀리 떨어져 있습니까?
Sanchises

@Sanchises 죄송합니다. 너무 멀어요.
Jordan

괜찮습니다! 나는 그렇게 생각했지만 별도의 배열을 사용하여 2 바이트를 줄일 수 있다는 대답에 대한 의견보다 앞서 가고 싶었습니다.
Sanchises

답변:


1

05AB1E , 25 바이트

è[¬D0‹#Isè]\[`sˆD0‹#Isè]¯

온라인으로 사용해보십시오!

설명

è[¬D0‹#Isè]\[`sˆD0‹#Isè]¯   # Arguments n, a
è                           # Get element at index n in a
 [¬D0‹#Isè]                 # Find the first element in the list
 [                          # While true, do
  ¬                         #   Head (get index of previous element)
   D0‹#                     #   Break if lower than 0
       Isè                  #   Get the element at that index
          ]                 # End loop
           \                # Delete top element of stack
            [`sˆD0‹#Isè]    # Iterate through list
            [               # While true, do
             `sˆ            #   Add value to global array and keep next index on stack
                D0‹#Isè     #   Same as above
                       ]    # End loop
                        ¯   # Push global array

3

하스켈 , 79 65 59 55 바이트

-6 덕분 바이트 브 루트 포스 .

x#i|let-1!d=[];i!d=i:x!!i!!d!d=[x!!i!!1|i<-last(i!0)!2]

정의가 작동 #즉 정수리스트의 목록을 받아 null로 표현되어 -1, 노드 값들의리스트를 반환.

온라인으로 사용해보십시오!

설명

let-1!d=[];i!d=i:x!!i!!d!d

!노드에서 시작하여 노드를 반복 i하고 방문한 목록을 리턴하는 함수 를 정의하십시오 . d다음 노드의 인덱스로 사용할 "튜플"인덱스를 지정하는 두 번째 인수 를 사용합니다 ( d==2정방향 d==0반복, 역방향 반복).

(i!0)

주어진 인덱스에서 시작하여 거꾸로 반복하고 방문한 인덱스를 반환합니다.

last(i!0)

목록의 시작 인 마지막 방문 색인을 가져옵니다.

last(i!0)!2

목록의 시작 부분부터 반복하십시오.

[x!!i!!1|i<-last(i!0)!2]

방문한 각 색인을 노드 값으로 바꾸십시오.


당신은 수있는 거의 쓰기 x!!i!!1i!1!!1하지만, 때문에 휴식 -1출력한다. 그냥 표현하는 또 다른 감시 값을 선택하면 null(예를 들어, -9), 그것은 작동 하겠지만, 항상을위한 깰 수있을 몇 가지 매우 성가신 입력.
Lynn

3

파이썬 2 , 60 바이트

l,n=input()
while~n:m=n;n=l[n][0]
while~m:p,v,m=l[m];print v

온라인으로 사용해보십시오!

이것은 Chas Brown의 대답이며 골프를 뺀 것입니다.

  • 과제를 저장하고 n을 재사용합니다.
  • 마지막 유효 n을 m에 저장하여
  • 마지막 줄에 저를 저장, 3 줄에 할당 후 인쇄를 배치
  • 음수 값은 양수 값과 마찬가지로 진실하기 때문에 -n 대신 ~ n 만 사용하므로 2자를 절약 할 수 있습니다.


2

MATL , 39 바이트

XHx`HwI3$)t]x6Mt`Hwl3$)tbhwt]x4L)Hw2I$)

온라인으로 사용해보십시오!

내 Octave 답변의 거의 직접 포트이지만이 버전은 먼저 끝을 찾은 다음 다른 방법으로 돌아 가지 않고 다시 작동하여 1 바이트를 절약했습니다.

XHx           % Store array in H.
`HwI3$)t]     % Work to the end of the array
x6Mt          % Delete the end of array delimiter, and push the array end index twice
`Hwl3$)    t] % Work to the beginning of the array
       tbhw   % Append all indices found.
Hw2I$)        % Index into original array.

1

PHP, 132 바이트

<?list(,$x,$y)=$argv;parse_str($x);while(($q=$x[$y*3+1])>=0)$y=$q;do{$n[]=$x[$y*3+2];$y=$x[$y*3];}while($x[$y*3]);echo join(' ',$n);

온라인으로 사용해보십시오!

입력이 쿼리 스트링으로 촬영 x[]=-1&x[]=1&x[]=1...순 (평면 배열의 모든 노드) next, prev다음 value노드에 사용 종료와 -1 각 노드.


1

파이썬 2 , 81 77 바이트

a,n=input()
u=a[n][0]
while-~u:u,v,w=a[u]
while-~w:print v;u,v,w=a[w]
print v

온라인으로 사용해보십시오!

편집 : 4 바이트 동안 Mr. Xcoder에게 Thx ...

튜플 [u, v, w] 목록을 가져옵니다. 여기서 u와 w는 -1이며 연결된 목록 세그먼트의 시작 / 끝을 나타냅니다.


77 바이트 온라인으로 사용해보십시오! . 부울은 int의 하위 클래스이므로 0Falsy 만 u>=0가능하므로 골프를 치고 공백을 제거 u+1하기 -~u위해 더 짧아 질 수 있습니다 .
Mr. Xcoder

@씨. Xcoder-그렇습니다!
Chas Brown

1

옥타브 , 81 78 76 바이트

function o=f(a,n)while q=a(n,1)o=a(n=q,2);end
while n=a(n,3)o=[o a(n,2)];end

온라인으로 사용해보십시오!

오히려 간단한 버전입니다. 설명은 독자에게 연습으로 남아 있습니다. 훨씬 더 재미있는 버전은 다음과 같습니다.

옥타브 , 142 99 92 바이트

@(a,n)[(p=@(b,c,z){q=a(z,2),@()[b(b,c,a(z,c)),q]}{2-~a(z,c)}())(p,1,n),p(p,3,n)(end-1:-1:1)]

온라인으로 사용해보십시오!

익명의 기능을 좋아한다고 들었습니다.

nx3첫 번째 열은 선행 열, 두 번째 열은 값 및 세 번째는 후속 노드 로 배열을 가져 옵니다. 모든 노드 인덱스는 1 기반이며 Octave의 기본값입니다.

% Create an anonymous function, taking an array a and first node n
@(a,n)
% Returns an array containing the predecessor and sucessor nodes
      [                                                                     ,                     ]
% Defines an recursive anonymous function (by supplying itself to the local namespace)
% which looks at the first column (c=1) or last column (c=3) of the input array to get the next nodes
       (p=@(p,c,z)                                                   )(p,1,n)
% Create a cell array, either containing the end node,
                    {q=a(z,2),                       
% ...or an array with all next  next nodes and the current node
% (note the use of an anonymous function taking no parameters to defer array access, in case of the last node)                
                              @()[p(p,c,a(z,c)),q]}
% depending whether the next node number is nonzero (followed by () to execute the deferred array access)
                                                    {2-~a(z,c)}()
% Do the same with c=3, reverse (function p builds the array right-to-left) and drop the current node to prevent a duplicate.                                                                             
                                                                             p(p,3,n)(end-1:-1:1)

1

코 틀린 , 85 바이트

{g,S->generateSequence(generateSequence(S){g[it][0]}.last()){g[it][2]}.map{g[it][1]}}

미화

{g,S->
    generateSequence(generateSequence(S){g[it][0]}.last()){ g[it][2]}.map { g[it][1] }
}

테스트

typealias Node=Triple<Int?,Int?,Int?>
data class Test(val input: List<Node>, val start:Int, val result: List<Int>)
val TEST = listOf<Test>(
Test(
listOf(Node(null, 12, 1), Node(0, 99, 2), Node(1, 37, null)),
1,
listOf(12, 99, 37)
),
Test(listOf(
Node(2, 99, 1), Node(0, 37, null), Node(null, 12, 0)),
1,
listOf(12, 99, 37)
),
Test(
listOf(Node(8, 5, 6), Node(10, 1, 4), Node(6, 11, null), Node(4, 3, 12), Node(1, 2, 3), Node(12, 8, null), Node(0, 7, 2), Node(null, 0, 10), Node(11, 3, 0), Node(null, 99, null), Node(7, 1, 1), Node(null, 2, 8), Node(3, 5, 5)),
4,
listOf(0, 1, 1, 2, 3, 5, 8)
),
Test(
listOf(Node(8, 5, 6), Node(10, 1, 4), Node(6, 11, null), Node(4, 3, 12), Node(1, 2, 3), Node(12, 8, null), Node(0, 7, 2), Node(null, 0, 10), Node(11, 3, 0), Node(null, 99, null), Node(7, 1, 1), Node(null, 2, 8), Node(3, 5, 5)),
0,
listOf(2, 3, 5, 7, 11)
),
Test(
listOf(Node(8, 5, 6), Node(10, 1, 4), Node(6, 11, null), Node(4, 3, 12), Node(1, 2, 3), Node(12, 8, null), Node(0, 7, 2), Node(null, 0, 10), Node(11, 3, 0), Node(null, 99, null), Node(7, 1, 1), Node(null, 2, 8), Node(3, 5, 5)),
9,
listOf(99)
),
Test(
listOf(Node(13, 80, 18), Node(18, 71, null), Node(5, 10, 19), Node(12, 1, 8), Node(19, 21, null), Node(31, 6, 2), Node(17, 5, 26), Node(26, 0, 30), Node(3, -1, 25), Node(null, 1, 23), Node(27, 6, 17), Node(14, 1, 24), Node(28, -1, 3), Node(null, 80, 0), Node(20, 4, 11), Node(33, 6, 29), Node(24, 9, 33), Node(10, 7, 6), Node(0, 67, 1), Node(2, 15, 4), Node(32, 1, 14), Node(null, 1, 31), Node(29, 3, null), Node(9, -1, 28), Node(11, 5, 16), Node(8, 1, null), Node(6, 3, 7), Node(null, 8, 10), Node(23, 1, 12), Node(15, 5, 22), Node(7, 9, null), Node(21, 3, 5), Node(null, 3, 20), Node(16, 2, 15)),
18,
listOf(80, 80, 67, 71)
),
Test(
listOf(Node(13, 80, 18), Node(18, 71, null), Node(5, 10, 19), Node(12, 1, 8), Node(19, 21, null), Node(31, 6, 2), Node(17, 5, 26), Node(26, 0, 30), Node(3, -1, 25), Node(null, 1, 23), Node(27, 6, 17), Node(14, 1, 24), Node(28, -1, 3), Node(null, 80, 0), Node(20, 4, 11), Node(33, 6, 29), Node(24, 9, 33), Node(10, 7, 6), Node(0, 67, 1), Node(2, 15, 4), Node(32, 1, 14), Node(null, 1, 31), Node(29, 3, null), Node(9, -1, 28), Node(11, 5, 16), Node(8, 1, null), Node(6, 3, 7), Node(null, 8, 10), Node(23, 1, 12), Node(15, 5, 22), Node(7, 9, null), Node(21, 3, 5), Node(null, 3, 20), Node(16, 2, 15)),
8,
listOf(1, -1, 1, -1, 1, -1, 1)
),
Test(
listOf(Node(13, 80, 18), Node(18, 71, null), Node(5, 10, 19), Node(12, 1, 8), Node(19, 21, null), Node(31, 6, 2), Node(17, 5, 26), Node(26, 0, 30), Node(3, -1, 25), Node(null, 1, 23), Node(27, 6, 17), Node(14, 1, 24), Node(28, -1, 3), Node(null, 80, 0), Node(20, 4, 11), Node(33, 6, 29), Node(24, 9, 33), Node(10, 7, 6), Node(0, 67, 1), Node(2, 15, 4), Node(32, 1, 14), Node(null, 1, 31), Node(29, 3, null), Node(9, -1, 28), Node(11, 5, 16), Node(8, 1, null), Node(6, 3, 7), Node(null, 8, 10), Node(23, 1, 12), Node(15, 5, 22), Node(7, 9, null), Node(21, 3, 5), Node(null, 3, 20), Node(16, 2, 15)),
4,
listOf(1, 3, 6, 10, 15, 21)
),
Test(
listOf(Node(13, 80, 18), Node(18, 71, null), Node(5, 10, 19), Node(12, 1, 8), Node(19, 21, null), Node(31, 6, 2), Node(17, 5, 26), Node(26, 0, 30), Node(3, -1, 25), Node(null, 1, 23), Node(27, 6, 17), Node(14, 1, 24), Node(28, -1, 3), Node(null, 80, 0), Node(20, 4, 11), Node(33, 6, 29), Node(24, 9, 33), Node(10, 7, 6), Node(0, 67, 1), Node(2, 15, 4), Node(32, 1, 14), Node(null, 1, 31), Node(29, 3, null), Node(9, -1, 28), Node(11, 5, 16), Node(8, 1, null), Node(6, 3, 7), Node(null, 8, 10), Node(23, 1, 12), Node(15, 5, 22), Node(7, 9, null), Node(21, 3, 5), Node(null, 3, 20), Node(16, 2, 15)),
14,
listOf(3, 1, 4, 1, 5, 9, 2, 6, 5, 3)
),
Test(
listOf(Node(13, 80, 18), Node(18, 71, null), Node(5, 10, 19), Node(12, 1, 8), Node(19, 21, null), Node(31, 6, 2), Node(17, 5, 26), Node(26, 0, 30), Node(3, -1, 25), Node(null, 1, 23), Node(27, 6, 17), Node(14, 1, 24), Node(28, -1, 3), Node(null, 80, 0), Node(20, 4, 11), Node(33, 6, 29), Node(24, 9, 33), Node(10, 7, 6), Node(0, 67, 1), Node(2, 15, 4), Node(32, 1, 14), Node(null, 1, 31), Node(29, 3, null), Node(9, -1, 28), Node(11, 5, 16), Node(8, 1, null), Node(6, 3, 7), Node(null, 8, 10), Node(23, 1, 12), Node(15, 5, 22), Node(7, 9, null), Node(21, 3, 5), Node(null, 3, 20), Node(16, 2, 15)),
17,
listOf(8, 6, 7, 5, 3, 0, 9)
),
Test(
listOf(Node(4, 11, 0), Node(null, 22, 3), Node(null, 33, 3), Node(1, 44, 4), Node(3, 55, null), Node(7, 66, 7), Node(6, 77, 6)),
3,
listOf(22, 44, 55)
),
Test(
listOf(Node(null, -123, null)),
0,
listOf(-123)
)
)

var f:(List<List<Int?>>,Int)-> Sequence<Int?> =
{g,S->generateSequence(generateSequence(S){g[it][0]}.last()){g[it][2]}.map{g[it][1]}}

fun main(args: Array<String>) {
    for ((input, start, result) in TEST) {
        val out = f(input.map { it.toList() }, start).toList()
        if (out != result) {
            throw AssertionError("$input $start $result $out")
        }
    }
}

TIO

TryItOnline


그냥 generateSequence가 더 짧기를 바랍니다
jrtapsell

0

자바 스크립트 ES6, 70 63 바이트

(x,i,a)=>(h=_=>i&&h(a(x[i].v),i=x[i].n))(x.map(_=>i=x[i].p||i))

테스트 사례 :

F([undefined,{p:0,v:12,n:2},{p:1,v:99,n:3},{p:2,v:37,n:0}],1,alert)

alert요구 함수의 본체에 있어야하고 바이트 총으로 계산합니다.
얽히고 설킨


+10 / -9는 컨센서스가 아닙니다.
얽히고 설킨

정확한 + 및 -s가 표시되지 않습니다. 또한 자바 스크립트의 의도 된 출력 방식이며, 출력에 약간의 지연이있을 때만 가능합니다
l4m2
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.