Lassen Sie uns eine Treppe bauen


19

Wir haben nicht genug (halb-) leichte Herausforderungen für Anfänger. Immer mehr der einfachen sind bereits vergeben. Also habe ich versucht, etwas zu finden, das für Anfänger erreichbar sein könnte, aber das ist kein Duplikat.

Eingang:

Eine einzelne Zeichenfolge, die durch eine neue Zeile des Betriebssystems (dh \r\n) getrennt ist,
oder ein Array mit mehreren Zeichenfolgen.

Ausgabe - Die Treppe :

Entfernen Sie alle nicht alphabetischen und nicht numerischen Symbole. Also bleibt nur noch [A-Za-z0-9]. Und dann 'eine Treppe bauen'; im grunde nach länge ordnen mit dem kleinsten oben und dem breitesten unten.

Herausforderungsregeln:

  1. Wenn zwei Zeichenfolgen gleich lang sind, werden sie als eine große Zeichenfolge zusammengeführt (die Reihenfolge spielt keine Rolle, es kann also vom ersten bis zum letzten oder vom letzten bis zum ersten sein, je nachdem, welche der beiden Sie bevorzugen).
  2. Die obige Regel kann gestapelt werden, wenn die zusammengeführten Zeichenfolgen wieder die gleiche Länge haben (siehe Testfall 2).

Allgemeine Regeln:

  • Die Eingabe ist STDIN und enthält nur ASCII-Zeichen. Und die Ausgabe ist STDOUT.
  • Der Fall des Ausgangs muss mit dem des Eingangs identisch sein.
  • Jede Einreichung muss ein vollständiges Programm sein, das kompiliert und ausgeführt werden kann, also nicht nur eine Methode / Funktion. EDIT: Ich bin ziemlich neu, also ist es vielleicht besser, von nun an die Standardeinstellung zu verwenden, obwohl ich selbst ein volles Programm bevorzuge. Entschuldigung für alle, die bereits ein vollständiges Programm veröffentlicht haben. Fühlen Sie sich frei zu bearbeiten, und ich werde versuchen, die Post-Mid-Challenge beim nächsten Mal nicht zu ändern.
  • Das ist , also gewinnt die kürzeste Antwort in Bytes. Ich akzeptiere wahrscheinlich die kürzeste Antwort in einem Jahr.
    Lassen Sie sich von Code-Golf-Antworten nicht davon abhalten, Golf-Nicht-Codegolf-Sprachen wie C # und dergleichen zu veröffentlichen! Versuchen Sie, für jede Programmiersprache die kürzeste Antwort zu finden.
  • Fühlen Sie sich frei, neuere Sprachen als diese Frage zu verwenden.

Testfälle:

Eingang 1:

This is a sample text,
that you will have to use to build stairs.
The wood may be of excellent quality,
or pretty crappy almost falling apart and filled with termites.
Bla bla bla - some more text
Ok, that will do

Ausgang 1:

Okthatwilldo
Thisisasampletext
Blablablasomemoretext
Thewoodmaybeofexcellentquality
thatyouwillhavetousetobuildstairs
orprettycrappyalmostfallingapartandfilledwithtermites

Eingang 2:

A
small
one
that
contains
equal
length
strings
for
the
special
rule

Ausgang 2:

A                   Or alternatively:       A
length                                      length
oneforthe                                   theforone
smallequal                                  equalsmall
stringsspecial                              specialstrings
thatrulecontains                            containsrulethat

Schritte erklärt von 2:

Erstbestellung nach Länge:

A
one
for
the
that
rule
small
equal
length
strings
special
contains

Erste Zusammenführung:

A
oneforthe
thatrule
smallequal
length
stringsspecial
contains

Zweite Ordnung nach Länge:

A
length
thatrule
contains
oneforthe
smallequal
stringsspecial

Zweite Zusammenführung:

A
length
thatrulecontains
oneforthe
smallequal
stringsspecial

Dritte Bestellung nach Länge:

A
length
oneforthe
smallequal
stringsspecial
thatrulecontains

Eingang 3:

Test,
test.
This
is
a
test.

Ausgang 3:

a                   Or alternatively:       a
is                                          is
TesttestThistest                            testThistestTest

Eingang 4:

a
bc
d!
123

