Accesorios después del hecho!

10

Este desafío está inspirado en las matemáticas es un hecho. La programación no lo es .


La notación matemática para un factorial o un hecho es un signo de exclamación !. El signo de exclamación también es un símbolo común noten muchos lenguajes de programación.

Desafío:

Tome una cadena que contenga números y los caracteres: + !como entrada y salida de lo siguiente:

Todo delante de un signo de exclamación debe evaluarse como una expresión matemática, así 2+2sería 4.

Todo después de un solo signo de exclamación debe agregarse como accesorios a lo que esté frente a él, por lo tanto: 2+2!5debe dar 45, porque 2+2=4, y 5es un accesorio. 2+2!5+5debería dar 410.

Como !también significa not, cualquier cosa que no sea un accesorio después del hecho no debe agregarse. Por lo tanto, 2+2!!5debe dar 4, ya 5que no es un accesorio. Ahora, not(not(true))==trueasí que 2+2!!!5debería dar 45. 2+2!!5!5+5debería dar:, 410porque 2+2=4, seguido de un factorial y !5!5+5. El primero 5no es un hecho, sino que 5+5está después de otro signo de exclamación y, por lo tanto, es un hecho, una vez más.

Aclaraciones:

  • Los signos de exclamación no serán adyacentes a a +en ninguno de los lados.
  • No habrá +números principales (es 5, no +5).
  • Opcionalmente, puede incluir un cero a la izquierda si ese es el resultado de la expresión frente a la primera !. Ambos 4y 04son salida aceptada para entrada:0+0!4

Resumen ejecutivo: evalúe cada suma (tratando !como separadores). Luego descarte todos los números que aparecen después de un número par de !(contando desde el comienzo de la cadena). Luego elimine todo !.

Casos de prueba:

!
   <- Empty string

5
5

12!
12

!87
87

!!5
   <- Empty string

5+5!2+2
104

5+5!!2+2
10

1!2!3!4!5!6!7!8!9
12468

10+10!!2+2!!3+3!4+4
208

2!!3!5
25

2!!3!5!7
25

10!!!!!!!5
105

Este es el por lo que gana el código más corto en bytes (en cada idioma). ¡Las explicaciones son altamente recomendadas!

Stewie Griffin
fuente
umm ... digamos que tenemos 2 !! 3! 5 aquí es o no 5 un accesorio de 3?
officialaimm
3
@officialaimm Es 25(ver caso de prueba agregado). Más importante 2!!3!5!7aún 25, daría , porque hay un número par a la !izquierda de la 7(por lo que no solo cuenta la carrera justo en frente del número, sino toda la !izquierda).
Martin Ender
¿Puede la salida ser un Mathematica Row?
ngenisis
Um ... ¿entonces este desafío no tiene nada que ver con los factoriales?
DLosc

Respuestas:

5

Retina , 35 31 29 bytes

Ahorró 4 bytes al inspirarse en ETHproductions .

Gracias a Leo por guardar otros 2 bytes.

