Escriba-verifique una expresión

10

Dada una expresión infija, determine si todas las constantes son del mismo tipo.

Los operadores consistirán solo en estos operadores diádicos :+-/*

Su programa o función debe tomar una cadena de expresión válida como entrada y generar un valor verdadero si las constantes en la expresión son del mismo tiempo, y un valor falso de lo contrario.

La expresión consistirá únicamente en constantes y puede contener cualquiera de los siguientes tipos:

  • Cadena, de la forma "String"(siempre comillas dobles, puede estar vacía, sin caracteres de escape, puede contener cualquier texto ASCII)
  • Entero, de la forma 14(siempre positivo o cero)
  • Flotante, de la forma 7.3f(Siempre positivo o cero, siempre tiene un componente decimal, por ejemplo 14.0f)
  • Byte, de la forma 0x42( 0-255, siempre 2 caracteres hexadecimales)
  • Booleano, de la forma true( trueo falsemayúsculas y minúsculas)

La expresión no contendrá paréntesis, ya que el orden de operación no afecta el tipo cuando no hay coerción de tipo.

Una constante solitaria sin operadores es una expresión válida.

Una expresión vacía no es una expresión válida.

Puede suponer que la cadena de expresión no contiene espacios en blanco fuera de los literales de cadena.
Nota: Alternativamente, puede suponer que siempre habrá espacios entre constantes y operadores, como se ve en los casos de prueba. Si hace esta suposición, especifique como tal en su respuesta

No tiene que manejar expresiones no válidas como 1 +.

Puntuación

Este es el , ¡por lo que gana menos bytes!

Casos de prueba

(Espacio en blanco agregado para facilitar la lectura)

2 + 3
True

"Hello" / "World"
True

true * false
True

"Hello" + 4
False

"Hello" + "4"
True

3 + 2.4f / 8
False

0xff * 0xff
True

0xff + 2
False

6
True

" " + ""
True

"4 + false" + "word"
True
Skidsdev
fuente
44
¿ " No distingue entre mayúsculas y minúsculas" para los valores booleanos significa que tenemos que admitir todos los casos? ¿O que podemos decidir qué caso usar?
Arnauld
@Arnauld debe admitir todos los casos
Skidsdev
@JonathanAllan mi interpretación fue que teníamos que manejar cualquier combinación de casos (por ejemplo truE+fALSe). Si no, puedo guardar dos bytes en mi solución.
Nick Kennedy el

Respuestas:

9

JavaScript (ES6),  79 77  75 bytes

Guardado 2 bytes gracias a @ExpiredData

Espera espacios en blanco alrededor de los operadores. Devuelve un valor booleano.

s=>![/".*?"/g,/0x../g,/\S+f/g,/\d/,/e/i].filter(e=>s!=(s=s.split(e)+''))[1]

Pruébalo en línea!

¿Cómo?

  1. Eliminamos todas las cadenas, usando /".*?"/g
  2. Eliminamos todos los bytes, usando /0x../g
  3. Eliminamos todos los flotadores, usando /\S+f/g
  4. Buscamos un dígito restante con /\d/; si encontramos uno, debe haber al menos un número entero
  5. Buscamos un remanente "e"o "E"con /e/i; si encontramos uno, debe haber al menos un valor booleano

Todas las expresiones eliminadas se reemplazan realmente con una coma, que es inofensiva.

Filtramos las expresiones regulares sin causar ningún cambio en la cadena de entrada y probamos si quedan menos de dos al final del proceso.

Arnauld
fuente
truey falseestán marcados como insensibles a mayúsculas y minúsculas, creo que eso significa que debe hacer que su expresión regular ignore mayúsculas y minúsculas al buscar estos ty s(aunque podría estar equivocado).
Jonathan Allan
1
@ JonathanAllan He puesto una solución temporal y le pedí al OP.
Arnauld
75 bytes
Datos vencidos
@ExpiredData Nice. :) ¡Gracias!
Arnauld
3

Perl 5 -p , 73 bytes

for$f(qw/".*?" \d+.\d+f 0x.. ....?e \d+/){s/$f//gi&&last}$_=/^[+\/* -]*$/

Pruébalo en línea!

¿Cómo?

Intente eliminar cadenas, flotantes, hexadecimales, booleanos y enteros, en ese orden. Detente tan pronto como se elimine algo. Después de detenerse, verifique si la cadena restante consta solo de operadores y espacios en blanco. Si lo hace, la verificación de triplicación es verdadera; Si no, es falso.

Primer intento: Perl 5 -MList::Util=all -p, 99 bytes

s/".*?"/!/g;for$f(qw/! \d+ \d+\.\d+f 0x[0-9a-f]{2} (true|false)/){$\||=all{/^$f$/i}/[^+\/* -]+/g}}{

Pruébalo en línea!

Xcali
fuente
$_=/^[+\/* -]*$/puede ser cambiado por $_=!y#-+/* ##c, y ....?epor.*e
Nahuel Fouilleul
de lo contrario en una expresión regular, 63 bytes
Nahuel Fouilleul
58 bytes suponiendo que siempre habrá espacios entre constantes y operadores
Nahuel Fouilleul
2

Jalea , 30 23 bytes

ṣ”"ŒœḢYŒlḲŒœḢeþ@“.e¶x”E

Pruébalo en línea!

Un enlace monádico que toma una cadena como entrada y devuelve 1 para verdadero y 0 para falso (valores booleanos de Jelly). Espera espacios en blanco alrededor de los operadores.

He agregado algunos casos de prueba nuevos al TIO, incluido uno con tres operadores y uno con mayúsculas y minúsculas para booleanos.

Explicación

ṣ”"                     | Split input at double-quotes
   Œœ                   | Split into two lists, one of odd indices and one even. The even indices will have the contents of the quoted bits in the input (if any)
     Ḣ                  | Keep only the odd-indexed items
      Y                 | Join with newlines (so now all quoted strings in input are a single newline)
       Œl               | Convert to lower case (so that booleans are case insensitive)
         Ḳ              | Split at spaces
          ŒœḢ           | As before just take odd indices
             eþ@“.e¶x”  | Check for each section which they contain of .e¶x (respectively floats, booleans, strings and hex; integers will have none of these)
                      E | Check each section is equal (will return true for single section)
Nick Kennedy
fuente
1

05AB1E , 50 24 bytes

'"¡āÉÏ»lð¡āÉÏε".e
x"Så}Ë

-26 bytes haciendo un puerto de la respuesta Jelly de @NickKennedy , ¡así que asegúrate de votarlo!

Espera entrada con espacios en los operandos.

Pruébelo en línea o verifique todos (y algunos más) casos de prueba .

Explicación:

'"¡         '# Split the (implicit) input-string by '"'
   āÉÏ       # Only keep all values at 0-based even indices
      »      # Join them by newlines
       l     # Converted to lowercase (for `true`/`false`)
ð¡           # Split by spaces (NOTE: `#` cannot be used here, since inputs without
             # operands wouldn't be wrapped inside a list)
  āÉÏ        # Keep all values at 0-based even indices again
     ε".e
     x"Så}   # Check for each item for each of [".","e","\n","x"] if it's in the item
          Ë  # Check if all inner lists are the same
             # (which is output implicitly as result)
Kevin Cruijssen
fuente
0

Python 2 , 102 bytes

import re
def f(s):
	m=map(eval,re.split('[*+-/]',s))
	return all(map(lambda t:type(t)==type(m[0]),m))

Pruébalo en línea!

No estoy completamente seguro de cómo representar algunos de estos tipos en Python. Por ejemplo, 0xff y 2 se tratan como enteros. Y 2.4f no es un tipo válido en Python, creo. Verdadero y falso en mayúscula para probar booleanos.

Editar: Gramática

GotCubes
fuente
3
Fracasará el último caso de prueba
Encarnación de la ignorancia
... y (tal como está) el true * falseuno.
Jonathan Allan
Se pasa por "Verdadero * Falso". Puedo intentar que funcione con minúsculas, pero pensé que ya que los bools siempre están en mayúsculas en Python, sería suficiente.
GotCubes
3
Actualmente esto no cumple con los criterios de desafío. A saber: no maneja mayúsculas y minúsculas insensiblemente, comete errores en los flotantes y devuelve incorrectamente verdadero cuando se le da una expresión que consiste en bytes y enteros
Skidsdev
0

Stax , 26 bytes

ïd"┬Z\¡►L!8$lm╗╕╤☻ú≡╝ò6Å>^

Ejecutar y depurarlo

Este programa espera espacios alrededor de los operadores. En general, funciona aplicando algunas transformaciones a la entrada de modo que el carácter máximo para cada tipo de expresión sea distinto.

Desempaquetado, sin golf y comentado, se ve así.

i           suppress automatic evaluation of input
'"/2::'s*   replace quoted strings with 's'
.\d'9R      replace all digits with '9'
.ez|t       replace 'e' with 'z'
j2::        split on spaces, and discard alternating groups (operators)
{|Mm        calculate the maximum character in each remaining group
:u          resulting array contains exactly one distinct value

Ejecute este

recursivo
fuente
0

Haskell, 140 bytes

r(a:t)|a=='"'=a:r(tail$snd$span(/=a)t)|elem a"+-*/"=r t|0<1=a:r t
r n=n
f x|z<-[last$'i':(filter(`elem`t)"fex\"")|t<-words$r x]=all(==z!!0)z
Benji
fuente
2
f x=let z=...in ...puede ser f x|z<-...=....
Jonathan Frech