Ausgang 4:

123     Or alternatively:    123
adbc                         dabc

1
containssoll nicht in Ausgabe 2 sein. Es wird zusammengeführt mitthatrule
Keatinge

2
Sie haben so ziemlich das genaue Gegenteil von dem, was Sie wollten, es ist ziemlich schwer, dies zu tun.
Bálint

"Fühlen Sie sich frei, neuere Sprachen als diese Frage zu verwenden" - Wenn ich also eine Sprache erstelle, um diese Herausforderung in 0 Byte zu lösen, ist das technisch legal, nicht wahr?
Bálint

War diese Herausforderung im Sandkasten?
Bálint

1
@nimi Ich persönlich bevorzuge in der Tat ein vollständiges Programm, aber wenn Sie wirklich darauf bestehen, kann ich es jetzt entfernen und jeder kann die Standardeinstellung verwenden. Ich bin ziemlich neu, also ist es vielleicht besser, die Standardeinstellung von nun an zu verwenden. Entschuldigung für alle, die bereits ein vollständiges Programm veröffentlicht haben. Fühlen Sie sich frei zu bearbeiten, und ich werde versuchen, die Regeln während der nächsten Herausforderung nicht zu ändern.
Kevin Cruijssen

Antworten:


4

Schale , 11 Bytes

ωȯmΣġLÖLmf□

Probieren Sie es online!

Husk ist jünger als diese Herausforderung (was offiziell keinen Unterschied macht, aber immer noch).

Erläuterung

ωȯmΣġLÖLmf□  Implicit input (list of strings), say ["a","bc","d!","123"]
        mf□  Keep only alphanumeric chars of each: ["a","bc","d","123"]
ωȯ           Repeat until fixed point is reached:
      ÖL       Sort by length: ["a","d","bc","123"]
    ġL         Group by length: [["a","d"],["bc"],["123"]]
  mΣ           Concatenate each group: ["ad","bc","123"]
             Final result ["123","adbc"], print implicitly separated by newlines.

Wenn "Behalte nur alphanumerische Zeichen von jedem" ist mf□, solltest du eifersüchtig sein. Wenn "Gruppe nach Länge" ist ġL, sollten Sie erstaunt sein.
Erik der Outgolfer

Ich habe deine Antwort jetzt akzeptiert. Das neue Meta ist, dass Sprachen, die neuer sind als die Herausforderung, verwendet werden können (und das habe ich auch bereits in meiner Herausforderung erwähnt, als ich es gepostet habe). Wie gesagt, nette Antwort!
Kevin Cruijssen

4

Python 3, 264 Bytes

Ich bin nicht gut im Code-Golf, also bin ich zuversichtlich, dass dies nicht die beste Python 3-Antwort sein wird. Dies verwendet eine Rekursion und ein geordnetes Diktat mit allen Wörtern für jede Länge.

from collections import*
def f(i):
 d = defaultdict(list)
 for l in i: x = "".join(c for c in l if c.isalnum());d[len(x)].append(x)
 n = (sorted(["".join(d[z]) for z in d.keys()], key=len))
 if n == i:return "\n".join(n)
 return f(n)
print(f(eval(input())))

Nimmt die Eingabe von stdin als Liste, testen Sie sie beispielsweise mit dieser Liste:

['A', 'small', 'one', 'that', 'contains', 'equal', 'length', 'strings', 'for', 'the', 'special', 'rule']

Wird ausgeben:

A
length
oneforthe
smallequal
stringsspecial
thatrulecontains

