Marque uma expressão com tipo

10

Dada uma expressão infix, determine se todas as constantes são do mesmo tipo.

Os operadores consistirão apenas desses operadores diádicos :+-/*

Seu programa ou função deve usar uma string de expressão válida como entrada e gerar um valor verdadeiro se as constantes na expressão forem do mesmo tempo e um valor falsey caso contrário.

A expressão consistirá apenas em constantes e pode conter qualquer um dos seguintes tipos:

  • String, no formato "String" (Sempre as aspas duplas, podem estar vazias, sem caracteres de escape, podem conter qualquer texto ASCII)
  • Inteiro, da forma 14 (Sempre positivo ou zero)
  • Flutuante, na forma 7.3f(Sempre positivo ou zero, sempre tem um componente decimal, por exemplo14.0f )
  • Byte, no formato 0x42( 0-255, Sempre 2 caracteres hexadecimais)
  • Booleano, no formato true( trueou false, sem distinção entre maiúsculas e minúsculas)

A expressão não conterá parênteses, pois a ordem da operação não afeta o tipo quando não há coerção de tipo.

Uma constante solitária sem operadores é uma expressão válida.

Uma expressão vazia não é uma expressão válida.

Você pode assumir que a cadeia de expressão não contém espaços em branco fora dos literais da cadeia.
Nota: Como alternativa, você pode assumir que sempre haverá espaços entre constantes e operadores, como visto nos casos de teste. Se você fizer essa suposição, especifique como tal em sua resposta

Você não precisa lidar com expressões inválidas, como 1 +.

Pontuação

Isso é , e o menor número de bytes vence!

Casos de teste

(Espaço em branco adicionado para facilitar a leitura)

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
fonte
4
O "case insensitive" para valores booleanos significa que temos de apoiar todos os casos? Ou que podemos decidir qual caso usar?
Arnauld
@Arnauld deve suportar todos os casos
Skidsdev
@ JonathanAllan Minha interpretação foi que tivemos que lidar com qualquer mistura de casos (por exemplo truE+fALSe). Caso contrário, posso salvar dois bytes na minha solução.
24519 Nick Kennedy

Respostas:

9

JavaScript (ES6),  79 77  75 bytes

Guardado 2 bytes graças a @ExpiredData

Espera espaço em branco ao redor dos operadores. Retorna um valor booleano.

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

Experimente online!

Quão?

  1. Nós removemos todas as strings, usando /".*?"/g
  2. Removemos todos os bytes, usando /0x../g
  3. Removemos todos os carros alegóricos, usando /\S+f/g
  4. Procuramos um dígito restante com /\d/ ; se encontrarmos um, deve haver pelo menos um número inteiro
  5. Procuramos um restante "e"ou "E"com /e/i; se encontrarmos um, deve haver pelo menos um valor booleano

Todas as expressões removidas são substituídas por uma vírgula, que é inofensiva.

Nós filtramos as expressões regulares que não causam alterações na sequência de entrada e testamos se menos de duas delas permanecem no final do processo.

Arnauld
fonte
truee falsesão marcados como não diferenciando maiúsculas de minúsculas, acho que isso significa que você precisa fazer com que o seu regex ignore maiúsculas e minúsculas ao procurá-las te s(embora eu possa estar errado).
Jonathan Allan
1
@ JonathanAllan Coloquei uma correção temporária e perguntei ao OP.
Arnauld
75 bytes
Dados expirados
@ExpiredData Nice. :) Obrigado!
Arnauld
3

Perl 5 -p , 73 bytes

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

Experimente online!

Quão?

Tente remover cadeias, flutuadores, hexadecimal, booleano e números inteiros, nessa ordem. Pare assim que algo for removido. Após parar, verifique se a sequência restante consiste apenas em operadores e espaço em branco. Caso isso aconteça, a verificação do tipo é verdadeira; se não, é falso.

Primeira tentativa: 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}}{

Experimente online!

Xcali
fonte
$_=/^[+\/* -]*$/pode ser alterado por $_=!y#-+/* ##c, e ....?epor.*e
Nahuel Fouilleul 2/19/19
caso contrário, em um regex, 63 bytes
Nahuel Fouilleul 2/19/19
58 bytes assumindo que haverá sempre espaços entre constantes e operadores
Nahuel FOUILLEUL
2

Geléia , 30 23 bytes

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

Experimente online!

Um link monádico que recebe uma string como entrada e retorna 1 para true e 0 para false (valores booleanos de Jelly). Espera espaço em branco ao redor dos operadores.

Adicionei alguns novos casos de teste ao TIO, incluindo um com três operadores e um com caso misto para booleanos.

Explicação

ṣ”"                     | 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
fonte
1

05AB1E , 50 24 bytes

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

-26 bytes criando uma porta para a resposta de @NickKennedy 's Jelly , portanto, !!

Espera entrada com espaços nos operandos.

Experimente on-line ou verifique todos (mais alguns) casos de teste .

Explicação:

'"¡         '# 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
fonte
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))

Experimente online!

Não tenho muita certeza de como representar alguns desses tipos no Python. Por exemplo, 0xff e 2 são tratados como números inteiros. E 2.4f não é um tipo válido em Python, eu acho. Capitalizado Verdadeiro e Falso para testar booleanos.

Editar: Gramática

GotCubes
fonte
3
Vai falhar o último caso de teste
Personificação da Ignorância
... e (como está) o true * falseprimeiro.
Jonathan Allan
Passa para "Verdadeiro * Falso". Eu posso tentar fazê-lo funcionar com letras minúsculas, mas achei que, uma vez que os bools são sempre capitalizados em python, isso seria suficiente.
GotCubes
3
Atualmente, isso não atende aos critérios de desafio. Ou seja: ele não controla booleans caso insensível, ele erros em carros alegóricos, e incorretamente retorna true quando dada uma expressão consistindo de bytes e inteiros
Skidsdev
0

Stax , 26 bytes

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

Execute e depure

Este programa espera espaços ao redor dos operadores. Em geral, ele funciona aplicando algumas transformações à entrada, de modo que o caractere máximo para cada tipo de expressão seja distinto.

Descompactado, não jogado e comentado, parece com isso.

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

Execute este

recursivo
fonte
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
fonte
2
f x=let z=...in ...pode ser f x|z<-...=....
Jonathan Frech