¡No es nada! …¿O es eso?

24

Introducción

La conversación callejera puede ser realmente difícil de entender, en particular para los programadores, que no son conocidos por ser muy callejeros.

Es su trabajo crear un intérprete para ayudarnos a todos a sobrevivir en el entorno urbano.

Reto

Dada una oración en inglés como entrada, cree un programa o una función que determine si el resultado de la oración es positivo o negativo.

La sentencia contendrá 0a 2palabras negativas. Como cualquier programador sabe, un doble negativo resulta positivo. Por lo tanto, su código debe generar o devolver un valor verdadero / falso según la siguiente regla:

No negative words  -> truthy
One negative word  -> falsey
Two negative words -> truthy

La lista de palabras negativas:

  • no` not`none
  • Cualquier cosa que termine en n't
  • never` neither`nor
  • nobody` nothing`nowhere

Hay un caso de borde. Cada vez que comienza una oración No,, esa palabra no se trata como una palabra negativa al determinar el resultado (cuenta para el número de palabras negativas, por lo que puede haber solo una más).

La oración seguirá las reglas gramaticales básicas (mayúsculas, puntuación) y solo contendrá palabras que se pueden encontrar en un diccionario (por suerte, esto no invalida el título de la pregunta). La oración no contendrá ningún nombre propio (lo siento, Dr. No, estás fuera).

Casos de prueba

Verdad:

Yes.
It's noon.
Hello, World!
What is this?
Ain't no thang!
Never say never.
No, it's noon now.
Neither me nor you.
I didn't do nothing!
No, I am your father.
A non-alcoholic drink.
I can't get no satisfaction.
All your base are belong to us.

Falsey

No.
No, no!
Not today.
Neither am I.
Don't do that!
That's no moon!
And none survived.
Is this not my car?
No man is an island.
Nosebleeds are no fun.
Nothing compares to you.
That's a no, I'm afraid.
No, I am not your mother.

La ironía aquí, por supuesto, es que algunos de estos deben interpretarse de manera diferente. Pero bueno, no puedes culpar al orador por no ajustarse a nuestra lógica.

Reglas

Las lagunas estándar están prohibidas. Este es el , ¡así que sé conciso!

Antti29
fuente
1
Nadie nunca ha estado ni en ninguna parte ni en nada.
Magic Octopus Urn
1
@MagicOctopusUrn: ¡Puedes perder beenuna oración 100% negativa!
Antti29

Respuestas:

10

Retina , 63 bytes

No,

Mi`\bn(e(ith|v)er|o(|body|ne|r|t|thing|where))\b|n't\b
0|2

Pruébalo en línea!

Explicación

No,

Eliminar No,de la entrada. Debido a las reglas de capitalización, esto solo puede aparecer al comienzo de la entrada, por lo que no necesitamos un explícito ^.

Mi`\bn(e(ith|v)er|o(|body|ne|r|t|thing|where))\b|n't\b

Cuente el número de coincidencias de la expresión regular sin distinción entre mayúsculas y minúsculas después de `. Simplemente coincide con todas las palabras relevantes, donde he extraído prefijos / sufijos comunes con las alternativas.

0|2

Cuenta 0o 2s, entonces convertimos incluso cuentas en1 pares en cuentas impares 0.

Martin Ender
fuente
¿hace la extracción de letras comunes a mano o utiliza un programa que encuentre la solución óptima para usted?
Jonás
@ Jonás lo hice a mano. Existen herramientas para el metagolf regex automatizado, pero generalmente toman dos listas, una para coincidir y otra para fallar, y generan una expresión regular para eso. No conozco ninguna herramienta que genere una expresión regular óptima para que coincida con un conjunto particular de subcadenas en una cadena más grande.
Martin Ender
3
podría ser un desafío interesante ...
Jonás
Debería poder asumir que n'tno es necesario \bdespués de eso, ya que las palabras tienen que venir de un diccionario. Además, tenía lo mismo, pero no tenía la esencia de la respuesta de manera concisa, usando un par de bytes más.
mbomb007
8

Bash, 115 107 99 98 97 95 85 bytes

Utiliza paquetes Core Utilities (para wc) y grep. Suponga que la oración se da a través de la entrada estándar. La expansión del historial está deshabilitada por set +o histexpand.

((~`grep -Pio "(?!^no,)\b(no(|t|r|ne|body|thing|where)|ne(v|ith)er|.*n't)\b"|wc -l`%2))

Verifique el resultado: en Bash 0 es verdadero, 1 es falso

¿Como funciona?

((                       )) # Logical evaluation: non-zero to TRUE, zero to FALSE
  ~                    %2   # C-style arithmetic: Bit-Negate and Modulus 2
   $(                 )     # Output of the program chain
     grep -Pio "regex"      # PCRE match, ignore case, output matching part one-per-line
     | wc -l                # Pipe to `wc` and count number of lines

18 bytes (115 a 99) guardados por la inspiración de Qwertiy 's respuesta y Martin Ender ' s respuesta . 1 byte gracias a Nahuel Fouilleul .

iBug
fuente
regex no es correcto: partidos noony noThat's a no, I'm afraid.
Nahuel Fouilleul
@NahuelFouilleul Corregido.
iBug
para comprobar: tio sin embargo, no podía pegar pruebas porque comentario límite de longitud
Nahuel FOUILLEUL
esto da resultados correctos((~$(grep -Pio "(?!^no,)\b(no(|t|r|ne|body|thing|where)|ne(v|ith)er)\b|.*n't\b"|wc -l)%2))
Nahuel Fouilleul
citas en lugar de $(..)guardar 1 byte
Nahuel Fouilleul
5

Javascript ES6, 89 87 86 caracteres

s=>s.match(/(?!^no,)\bn(o(|t|r|ne|body|thing|where)|e(v|ith)er)\b|n't\b|$/ig).length&1

Prueba:

f=s=>s.match(/(?!^no,)\bn(o(|t|r|ne|body|thing|where)|e(v|ith)er)\b|n't\b|$/ig).length&1

console.log(`Yes.
It's noon.
Hello, World!
Never say never.
Ain't no thang!
No, it's noon now.
Neither me nor you.
I didn't do nothing!
No, I am your father.
A non-alcoholic drink.
I can't get no satisfaction.
All your base are belong to us.`.split`
`.every(f))

console.log(`No.
No, no!
Not today.
Neither am I.
Don't do that!
That's no moon!
And none survived.
No man is an island.
Nosebleeds are no fun.
Nothing compares to you.
That's a no, I'm afraid.
No, I am not your mother.`.split`
`.every(s=>!f(s)))

Qwertiy
fuente
2

Perl 5 , 74 bytes

Código de 73 bytes + 1 para -p.

s/No,//;$_=!(s/(\bn(o(r|t|ne|body|thing|where)?|e(v|ith)er)|n't)\b//gi%2)

Pruébalo en línea!

Dom Hastings
fuente