1
Gute Antwort! Ein paar Tipps zum Golfen: 1) Sie brauchen keine Leerzeichen um = Zeichen oder == Zeichen. 2) Python kann Stichwörter erkennen, wenn bekannt ist, dass es sich nicht um einen anderen Variablennamen handeln kann, wie Sie dies mit "import *" (z. B. ") für", "return" \ n "getan haben. 3) Ich bin mir ziemlich sicher (nicht positiv), dass Sie die Klammern um sortiert () nicht benötigen. Viel Spaß beim Codieren!
Blau

Sie können filter(str.isalnum, l)anstelle des "".joinTeils
njzk2


3

Oracle SQL 11.2, 346 Byte

Die Zeilen in der Eingabezeichenfolge werden durch '¤' getrennt. Auf diese Weise muss keine Tabelle erstellt werden, die als Eingabe verwendet werden soll.

This is a sample textthat you will have to use to build stairsThe wood may be of excellent qualityor pretty crappy almost falling apart and filled with termitesBla bla bla - some more text¤Ok, that will do
A¤small¤one¤that¤contains¤equal¤length¤strings¤for¤the¤special¤rule
TesttestThis¤is¤a¤test         

Abfrage:

WITH v AS(SELECT REGEXP_REPLACE(COLUMN_VALUE,'[^a-zA-Z0-9]')s FROM XMLTABLE(('"'||REPLACE(:1,'¤','","')||'"'))),r(s,i,l)AS(SELECT s,1,1 FROM v UNION ALL SELECT LISTAGG(s)WITHIN GROUP(ORDER BY s)OVER(PARTITION BY LENGTH(s)),ROW_NUMBER()OVER(PARTITION BY LENGTH(s)ORDER BY s),l+1 FROM r WHERE l<LENGTH(:1)AND i=1)SELECT s FROM r WHERE l=LENGTH(:1);  

Nicht golfen

WITH v AS
( 
  -- Splits on ¤ and keeps only alphanum characters 
  SELECT REGEXP_REPLACE(COLUMN_VALUE,'[^a-zA-Z0-9]')s FROM XMLTABLE(('"'||REPLACE(:1,'¤','","')||'"'))
)
-- Recursive view 
-- s : string
-- i : index of the string in case of duplicates
-- l : exit condition
,r(s,i,l)AS
(
  -- Start with every element of the input
  SELECT s,1,1 FROM v
  UNION ALL
  SELECT -- Concatenate elements of the same lengths
         LISTAGG(s)WITHIN GROUP(ORDER BY s)OVER(PARTITION BY LENGTH(s))
         -- Index of elements of the same length (listagg with over generates duplicates)
        ,ROW_NUMBER()OVER(PARTITION BY LENGTH(s) ORDER BY s)
        -- exit condition
        ,l+1 FROM r WHERE l<LENGTH(:1) AND i=1
)
-- Keep only the elements from the last iteration (automaticaly sorted on my system)
SELECT s FROM r WHERE l=LENGTH(:1)  

Sie können Ihre Regex durch[\W_]
FliiFe

@FliiFe entfernt nicht das ',' und '.' im letzten Testfall
Jeto

Seltsam ... Aber man kann immer noch ersetzen 0-9mit \d. Vielleicht sind die Regeln für reguläre Ausdrücke in SQL anders als in Python / PHP / Javascript? (js ist immer noch ein spezieller Fall, da es sich um einen Lookbehind handelt)
FliiFe

2

Haskell, 129 Bytes

import Data.List
import Data.Char
l=length
print.(foldl(const.map concat.groupBy((.l).(==).l).sortOn l)=<<(filter isAlphaNum<$>))

Akzeptiert und druckt eine Reihe von Zeichenfolgen. Wenn das Ergebnis von der Funktion zurückgegeben werden kann (im Gegensatz zu gedruckt zu stdout), können Sie das weglassen print.und 6 Bytes sparen.

Wie es funktioniert (Anmerkung, ich verwende xfür den Eingabeparameter, der in der obigen pointfree-Version natürlich nicht vorkommt):

 (    )=<<(     )          -- (f =<< g) x is f (g x) x, so we fold over x with a
                           -- starting value of:
     filter isAlphaNum<$>x -- keep only alphanumeric chars in every line of x

                           -- during folding, I ignore the the elements of x.
                           -- However folding stops the repeatedly applied function
                           -- after (length x) steps, which is enough for combining
                           -- lines of equal length

 const                     -- ignore elements from x, deal only with start value
                sortOn l   -- sort lines from shortest to longest
      groupBy((.l).(==).l) -- group lines of equal length
    map concat             -- concatenate each group      

print                      -- print result after (length x) iterations

2

Python 3, 184 180 Bytes

def f(x):l=len;m=filter;y=sorted([''.join(m(str.isalnum,i))for i in x],key=l);*z,=m(l,[''.join(i for i in y if-~j==l(i))for j in range(l(y[-1]))]);y==z and+print(*z,sep='\n')or f(z)

Eine Funktion, die die Eingabe als Argument als Liste von Zeichenfolgen akzeptiert und das Ergebnis an STDOUT ausgibt. Die Ausführung löst einen Fehler aus (aufgrund der Verwendung des Operators + vor der Druckanweisung), jedoch nicht bevor die Ausgabe gedruckt wurde.

Wie es funktioniert

def f(x):                              Function with input of list of strings
l=len;m=filter                         Redefine much-used functions: len gives the length
                                       of an object and filter chooses those items from an
                                       iterable for which a function is true
[''.join(m(str.isalnum,i))for i in x]  Strip to leave only alphanumeric characters...
y=sorted(...,key=l)                    ...and sort by length, into y
''.join(i for i in y if-~j==l(i))      Concatenate equal length strings...
[...for j in range(l(y[-1]))]          ...for all possible string lengths...
*z,=(m(l,...))                         ...and remove empty strings by filtering by length
                                       (the empty string has length 0, and is thus false),
                                       into z
y==z and+print(*z,sep='\n')...         If no change after concatenation, no more equal
                                       length strings exist, so print result to STDOUT...
...or f(z)                             ...else pass new list to function

Probieren Sie es auf Ideone


2

J , 48 Bytes

[:(/:#&>)[:(#&>,&.>//.])^:_(#~e.&AlphaNum_j_)&.>

Probieren Sie es online!

ungolfed

[: (/: #&>) [: (#&> ,&.>//. ])^:_ (#~e.&AlphaNum_j_)&.>

Erläuterung

  • (#~e.&AlphaNum_j_)&.> non alphanum entfernen
  • (#&> ,&.>//. ]) Artikel gleicher Länge kombinieren
  • ^:_ kombiniere weiter, bis es aufhört sich zu ändern
  • (/: #&>) nach Länge sortieren

1

Javascript 198 188 186 179 Bytes

Dies ist mein zweitlängstes Golf-Javascript-Programm

s=>s.replace(/[^\w]|_/g,``,l=0).split(/\s/g).sort(g=(a,b)=>a[m=`length`]-b[m]).reduce((a,b,c)=>a+(a.split(/\s/g)[c-1][m]<b[m]?`
`:` `)+b).replace(/ /g,``).split`
`.sort(g).join`
`

Wahrscheinlich kann weiter Golf gespielt werden


Wofür verwenden Sie die tVariable?
Gcampbell

Ok , so können Sie Golf durch y erklärt = „split“ und dann anstelle der Verwendung .split()Sie verwenden können[y]()
Bald Bantha

@ Gcampbell Das war nur ein Überbleibsel aus dem Test
Bálint

@BaldBantha Ich glaube nicht, dass es dadurch kürzer wird
Bálint

@BaldBantha Das habe ich allerdings mit einiger Länge gemacht
Bálint


1

Gelee , 17 Bytes

f€ØWṖ¤L€Ġị⁸Ẏ€µÐLY

Probieren Sie es online!

Nicht sicher, warum Ẏf¥€ØWṖ¤L€ĠịµÐLYnicht funktioniert ...

Erläuterung:

f€ØWṖ¤L€Ġị⁸Ẏ€µÐLY Full program
             µÐL  Execute the following until we get a result a second time
     ¤              The following as a nilad
  ØW                  [A-Za-z0-9_]
    Ṗ                 Remove last element (_)
f€                  Filter the left argument (current result) with the above nilad
       €            Left map
      L               Length
        Ġ           Group indices of same values, sort values
          ⁸         Left argument
         ị          Index on ^^ and ^
            €       Left map
           Ẏ          Concatenate elements
                Y Join on newlines (full program will display correctly)

1

Pyth, 22 Bytes

jlDusM.glkG@Ls++GrG1UT

Probieren Sie es hier aus.

Erläuterung:

jlDusM.glkG@Ls++GrG1UT
j                      join on newlines
 lD                     sort by length
   u                     run until duplicate result, return result (argument G, iteration number H)
    sM                    map concatenate elements
      .g                   group elements by function (argument k)
        l                   length
         k                   k
          G                 G
           @L             left map filter on presence (extra argument first)
             s             concatenate elements
              +             concatenate two items
               +             concatenate two items
                G             G (default = lowercase alphabet)
                 r 1          to uppercase
                  G            G
                    U        unary range [0..n)
                     T        T (default = 10)

1

Pyth, 39 Bytes

Zurück zum Golfen!

Da ist das Programm:

=Qm:d"[\W_]"kQKYLmsd.glkolNb;WnKQ=KQ=yQ;jQ

=Qm:d"[\W_]"kQLmsd.glkolNb;WnYQ=YQ=yQ;j

Teste es hier!

Erklärungen

=Qm:d"[\W_]"kQLmsd.glkolNb;WnYQ=YQ=yQ;j       (Implicit) Assign evaluated imput to Q (In this case, an array)
=Q                                            Reassign a value to Q
  m          Q                                map a function over Q
   :d"[\W_]"k                                 Replace any special character with an empty string
              L           ;                   Declare a function y(b)
                      olNb                      Sort b by length
                  .glk                          Group strings of same length in arrays
               msd                              Concat each inner array
                           WnYQ      ;        While Y != Q (previous array is not equal to current array)
                               =YQ              Assign the current array to Y (Y=Q)
                                  =yQ           Assign y(Q) to Q (Q=yQ). Here, the assigned variable name is implicit
                                      j       Display the resulting array

Versuchen Sie zu verwenden Rund Lstattm
Leaky Nun

1

Java 8, 268 Bytes

Ein ungültiges Lambda, das einen veränderlichen Wert annimmt List<String>(dh implementiert addund remove; zB ArrayList). Die Ausgabe wird standardmäßig ausgegeben, durch eine neue Zeile und eine nachfolgende neue Zeile getrennt. Besetzung für Consumer<List<String>>.

l->{int i=0,z;while(i<l.size())l.set(i,l.get(i++).replaceAll("\\W| ",""));while(l.size()>0){l.sort((s,t)->s.length()-t.length());String s=l.remove(0);for(i=0,z=s.length();l.size()>0&&l.get(0).length()==z;i++)s+=l.remove(0);if(i<1)System.out.println(s);else l.add(s);}}

Probieren Sie es online

Dies endete viel länger als ich erwartet hatte. Wie Kevin bemerkte, ist es komplizierter, als es auf den ersten Blick scheint.

Ungolfed Lambda

l -> {
    int i = 0, z;
    while (i < l.size())
        l.set(i, l.get(i++).replaceAll("\\W| ", ""));
    while (l.size() > 0) {
        l.sort((s, t) -> s.length() - t.length());
        String s = l.remove(0);
        for (
            i = 0, z = s.length();
            l.size() > 0 && l.get(0).length() == z;
            i++
        )
            s += l.remove(0);
        if (i < 1)
            System.out.println(s);
        else
            l.add(s);
    }
}

Zuerst reduziere ich die Eingabe auf Buchstaben und Zahlen. Ich verarbeite dann die Eingaben in Gruppen nach Länge. Ich hänge Elemente an das erste Element in der Liste an, bis die nächste Länge erreicht ist, und entferne sie nach und nach. Wenn nur das erste Element verwendet wurde, ist dies die einzige Zeichenfolge dieser Länge, sodass sie gedruckt wird. Andernfalls wird die verknüpfte Zeichenfolge zur Liste für eine weitere Iteration hinzugefügt. Ich sortiere die Liste nach der Länge jeder Iteration vor der Verwendung.

Ich begann mit einer reizenden Lösung, die eine Prioritätswarteschlange verwendete, um die Zwischenzeichenfolgen zu verfolgen. Leider java.util.PriorityQueue<String>ist es ziemlich lang (und die Verwendung des Rohtyps war länger), also musste es gehen.


1

Japt v2.0a1 -h, 11 Bytes

Eingabe und Ausgabe als Arrays von Strings.

£=mk\W üÊmq

Versuch es

£=mk\L üÊmq
                :Implicit input of string array U
£               :Map
  m             :  Map U
   k            :    Remove
    \W          :    /[^A-Z0-9]/gi
       ü        :  Sort & partition by
        Ê       :    Length
         m      :  Map
          q     :    Join
 =              :  Reassign to U for next iteration
                :Implicit output of last element

Obwohl ich zu diesem Zeitpunkt vergessen habe, Testfälle hinzuzufügen (ich werde jetzt einen hinzufügen), sollten Ziffern auch in den Zeichenfolgen aufbewahrt werden (also [a-zA-Z0-9]statt [a-zA-Z]).
Kevin Cruijssen

@ KevinCruijssen, behoben
Shaggy

1

JavaScript, 119 Bytes

Ich denke, das sollte viel kürzer sein ...

Enthält 2 führende Zeilenumbrüche in der Ausgabe.

f=s=>s==(s.replace(/[^\w\n]|_/g,t=``).split`
`.sort((x,y)=>x[l=`length`]-y[l]).map(x=>t+=s==(s=x[l])?x:`
`+x),t)?t:f(t)

Probieren Sie es online aus


Ein negativer Zeichenbereich scheint ein globales Flag anzunehmen, daher können Sie den Wert gfür 118
Jan

@
Shaggy

Dann muss es die Rekursion sein, noch können Sie die globale Flagge fallen
Jan



1

Pyth, 21 Bytes

jusM.glkG:R"[^\w\d]"k

Die Eingabe ist eine Liste von Zeichenfolgen. Probieren Sie es hier online aus oder überprüfen Sie alle Testfälle hier .

jusM.glkG:R"[^\w\d]"kQ   Implicit: Q=eval(input()), k=""
                         Trailing Q inferred
          R          Q   For each string in Q...
         : "[^\w\d]"     ... replace non-alphanumerics...
                    k    ... with k (empty string)
 u                       Repeat the following until a fixed point occurs, current as G:
    .g  G                  Group the elements of G...
      lk                   ... by length
                             Groups ordered by the result of the inner function, i.e. length
                             This means that, in the final iteration, this acts as a sort by length
  sM                       Concatenate each group back into a string
j                        Join the resulting list on newlines, implicit print

0

05AB1E , 16 Bytes

εžKÃ}»Δ¶¡é.γg}J»

Eingabe als Liste von Zeichenfolgen.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Könnten 14 Bytes sein, εžKÃ}Δé.γg}J}»wenn Δdas auch mit einer Liste von Strings funktionieren würde.

Erläuterung:

ε   }            # Map the (implicit) input-list of strings:
 žjà             #  Leave only the letters and digits of each string
                 #   i.e. ["a","bc","d!","123"] → ["a","bc","d","123"]
     »           # Join the list by newlines to a single string
                 #  i.e. ["a","bc","d","123"] → "a\nbc\nd\n123"
      Δ          # Loop until the string no longer changes:
       ¶¡        #  Split by newlines
                 #   i.e. "a\nbc\nd\n123" → ["a","bc","d","123"]
          }    #  Group the strings by:
           g     #   Their length
                 #    i.e. ["a","bc","d","123"] → [["a,"d"],["bc"],["123"]]
             J   #  Join each group-list to a single string
                 #   i.e. [["a,"d"],["bc"],["123"]] → ["ad","bc","123"]
              »  #  Join this list by newlines again
                 #   i.e. ["ad","bc","123"] → "ad\nbc\n123"
                 # (and the result is output implicitly after the loop)
                 #  i.e. "123\nadbc"

-1

PowerShell, Windows 10, 63 Bytes

Also Eingabe ...

$n = @"
This is a sample text,
that you will have to use to build stairs.
The wood may be of excellent quality,
or pretty crappy almost falling apart and filled with termites.
Bla bla bla - some more text
Ok, that will do
"@

und Code ...

((($n -Split '\n').Replace(" ","")) -Replace '[\W]','')|Sort *h

Das deckt Input / Output 1 ab und arbeitet an 2 und 3 ...


Willkommen bei PPCG! Wir erlauben normalerweise keine Eingabe durch Setzen einer Variablen. Sie müssten entweder eine Funktion erstellen, die ein Argument entgegennimmt, oder Eingaben von STDIN, einem Befehlszeilenargument oder ähnlichem entgegennehmen.
Stephen

1
Willkommen bei PPCG! Zusätzlich zu dem, was @StepHen gesagt hat, schlägt Ihre aktuelle Antwort für den Sonderfall fehl. Alles wird nur einmal zusammengefügt und sortiert, aber es werden keine gleich großen Zeilen zusammengefügt und erneut sortiert. (Siehe Testfall 2.)
Kevin Cruijssen
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.