Dada una cadena de caracteres +=-
donde hay al menos uno =
, inserte enteros positivos entre todos los símbolos y al principio y al final de modo que se satisfagan las ecuaciones matemáticas.
Por ejemplo, dada la entrada
+-=-=
necesita insertar enteros positivos de A a F como este
A+B-C=D-E=F
de modo que las ecuaciones estén todas satisfechas, es decir, A + B - C
y D - E
y F
sean todos el mismo número.
Hay muchas formas posibles de hacer esto, ya que, siempre que las ecuaciones funcionen, se puede usar cualquier conjunto de enteros positivos. Cada línea aquí es una posible salida válida para ingresar +-=-=
:
2+3-4=6-5=1
1+1-1=2-1=1
4+2-4=4-2=2
100+1-10=182-91=91
89+231-77=1024-781=243
Tenga en cuenta que no se requiere que el valor de las expresiones sea un número entero positivo como lo son los números insertados. Por ejemplo, dada la entrada, -=-
las salidas 1-10=8-17
(evals a -9) y 10-1=17-8
(evals a 9) son igualmente válidas. Por supuesto, para algunas entradas, como =
es imposible tener un negativo como expresión, ya que solo 5=5
se pueden insertar números positivos como .
Tenga en cuenta también que cero no es un entero positivo.
El código más corto en bytes gana.
Puede generar los números como una lista en lugar de insertarlos directamente en la cadena. Si saca la cadena, puede haber espacios que separan símbolos y números. Entonces, para entrada +-=-=
, salida
2, 3, 4, 6, 5, 1
o
2 + 3 - 4 = 6 - 5 = 1
es equivalente a la salida
2+3-4=6-5=1
Casos de prueba
Input | One Possible Output
= | 1=1
== | 2=2=2
+= | 1+3=4
=+ | 2=1+1
-= | 30-10=20
=- | 1=2-1
=-= | 3=7-4=3
=+= | 2=1+1=2
=== | 100=100=100=100
+=- | 3+2=7-2
-=+ | 7-2=3+2
+=+ | 3+3=3+3
-=- | 1-10=8-17
--= | 60-1-1=58
++= | 60+1+1=62
-+= | 60-9+1=52
+-= | 60+9-1=68
+-=-= | 2+3-4=6-5=1
--=-- | 2-1-1=2-1-1
==-== | 47=47=50-3=47=47
=++=+-=-+=--= | 3=1+1+1=3+1-1=1-1+3=5-1-1=3
+--++-=-+-+- | 35+10-16-29+20+107-1000=5-4+3-2+1-876
====== | 8=8=8=8=8=8=8
fuente
Respuestas:
Retina , 58 bytes
Pruébalo en línea!
Solución alternativa al mismo número de bytes:
Pruébalo en línea!
Explicación
La idea básica es convertir todas las
+
s y-
s en simples+1
y-1
operaciones y luego a anteponer un número suficientemente grande que hace todo el trabajo ecuaciones. Para que las ecuaciones coincidan, simplemente podemos anteponer el mismo número a cada una de ellas, y luego reducirlo en uno para cada uno+1
y aumentarlo en uno para cada uno-1
después. Como trabajaremos con números unarios, el único problema es que el primer número debe ser lo suficientemente grande como para que podamos reducirlo en 1 veces.Comenzamos insertando un
1
después de cada-
o+
.Esto
\B
asegura que estas coincidencias estén al principio de la entrada, o entre a=
y+
ao-
, es decir, todas las posiciones donde queremos insertar el número inicial de una expresión. La((\+1)|(-1))*
parte a continuación, simplemente cuenta el número de+1
s y-1
s en grupos2
y3
respectivamente. Ahora analicemos la cadena de sustitución:Caída repetida
1_
de la cadena, aplicando la cancelación requerida desde el+1
s.Finalmente, reemplace todas las cadenas de
1
s con sus longitudes para convertir de unario a decimal.fuente
Python 2 , 76 bytes
Pruébalo en línea!
fuente
eqtn_len + plus_signs + minus_signs - 2 * plus_signs = eqtn_len + minus_signs - plus_signs
. Entonces, dado que todos los otros números en el fragmento son unos, el total para el fragmento resultaeqtn_len + minus_signs - plus_signs - minus_signs + plus_signs = eqtn_len
. La longitud de la ecuación debe ser positiva, por lo que todo funciona.Python 2,
199179178172162158156152151 bytesDemasiado tiempo, pero la solución fue fácil de crear.
Pruébalo en línea
Esto intentará todas las posibilidades hasta que encuentre una solución. El programa es extremadamente lento. También realiza el reemplazo de la cadena cada iteración. La edición "172" lo hizo drásticamente más lento, ya que en lugar de comenzar con un rango pequeño, comienza al máximo. Por ejemplo, las entradas
-=
o=+
tienen que intentar 2 ** 32 intentos antes de llegar a una solución.Para acelerar el programa, use la versión con 178 bytes del historial de edición.
fuente
range
En python2 no se crea todo el rango como una lista de inmediato? IIRC puede acelerarlo usando en suxrange
lugar, ya que creo que esa es la versión de carga diferida (Python3 usa lazy como valor predeterminadorange
)print range(1,65537)
y se completó en 0.034 s.l=...
, pero colocando eso en elproduct(range(...),repeat=len(s)+1)
. Si necesita paréntesis, solo guarda un byte (\ n)len(s)+1
, podría usar-~len(s)
en su lugar, lo que no requeriría parens.JavaScript (ES6),
9282 bytesGolfó 8 bytes con un truco de @xnor
El truco aquí es insertar un
1
después de cada+
o-
, luego anteponer a cada expresión el número que hace que la expresión sea igual a la longitud de la entrada. De esta manera podemos garantizar que el número sea siempre positivo; Como siempre hay al menos 1=
en la cadena, el número de+
s nunca puede alcanzar la longitud de la cadena, por lo que el resto siempre es al menos1
. Puede verificar esto escribiendo un número arbitrario de+
s en el fragmento de arriba.fuente
Python 2 ,
120119 bytes-1 byte gracias a mbomb007
Pruébalo en línea! o Verificar todos los casos de prueba
Primero inserto
1
en cada posición, para verificar el valor más alto, luego lo agrego como desplazamiento en cada ecuación. Esto funciona porque no puede agregar números negativos, por lo que el resultado mínimo viene dado por la cantidad de+
ecuaciones que solo tiene+
.fuente
GNU Prolog, 156 bytes
Explicación
Tenemos un montón de ecuaciones para resolver, entonces, ¿por qué no usar un solucionador de ecuaciones real?
x
es básicamente un evaluador de ecuaciones para ecuaciones de la forma+-+
; Además de la ecuación en sí, tiene dos argumentos adicionales (una lista de diferenciasL,R
que contiene los valores de la ecuación y un valorV
que la ecuación evalúa). Como es habitual en Prolog, se puede usar de cualquier manera (por ejemplo, puede especificarV
y obtener unL,R
, especificarL,R
y obtener unV
, especificar ambos y verificar que el valor sea correcto, o no especificar ninguno, en cuyo caso se impondrán restricciones apropiadas en ambosV
yL,R
) SeL,R
nombra el "elemento actual" deE
, y también incluimos una afirmación de queE
es mayor que 0 (porque la pregunta requiere el uso de números positivos). Esta función es un poco más detallada de lo que me gustaría, por ejemplo, tuve que escribir el[E|R]
patrón de coincidencia / no coincidencia dos veces, debido al hecho de que las listas son asociativas a la derecha pero la suma y la resta son asociativas a la izquierda. Lamentablemente, necesitamos usar una lista real, en lugar de inventar nuestro propio tipo de lista asociativa izquierda fuera de las celdas de cons, parafd_labeling
trabajar.q
es similar ax
, pero también incluye=
. Básicamente solo llamax
, y se recursivamente. Por cierto, es una demostración muy clara de cómo funcionan las listas de diferencias, mostrando que puede concatenar dos listas de diferenciasL,T
yT,R
formar una sola lista de diferenciasL,R
. La idea básica es que una lista de diferencias es una función parcial que toma un argumentoR
y devuelve un valorL
que estáR
antepuesto a la lista misma. Por lo tanto, al identificar el argumento de una lista de diferencias y el valor de retorno de otra, podemos componer las funciones y así concatenar las listas.Finalmente,
s
que es la función que realmente resuelve la tarea en la pregunta, es una función envolvente que llamaq
con argumentos. Convertimos la lista de diferencias en una lista regular al proporcionarla[]
como argumento, y la usamosfd_labeling
para encontrar una solución a la ecuación que construimos. (De forma predeterminada, parece que le gusta establecer valores en 1 si no hay razón para establecerlos en otra cosa. Sin embargo, se puede configurar;value_method(random)
ofrece soluciones más "interesantes" que poner 1s en todas partes, por ejemplo, y sigue siendo muy rápido. )Salida de muestra
Con el programa como está escrito:
Si hago que el programa sea un poco más largo para agregar un
value_method(random)
, el resultado varía, pero se ve más o menos así:En ambos casos,
?
al final de la salida significa que puede haber más de una solución. (Por supuesto, en este caso, sabemos que hay un montón más de una solución!)fuente
Mathematica, 116 bytes
Función pura que toma una cadena como entrada y devuelve una lista de enteros positivos. Estrategia básica: solo sumamos 1 y restamos 1, y elegimos los números iniciales en cada expresión para que todo sea igual.
c=Characters@StringSplit[#,"="]/."+"->-1/."-"->1
dividiría la cadena de entrada en cada signo igual, luego reemplazaría cada+
por-1
y cada-
por1
. Sin embargo, si hay un signo igual al principio o al final, entonces sería ignorado. Por lo tanto, agregamos artificialmente un nuevo carácter en cada extremo ("0"<>#<>"0"
) y lo hacemos desaparecer después de que se complete la división de cadenas (/."0"->Nothing
).El total de cada sublista ahora es igual a un número entero que podemos poner delante de
+
sy-
s para que cada expresión sea igual.1-Min[Tr/@c]
es el número entero más pequeño que podemos agregar a cada total para que todos sean positivos. EntoncesPrepend[#^2,1-Min[Tr/@c]+Tr@#]&
toma cada sublista (^2
convierte todas sus entradas1
) y antepone su total desplazado por este entero compensador más pequeño. Las listas resultantes seJoin
editan juntas para producir la salida.fuente
Ruby, 76
¡El valor objetivo para las expresiones se fija en
5**8
menos 1 por razones de golf! Originalmente estaba usandos.size+1
menos 1.Sin golf en el programa de prueba
Salida
fuente
PHP,
207204197114 bytesenfoque directo: mucho más corto y rápido
Ejecutar
echo '<input>' | php -nR '<code>'
o probarlo en línea .Descompostura
!$c
es verdadero en la primera iteración, convertida en1
para indexación de cadenas;"="[1]
esta vacio.Después de eso,
$c
se establece y es!$c
falso, se lanza0
y"="[0]
es el primer personaje.así que definitivamente estamos seguros con la longitud de la entrada. Todos los términos se evaluarán a eso.
chunk_split($s,$n,$i)
inserta$i
después de cada$n
carácter de$s
- y al final.Para evitar que los términos vacíos se conviertan en
1
, se forza un error al establecer la longitud del fragmento en0
.fuente
Röda ,
112110109 bytesPruébalo en línea!
La función de división no funcionó como pretendía con este programa. Por ejemplo,
split("", sep="")
devuelve una cadena vacía en lugar de nada. ¿Cómo es eso lógico? Debido a esto, el programa es casi 20 bytes más grande de lo que podría ser si la semántica dividida fuera ideal.La idea de esta respuesta es que sabemos que la longitud de la cadena de entrada debe ser mayor o igual al valor de la ecuación, por lo que definimos el valor de la ecuación como la longitud de la cadena. Para cada parte de la ecuación, creemos que cada operador es
+1
o-1
y resta y suma al valor de la ecuación.Sin golf:
fuente