Decidi un valore letterale intero C.
Obbiettivo
Data una stringa ASCII, decidere se si tratta di un valore letterale intero C valido.
C intero letterale
Il valore letterale intero AC è costituito da:
Uno di:
0seguito da zero o più cifre ottali (0-7)Una cifra decimale diversa da zero seguita da zero o più cifre decimali (
0-9)0Xoppure0x, seguito da una o più cifre esadecimali (0-9,A-Fea-f)
facoltativamente seguito da uno di:
Uno tra
Uou, che sono i suffissi "non firmati"Uno dei
L,l,LL, oll, che sono il "lungo" e "long long" suffissiQualsiasi combinazione di quanto sopra, in qualsiasi ordine.
Tieni presente che possono esserci molte cifre arbitrariamente, anche se C non supporta interi di lunghezza arbitraria. Allo stesso modo, anche se il letterale with le co superasse il longtipo o co, è comunque considerato un letterale valido.
Si noti inoltre che ci deve non essere un segno che porta più o meno, perché non è considerato una parte del letterale.
Regole
È definito dall'implementazione per accettare spazi bianchi iniziali o finali.
La stringa non ASCII rientra nella situazione non importa .
Esempi
Verità
000742u42lu42UL19827489765981697847893769837689346573uLL(Le cifre possono essere arbitrariamente molte anche se non si adattano alunsigned long longtipo)0x8f6aa032838467beee3939428l(Così può per illongtipo)0XCa0(Puoi mescolare i casi)
Falsità
08(Cifra non ottale)0x(Una cifra deve seguireXox)-42(La firma principale non fa parte del letterale)42Ll(SoloLLollè valido per illong longtipo)42LLLL(Identificatore di tipo ridondante)42Uu(Identificatore di tipo ridondante)42Ulu(Identificatore di tipo ridondante)42lul(Identificatore di tipo ridondante)42H(Identificatore di tipo non valido)0b1110010000100100001(C ++ valido, ma non C valido)HelloStringa vuota
Soluzione ungolfed
Haskell
Non riconosce gli spazi bianchi iniziali o finali.
Ritorno ()in caso di successo. Altrimenti fallimento monadico.
import Text.ParserCombinators.ReadP
decideCIntegerLit :: ReadP ()
decideCIntegerLit = do
choice [
do
'0' <- get
munch (flip elem "01234567"),
do
satisfy (flip elem "123456789")
munch (flip elem "0123456789"),
do
'0' <- get
satisfy (flip elem "Xx")
munch1 (flip elem "0123456789ABCDEFabcdef")
]
let unsigned = satisfy (flip elem "Uu")
let long = string "l" +++ string "L" +++ string "ll" +++ string "LL"
(unsigned >> long >> return ()) +++ (optional long >> optional unsigned)
eof
Risposte
Retina 0.8.2 , 60 59 byte
i`^(0[0-7]*|0x[\da-f]+|[1-9]\d*)(u)?(l)?(?-i:\3?)(?(2)|u?)$
Provalo online! Il collegamento include casi di test. Modifica: 1 byte salvato grazie a @FryAmTheEggMan. Spiegazione:
i`
Trova la corrispondenza tra maiuscole e minuscole.
^(0[0-7]*|0x[\da-f]+|[1-9]\d*)
Inizia con ottale, esadecimale o decimale.
(u)?
Identificatore non firmato facoltativo.
(l)?
Specificatore di lunghezza opzionale.
(?-i:\3?)
Facoltativamente, ripetere il caso dello specificatore di lunghezza in modo sensibile.
(?(2)|u?)$
Se non esiste ancora uno specificatore senza segno, un'altra possibilità per uno specificatore facoltativo, prima della fine del letterale.
Perl 5 -p , 65 61 byte
@NahuelFouilleul ha rasato 4 byte
$_=/^(0[0-7]*|0x\p{Hex}+|[1-9]\d*)(u?l?l?|l?l?u?)$/i*!/lL|Ll/
Provalo online!
Java 8 / Scala polyglot, 89 79 byte
s->s.matches("(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\\d*|0x[\\da-f]+)(u?l?l?|l?l?u?)")
-10 byte grazie a @NahuelFouilleul
Provalo online in Java 8.
Provalo online in Scala (eccetto con =>invece di ->- grazie a @TomerShetah ).
Spiegazione:
s-> // Method with String parameter and boolean return-type
s.matches( // Check whether the input-string matches the regex
"(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\\d*|0x[\\da-f]+)(u?l?l?|l?l?u?)")
Spiegazione dell'espressione regolare:
In Java, il String#matchesmetodo aggiunge implicitamente un interlinea e uno finale ^...$per abbinare l'intera stringa, quindi la regex è:
^(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)$
(?! ) # The string should NOT match:
^ .* # Any amount of leading characters
( ) # Followed by:
Ll # "Ll"
|lL # Or "lL"
# (Since the `?!` is a negative lookahead, it acts loose from the
# rest of the regex below)
(?i) # Using case-insensitivity,
^ ( # the string should start with:
0 # A 0
[0-7]* # Followed by zero or more digits in the range [0,7]
| # OR:
[1-9] # A digit in the range [1,9]
\d* # Followed by zero or more digits
| # OR:
0x # A "0x"
[ ]+ # Followed by one or more of:
\d # Digits
a-f # Or letters in the range ['a','f']
)( # And with nothing in between,
)$ # the string should end with:
u? # An optional "u"
l?l? # Followed by no, one, or two "l"
| # OR:
l?l? # No, one, or two "l"
u? # Followed by an optional "u"
C # (.NET Core) ,
197191
byte
@nwellnhof rasato 6 byte:
using c=System.Console;class P{static void Main(){c.WriteLine(System.Text.RegularExpressions.Regex.IsMatch(c.ReadLine(),@"^(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)$"));}}
Originale:
using c=System.Console;using System.Text.RegularExpressions;class P{static void Main(){c.WriteLine(Regex.IsMatch(c.ReadLine(),@"^(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)$"));}}
Provalo online!
Python 3 , 103 byte
import re;re.compile("^(0[0-7]*|[1-9]\d*|0[xX][\dA-Fa-f]+)([uU](L|l|LL|ll)?|(L|l|LL|ll)[uU]?)?$").match
Provalo online!
solo una regex di base, probabilmente molto subottimale
restituisce un oggetto match per true e None per falsy; l'input non può contenere spazi bianchi circostanti
-3 byte grazie a Digital Trauma (sulla mia risposta Retina)
-1 byte grazie a FryAmTheEggman (sulla mia risposta Retina)
-3 byte grazie a pxeger
Retina 0.8.2 , 73 byte
^(0[0-7]*|[1-9]\d*|0[xX][\dA-Fa-f]+)([uU](L|l|LL|ll)?|(L|l|LL|ll)[uU]?)?$
Provalo online!
Proprio la stessa regex che ho usato. La prima volta che usi Retina, sono sicuro che può essere ottimizzato con alcune cose del golf Retina!
-3 byte grazie a Digital Trauma
-1 byte grazie a FryAmTheEggman
JavaScript (ES6), 77 byte
s=>/^(0x[\da-f]+|0[0-7]*|[1-9]\d*)(u?l?l?|l?l?u?)$/i.test(s)&!/Ll|lL/.test(s)
Provalo online!
Come?
La prima regex non fa distinzione tra maiuscole e minuscole. Gli unici pattern non validi che non possono essere filtrati in questo modo sono "Ll"e "lL". Quindi usiamo una seconda espressione regolare che distingue tra maiuscole e minuscole per prenderci cura di loro.
Carboncino , 76 byte
≔⊟Φ³¬⌕↧θ…0xιη≔✂↧θη⁻LθL⊟Φ⪪”{“↧←;⭆δa”¶⁼ι↧…⮌θLι¹ζ›∧⁺Lζ¬⊖η⬤ζ№E∨×⁸ηχ⍘λφι∨№θLl№θlL
Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:
≔⊟Φ³¬⌕↧θ…0xιη
Trova la lunghezza del prefisso più lungo di 0xnell'input minuscolo.
≔✂↧θη⁻LθL⊟Φ⪪”{“↧←;⭆δa”¶⁼ι↧…⮌θLι¹ζ
Tagliare via il prefisso e controllare anche per un suffisso minuscolo di ull, ul, lluo lu, in caso affermativo poi tagliare che fuori pure.
›...∨№θLl№θlL
L'input originale non deve contenere Llo lL.
∧⁺Lζ¬⊖η
La stringa suddivisa in sezioni non deve essere vuota a meno che non lo sia il prefisso 0.
⬤ζ№E∨×⁸ηχ⍘λφι
Convertire la lunghezza del prefisso a 10, 8o 16opportunamente, poi prendere che molti di base 62 cifre e verificare che tutti i caratteri rimanenti sono cambiate in maiuscolo una di quelle cifre.
05AB1E , 63 61 62 byte
„Uuõª„LLæDl«âDí«JéRʒÅ¿}нõ.;Ðć_ilDć'xQiA6£мÐþQë\7ÝKõQë\þQ}sõÊ*
Questo non è troppo facile senza regex ..: / Può sicuramente essere giocato un po 'di più, però.
+1 byte come bug-fix per ingressi desiderate "u", "l", "LL", ecc (grazie per notare @Neil )
Provalo online o verifica tutti i casi di test .
Spiegazione:
„Uu # Push string "Uu"
õª # Convert it to a list of characters, and append an empty string:
# ["U","u",""]
„LL # Push string "LL"
æ # Take its powerset: ["","L","L","LL"]
Dl # Create a lowercase copy: ["","l","l","ll"]
« # Merge the lists together: ["","L","L","LL","","l","l","ll"]
â # Create all possible pairs of these two lists
Dí # Create a copy with each pair reversed
« # Merge the list of pairs together
J # Join each pair together to a single string
éR # Sort it by length in descending order
Ora abbiamo l'elenco:
["llu","LLu","llU","LLU","ull","uLL","Ull","ULL","ll","LL","lu","lu","Lu","Lu","lU","lU","LU","LU","ll","LL","ul","ul","uL","uL","Ul","Ul","UL","UL","l","l","L","L","u","u","U","U","l","l","L","L","u","u","U","U","","","",""]
ʒ # Filter this list by:
Å¿ # Where the (implicit) input ends with this string
}н # After the filter: only leave the first (longest) one
õ.; # And remove the first occurrence of this in the (implicit) input
ÐD # Triplicate + duplicate (so there are 4 copies on the stack now)
ć # Extract head; pop and push remainder-string and first character
# separated to the stack
_i # If this first character is a 0:
l # Convert the remainder-string to lowercase
D # Duplicate it †¹
ć # Extract head again
'xQi '# If it's equal to "x":
A # Push the lowercase alphabet
6£ # Only leave the first 6 characters: "abcdef"
м # Remove all those characters from the string
Ð # Triplicate it †²
þ # Only keep all digits in the copy
Q # And check that the two are still the same
# (thus it's a non-negative integer without decimal .0s)
ë # Else:
\ # Discard the remainder-string
7Ý # Push list [0,1,2,3,4,5,6,7]
K # Remove all those digits
õQ # Check what remains is an empty string
ë # Else:
\ # Discard the remainder-string
þ # Only keep all digits
Q # And check that the two are still the same
# (thus it's a non-negative integer without decimal .0s)
}s # After the if-else: Swap the two values on the stack
# (this will get the remaining copy of †² for "0x" cases,
# or the remaining copy of †¹ for other cases)
õÊ # Check that this is NOT an empty string
* # And check that both are truthy
# (after which the result is output implicitly)
AWK , 86 byte
{print/^(0[0-7]*|[1-9][0-9]*|0[xX][0-9A-Fa-f]+)([uU](L|l|LL|ll)?|(L|l|LL|ll)[uU]?)?$/}
Provalo online!
Stampa semplicemente vero o falso a seconda che la riga di input corrisponda o meno all'espressione regolare. Non accetta spazi iniziali o finali.
Haskell , 169 byte
import Data.Char
s!p=s>""&&dropWhile p s`elem`do u<-["","u","U"];l<-"":words"L l LL ll";[u++l,l++u]
f('0':x:s)|elem x"xX"=s!isHexDigit|1<2=(x:s)!isOctDigit
f s=s!isDigit
Provalo online!
Ruby , 67 byte
->s{/^(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)?$/i=~s&&/Ll/!~s}
Provalo online!
Elisir , 74 byte
&(&1=~~r/^(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)?$/i&&!(&1=~~r/Ll/))
Provalo online!