\d+|\+
$*
1+
$.&
1`!

!\d*!?

Pruébalo en línea!

Martin Ender
fuente
Puede guardar algunos bytes en las últimas líneas como esta
Leo
1
@Leo Eso es genial, gracias. :)
Martin Ender
5

JavaScript (ES6), 58 56 bytes

Ahorró dos bytes gracias a Martin Ender .

let f =
x=>x.replace(/[^!]+/g,eval).replace(/!(\d*)!?\d*/g,"$1")
<input value="2+2!5+5" oninput="try{O.value=f(value)}catch(e){}"><br>
<input id=O value="410" disabled>

Podría mejorarse de alguna manera ...

ETHproductions
fuente
Buen uso del argumento de función para replace.
Neil
@Neil Gracias, pero encontré una mejor manera :-)
ETHproductions
Su fragmento de código me está dando la respuesta incorrecta 1+1!5. Creo que te olvidaste evalun poco antes del !.
Value Ink
@ValueInk Ah, caramba, no creo que haya una manera fácil de arreglar eso.
ETHproductions
2

Jalea , 16 bytes

ṣ”!µḢW;m2$VṾ$L¡€

Pruébalo en línea!

Explicación

La observación clave aquí es que podemos ejecutar los pasos "fuera de orden"; en lugar de evaluar las sumas y luego ignorar las que no nos gustan, podemos ignorar las sumas en posiciones no válidas y luego evaluar el resto.

ṣ”!µḢW;m2$VṾ$L¡€
ṣ”!                Split input on '!'
   µ               Set as the new default for missing arguments
    Ḣ              Take the first element, removing it from the default
     W;  $         Cons with
       m2            every odd-numbered element of {the tail of the !-split input}
               €   For each remaining element
          VṾ$      Evaluate and de-evaluate it
             L¡      a number of times equal to its length

La evaluación de una suma igual que "10+10"la evaluará a un número, por ejemplo 20, después de-evaluar en una cadena, "20". Repetir ese proceso no tiene ningún efecto adicional (es idempotente). Por lo tanto, evaluamos efectivamente cada elemento de la cadena, excepto la cadena nula, que permanece sin evaluar porque tiene una longitud cero.


fuente
Ese es un gran truco para evaluar condicionalmente cada elemento. ¿Podría de alguna manera tomar el AND lógico de cada elemento y su valor eval-deval'd? (Asumo que la cadena vacía es falsa en Jelly)
ETHproductions
@ETHproductions: la tacidez de Jelly hace improbable que eso ahorre bytes; prefiere evitar usar el mismo valor dos veces si es posible, y si desea reutilizar un valor, normalmente debe poner al menos un extra µen algún lugar (y µno funciona dentro de un bucle, lo que significa que necesitaría algo aún más detallado). Me las arreglé para hacer que funcione, tal como ṣ”!µḢW;m2$ȧVṾ$$€, pero no es más corto (y tiene la característica de la pila de signos de dólar que tiende a ocurrir cuando se presiona la jalea hasta el borde de su capacidad para estructuras de control nido.)
2

Jalea , 18 bytes

ṣ”!µḊm2;@ḢW$LÐfVṾ€

Pruébalo en línea!

¿Cómo?

ṣ”!µḊm2;@ḢW$LÐfVṾ€ - Main link: string
ṣ”!                - split on '!' characters
   µ               - monadic chain separation (call that x)      e.g. ['1+1','0+0','0+0','0+0','','1+0','','','']
    Ḋ              - dequeue x (all but the leftmost entry of x) e.g.       ['0+0','0+0','0+0','','1+0','','','']
     m2            - modulo 2 index into that result             e.g.       ['0+0',      '0+0',   '1+0',   '']
           $       - last two links as a monad
         Ḣ         -     head x (the leftmost entry of x)        e.g.  '1+1'
          W        -     wrap                                    e.g. ['1+1']
       ;@          - concatenate with reversed arguments         e.g. ['1+1','0+0',      '0+0',   '1+0',   '']
             Ðf    - filter keep:
            L      -     length (keep that have non-zero length) e.g. ['1+1','0+0',      '0+0',   '1+0']
               V   - eval as jelly code (vectorises)             e.g. [  2,    0,          0,       1]
                      Yes, addition is just + and decimal numbers are just strings of digits in Jelly believe it or not!
                Ṿ€ - uneval €ach (creates a string from each one)e.g. [ '2',  '0',        '0'     ,'1']
                      without the € it would uneval the list and hence yield commas too)
                   - implicit print (prints the resulting list [of characters and possibly
                      lists of characters] as if it were all one string.)
Jonathan Allan
fuente
No creo que esto funcione para literal 0+0en el medio de la entrada (en un lugar donde no se descarta); produce la cadena nula, aunque debería producir un dígito 0.
Ah, cierto, tendré que pasar a una solución más larga :(
Jonathan Allan
Debe arreglarse (posiblemente golfable ahora).
Jonathan Allan
1

Ruby , 58 56 + 1 = 59 57 bytes

Usa la -pbandera. -2 bytes de Tutleman .

i=0;$_=' '+$_;gsub(/!?([^!]*)/){eval$1if(2>i+=1)||i%2<1}

Pruébalo en línea! (Se agregó una línea de código adicional para que tome todas las líneas de entrada e imprima la salida en diferentes líneas).

Tinta de valor
fuente
Creo que puedes dejar los paréntesis eval$1, ¿no?
Tutleman
@Tutleman eh. No sé qué problema estaba teniendo que me hizo agregar los padres (no estaban presentes cuando comencé a escribir el programa), pero parece que realmente puedo abandonarlos.
Value Ink
0

Lote, 192 184 bytes

@echo off
set/ps=
call:c . "%s:!=" "%"
echo(%s%
exit/b
:c
set s=
if not %2=="" set/as=%2
:l
shift
shift
if "%1"=="" exit/b
if %1=="" goto l
set/at=%1
set s=%s%%t%
goto l

Tener que manejar las cadenas vacías es inconveniente.

Neil
fuente
0

Pip , 18 bytes

Creo que esto es lo más corto posible ... aunque dije eso hace unas tres iteraciones también.

{VaX++v%2+!v}Ma^'!

Toma entrada como argumento de línea de comando. Pruébalo en línea!

Explicación

                    a is 1st cmdline arg; global variable v is -1 (implicit)
              a^'!  Split a on !
{           }M      Map this function to the resulting list (note that inside function,
                    a is the function arg):
    ++v              Increment v (so that v tracks the 0-based index of the current
                     element)
       %2            We want to keep the elements where v%2 is 1...
         +!v         ... and also v=0, where v%2 is 0, but adding !v makes it 1
  aX                 String-multiply the argument by the above quantity (turning elements
                     we don't want into empty string)
 V                   Eval it (eval'ing empty string gives nil, but that's okay because
                     nil doesn't output anything)
                    Autoprint the resulting list, concatenated together (implicit)
DLosc
fuente
0

R, 95 bytes

function(x)for(e in strsplit(gsub('!([^!]*)![^!]*','\\1!',x),'!')[[1]])cat(eval(parse(text=e)))

Probablemente haya margen de mejora, pero por el momento es lo mejor que se me ocurre.

Robert Hacken
fuente