Números faltantes en suma aritmética


14

Desafío

Dando una suma aritmética válida con algunos números faltantes, genera la expresión completa.

Ejemplo:

    1#3                 123
+   45#     =>     +    456
--------            --------
    579                 579

Entrada

  • El formato de expresión puede ser una matriz ["1#3", "45#", "579"], una cadena "1#3+45#=579"o 3 entradasf("1#3","45#","579")

Salida

  • Igual que la entrada
  • No necesita dar salida al resultado

Notas

  • Los números que faltan se representarán utilizando #o cualquier otro carácter no numérico constante que desee
  • Suponga que el resultado no tendrá un número faltante
  • Suponga que la entrada / salida consta de 2 términos y un resultado final
  • Suponga que ambos términos> 0 y resultado> = 2
  • Puede haber múltiples soluciones. Puede enviar a cualquiera siempre que el resultado de la suma coincida

Casos de prueba con posibles salidas (formato bonito)

    #79                     879
+   44#         =>      +   444
--------                --------
    1323                   1323

    5#5                     555
+   3#3         =>      +   343
--------                --------
    898                     898

      #                       1
+     #         =>      +     1
--------                --------
      2                       2

    ###                     998
+   ###         =>      +     1     PD: there are a lot of possible outputs for this one
--------                --------
    999                     999


    123                     123
+     #         =>      +     1
--------                --------
    124                     124


      9                       9
+    #6         =>      +    46
--------                --------
     55                      55


    #123651                     1123651
+      #98#         =>      +      7981
------------                -----------
    1131632                     1131632

Aplican reglas estándar de


¿Necesitamos eliminar los ceros a la izquierda?

@Mnemonic no necesariamente
Luis felipe De jesus Munoz

¿Puedo tomar la entrada con los lados =intercambiados? por ejemplo579=1#3+45#
dzaima

2
"Asumir ambos términos> 0" ¿"asume" significa que tengo que generar ambos términos> 0 o que puedo suponer que siempre hay una solución con ambos> 0 pero generar lo que sea?
dzaima

1
también su caso de prueba adicional evita exactamente lo que estaba pidiendo - los ceros a la izquierda
dzaima

Respuestas:


9

Brachylog , 22 16 bytes

{Ṣ∧Ị∋|}ᵐ²ịᵐ.k+~t

Pruébalo en línea!

-6 bytes gracias a @Fatelize

Explicación

{Ṣ∧Ị∋|}ᵐ²ịᵐ.k+~t
{     }ᵐ²                   #   for each letter in each string
 Ṣ∧Ị∋                       #       if " " return a digit; else input
     |                      #
         ịᵐ                 #   cast each string to number
            k+              #   the sum of all but the last one
              ~t            #       is equal to the last one
           .                #   output that list

1
{"#"∧Ị∋|}ᵐ²ịᵐ.k+~tes 4 bytes más corto. No estoy seguro de por qué hiciste algo tan complicado en tu mapa.
Fatalize

Dado que podemos usar cualquier carácter no numérico, debe usar, por ejemplo, un espacio en lugar del "#"cual ahorrará dos bytes más.
Fatalize el

8

JavaScript (ES6), 74 57 bytes

Toma la entrada como (a)(b)(result), donde a y b son cadenas con .dígitos desconocidos y el resultado es un entero. Devuelve una matriz de 2 enteros.

a=>b=>F=(c,n)=>`${r=[c,n]}`.match(`^`+[a,b])?r:F(c-1,-~n)

Pruébalo en línea!

Comentado

a => b =>                // a, b = term patterns (e.g. a = ".79", b = "44.")
  F = (c,                // c = expected result (e.g. 1323)
          n) =>          // n = guessed value of b, initially undefined
    `${r = [c, n]}`      // we coerce r = [c, n] to a string (e.g. "879,444")
                         // if n is still undefined, this gives just c followed by a comma
    .match(`^` + [a, b]) // we coerce [a, b] to a string, prefixed with "^" (e.g. "^.79,44.")
    ?                    // this is implicitly turned into a regular expression; if matching:
      r                  //   return r
    :                    // else:
      F(c - 1, -~n)      //   decrement c, increment n and do a recursive call

Ah, eso es lo que está pasando. Intenté entender tu código sin explicación ayer (y soy malo en JS), pero no entendí por qué -~nno podía ser justo n+1y cómo F=(c,n)=>se usaba. Ahora que agregó una explicación, todo tiene sentido. ces la tercera entrada, nno está definida (y se ~undefinedvuelve -1diferente undefined+1). Todo está claro ahora (y desafortunadamente no es algo que pueda portar a Java, que fue principalmente por lo que intenté entenderlo xD). PD: Ya voté ayer, así que voté por una de sus otras respuestas (que ya no voté, no hay muchas disponibles ...); p
Kevin Cruijssen

@KevinCruijssen FWIW, escribí un consejo sobre esto hace algunas veces. Pero sí ... eso es algo de JS y probablemente no sea portátil a muchos otros idiomas.
Arnauld

Bueno, podría ser capaz de semi-portarlo, pero simplemente creando un segundo método recursivo y usando un ternario if para verificarlo null, convirtiéndolo manualmente -1. Sin embargo, Java tiene un límite recursivo (muy) limitado de StackOverflow, por lo que usar un método recursivo con aleatoriedad con la esperanza de que termine correctamente dentro de aproximadamente 1024 llamadas recursivas no funcionará de todos modos en Java. Ah bueno. He votado tu propina. ¡Ten un buen fin de semana! :)
Kevin Cruijssen

@KevinCruijssen Mi primer intento de JS fue hacer exactamente eso: probar valores aleatorios con una función recursiva. Y usualmente estaba haciendo significativamente menos iteraciones que la que usaba un contador. Dato curioso: incluso ###+###=999, sus probabilidades son de 1 en 1000. Por lo tanto, con 1024 iteraciones, debería tener éxito un poco más de lo que falla. :)
Arnauld

7

Matlab, 143 134 132 119 115 bytes

function[m]=f(x,y,r),p=@(v)str2num(strrep(v,'#',char(randi([48,57]))));m=[1,1];while sum(m)-r,m=[p(x),p(y)];end;end

-4 bytes gracias a @Luismendo

Pruébalo en línea


Bastante grande y bastante estúpido. Simplemente reemplaza todo #con dígitos aleatorios hasta que encuentra los correctos.


5

R , 67 51 bytes

Rock simple y escalas horriblemente, simplemente grep todas las combinaciones de suma. Utilizar "." para dígitos desconocidos. No encontrará la misma respuesta que el caso de prueba número 4, pero dará una posible respuesta, que sigue la letra de las reglas tal como se indica.

-16 bytes mediante grepping después de formar la salida y reemplazar pastecon el ?operador.

function(x,y,z,`?`=paste)grep(x?y,1:z?z:1-1,v=T)[1]

Pruébalo en línea!


1
Impresionante idea, nunca hubiera pensado en eso. Puede guardar algunos bytes usando * en lugar de grepl: tio.run/##PYzLCoMwEEX3/…
JayCe

1
Estaba buscando varios operadores y se te ocurrió ?... Creo que esta es la primera vez. Por cierto, olvidé si ya te lo dije, pero estamos tratando de que R sea nominado para el idioma de septiembre del mes . Puedes votar si aún no lo has hecho.
JayCe

Podría haber elegido cualquier cosa con baja prioridad. Siente que debería haber una mejor manera de obtener el partido ...
J.Doe

3

Carbón , 32 bytes

F²⊞υ0W⁻ζΣIυ≔E⟦θη⟧⭆κ⎇⁼μ#‽χμυ←Eυ⮌ι

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

F²⊞υ0

Empuje dos cadenas 0a la lista vacía predefinida upara que el ciclo while continúe.

W⁻ζΣIυ

Repita mientras la suma de convertir los valores en uentero no es igual al resultado deseado.

≔E⟦θη⟧

Crea una matriz de las dos entradas y mapea sobre ella.

⭆κ⎇⁼μ#‽χμυ

Reemplace cada uno #con un dígito aleatorio y asigne el resultado nuevamente u.

←Eυ⮌ι

Imprime el resultado justificado a la derecha. (La izquierda justificada sería solo υpara un ahorro de 4 bytes).



3

05AB1E (heredado), 23 20 bytes

[²³«εð9ÝΩ:}²gôJDO¹Q#

-3 bytes gracias a @Emigna .

Los dígitos desconocidos son espacios ( ). El orden de entrada debe ser: resultado esperado; cuerda más larga; cuerda más corta

Pruébalo en línea .

Explicación:

[                 # Start an infinite loop
 ²³«              #  Take the second and third inputs, and merge them together
               #   i.e. " 79" and " 4 " → " 79 4 "
    ε     }    #  Map each character to:
     ð   :     #   Replace a space with:
      9ÝΩ      #   A random digit in the range [0,9]
               #    i.e. " 79 4 " → ['3','7','9','2','4','3']
               #    i.e. " 79 4 " → ['5','7','9','7','4','4']
²g             #  Get the length of the second input
               #   i.e. " 79" → 3
  ô            #  And split it into two numbers again
               #   i.e. ['3','7','9','2','4','3'] and 3 → [['3','7','9'],['2','4','3']]
               #   i.e. ['5','7','9','7','4','4'] and 3 → [['5','7','9'],['7','4','4']]
   J           #  Join each list together to a single number
               #   i.e. [['3','7','9'],['2','4','3']] → [379,243]
               #   i.e. [['5','7','9'],['7','4','4']] → [579,744]
    D          #  Duplicate this list
     O         #  Sum the list
               #   i.e. [379,243] → 622
               #   i.e. [579,744] → 1323
      ¹Q#      #  If it's equal to the first input: stop the infinite loop
               #  (and output the duplicate list implicitly)
               #   i.e. 1323 and 622 → 0 (falsey) → continue the loop
               #   i.e. 1323 and 1323 → 1 (truthy) → stop the loop and output [579,744]

1
Reemplazar ahorra 3 sobre el if.
Emigna

@Emigna Ah, por supuesto. ¡Gracias!
Kevin Cruijssen

3

Perl 6 , 81 74 bytes

-7 bytes gracias a nwellnhof!

{first {try S/\=/==/.EVAL},map {$^a;S:g[\#]=$a[$++]},[X] ^10 xx.comb('#')}

Pruébalo en línea!

Bloque de código anónimo que toma la entrada como una cadena que contiene una expresión aritmética, por ejemplo, "12 # + 45 # = 579". Sustituye cada uno #con posibles permutaciones de dígitos, sustituye el =con== y encuentra el primer resultado válido.

Explicación:

{  # Anonymous code block                                                      }
 first   # Find the first of:
                                                               ^10  # The range of 0 to 9
                                                                   xx.comb('#') # Multiplied by the number #s in the code
                                                          ,[X]  # The cross-product of these lists
                          map   # Map each crossproduct to:
                              {$^a;.trans: "#"=>{$a[$++]}}  # The given string with each # translated to each element in the list
      {try S/\=/==/.EVAL}, # Find which of these is true when = are changed to == and it is eval'd

Se puede utilizar S:g[\#]=$a[$++]en lugar de transa 74 bytes .
nwellnhof

@nwellnhof ¡No me di cuenta de que podrías usar S///ese tipo de sintaxis! ¡Gracias!
Jo King


2

Java 10, 203 198 193 bytes

(a,b,c)->{int A=0,B=0,l=a.length();for(a+=b,b="";A+B!=c;A=c.valueOf(b.substring(0,l)),B=c.valueOf(b.substring(l)),b="")for(var t:a.getBytes())b+=t<36?(t*=Math.random())%10:t-48;return A+"+"+B;}

Pruébalo en línea.

Explicación:

(a,b,c)->{           // Method with 2 Strings & integer parameters and String return-type
  int A=0,B=0,       //  Result-integers, starting both at 0
      l=a.length();  //  Length of the first String-input
  for(a+=b,          //  Concat the second String-input to the first
      b="";          //  Reuse `b`, and start it as an empty String
      A+B!=c         //  Loop as long as `A+B` isn't equal to the integer-input
      ;              //    After every iteration:
       A=c.valueOf(b.substring(0,l)),
                     //     Set `A` to the first String-part as integer
       B=c.valueOf(n.substring(l)),
                     //     Set `B` to the second String-part as integer
       b="")         //     Reset `b` to an empty String
    for(var t:a.getBytes())
                     //   Inner loop over the characters of the concatted String inputs
      b+=t<36?       //    If the current character is a '#':
          (t*=Math.random())%10
                     //     Append a random digit to `b`
         :           //    Else (it already is a digit):
          t-48;      //     Append this digit to `b`
  return A+"+"+B;}   //  After the loop, return `A` and `B` as result

2

C (gcc) , 228 213 203 172 170 bytes

-15 Bytes gracias a @ceilingcat . Nunca he usado indexantes.

-10 Bytes gracias a @Logem . Magia de preprocesador

llamada refactorizada exit(0)con pone como parámetro.

char*c,*p[9],k;main(i,v)int**v;{for(i=X[1],35))||X[2],35))?p[k++]=c,main(*c=57,v):k;!c*i--;)47==--*p[i]?*p[i]=57:Y[1])+Y[2])^Y[3])?main(i,v):exit(puts(v[2],puts(v[1])));}

Pruébalo en línea!



Puede guardar dos bytes reemplazando la macro -DX=c=index(v, con el -DX=(c=index(venlace TIO en mi último comentario.
Logern

Gracias chicos. No parece que haya intentado jugar golf antes ...
cleblanc

1

C # .NET, 225 220 196 bytes

(a,b,c)=>{int A=0,B=0,l=a.Length;for(a+=b,b="";A+B!=c;A=int.Parse(b.Substring(0,l)),B=int.Parse(b.Substring(l)),b="")foreach(var t in a)b+=(t<36?new System.Random().Next(10):t-48)+"";return(A,B);}

Puerto de mi respuesta Java 10 .
(Estoy muy oxidado en el golf C # .NET, por lo que definitivamente puedo jugar al golf ...)

-3 bytes implícitamente gracias a @ user82593 y este nuevo consejo de C # que agregó .
-29 bytes gracias a @hvd .

Pruébalo en línea.

Explicación:

(a,b,c)=>{        // Method with 2 string & int parameters and int-tuple return-type
  int A=0,B=0,    //  Result-integers, starting both at 0
      l=a.Length; //  Length of the first string-input
  for(a+=b,       //  Concat the second string-input to the first
      b="";       //  Reuse `b`, and start it as an empty string
      A+B!=c      //  Loop as long as `A+B` isn't equal to the integer-input
      ;           //    After every iteration:
       A=int.Parse(b.Substring(0,l)),
                  //     Set `A` to the first string-part as integer
       B=int.Parse(b.Substring(l)),
                  //     Set `B` to the second string-part as integer
       b="")      //     Reset `b` to an empty string
    foreach(var t in a)
                  //   Inner loop over the characters of the concatted string inputs
      b+=(t<36?   //    If the current character is a '#':
           new System.Random().Next(10)
                  //     Use a random digit
          :       //    Else (it already is a digit):
           t-48)  //     Use this digit as is
         +"";     //    And convert it to a string so it can be appended to the string
  return(A,B);}   //  After the loop, return `A` and `B` in a tuple as result

Puede usar el regular using System;en su lugar, es más corto que namespace System{}.
hvd

@hvd ¡Eso fue todo! ... No he hecho C # en años, jaja ... Intenté de manera using System.*;similar a las importaciones en Java, pero eso no funcionó. Olvidé que tenía que quitar la .*parte. Gracias por los 5 bytes.
Kevin Cruijssen

1
Releerlo ahora, en realidad fue una sugerencia subóptima. Puede escribir int.Parse(-4), usar new System.Random()(+7) y soltar using System;(-13) para guardar otros 10 bytes. :) Además, no es necesario .ToCharArray(), eso quita 14 bytes más.
hvd

@hvd ¡Gracias! No estoy seguro de cómo me olvidé de int.Parsevs System.Int32.Parse... Es básicamente lo mismo que System.Stringy string... Y no sabía que era posible recorrer los personajes sin el .ToCharArray(). Gracias por otros -24 bytes. : D
Kevin Cruijssen

1

Python 3 , 121 155 152 149 bytes

import re
def f(i,k=0,S=re.sub):s=S('#','%s',i)%(*list('%0*d'%(i.count('#'),k)),);print(s)if eval(S('=','==',S('\\b0*([1-9])','\\1',s)))else f(i,k+1)

Pruébalo en línea!

+34 Nueva solución con expresiones regulares para eludir el hecho de que Python no admite números con ceros a la izquierda.

-3 gracias a @Jonathan Frech


La solución anterior no funciona si # es el primer carácter de cualquier número (porque eval no acepta ceros iniciales) y, por lo tanto, no es válido :(

def f(i,k=0):
 s=i.replace('#','%s')%(*list('%0*d'%(i.count('#'),k)),)
 print(s)if eval(s.replace('=','=='))else f(i,k+1)

Pruébalo en línea!


1
Me temo que esta presentación no es válida por el motivo indicado en la publicación.
Erik the Outgolfer

2
Como su función no contiene ninguna declaración compuesta, puede condensarla en una sola línea.
Jonathan Frech

0

PHP, 112 bytes

solución de fuerza bruta poco convincente

for(;$s=$argn;eval(strtr($s,['='=>'==','#'=>0]).'&&die($s);'))for($k=$n++;$k;$k=$k/10|0)$s[strpos($s,35)]=$k%10;

toma una cadena como entrada, se detiene en la primera solución. Ejecutar como tubería -nRo probarlo en línea .


0

Powershell, 91 bytes

El script encuentra todas las soluciones. El número total de iteraciones es 10 potencia el número de caracteres #. La profundidad de recursión es igual al número de caracteres #.

filter f{$h,$t=$_-split'#',2
if($t){0..9|%{"$h$_$t"}|f}elseif($h-replace'=','-eq'|iex){$h}}

Script de prueba:

filter f{$h,$t=$_-split'#',2
if($t){0..9|%{"$h$_$t"}|f}elseif($h-replace'=','-eq'|iex){$h}}

@(
    ,('1#3+45#=579','123+456=579')
    ,('#79+44#=1323','879+444=1323')
    ,('5#5+3#3=898','505+393=898 515+383=898 525+373=898 535+363=898 545+353=898 555+343=898 565+333=898 575+323=898 585+313=898 595+303=898')
    ,('#+#=2','0+2=2 1+1=2 2+0=2')
    ,('9+#6=55','9+46=55')
    ,('123+##=124','123+01=124')
    ,('#123651+#98#=1131632','1123651+7981=1131632')
    ,('##+##=2','00+02=2 01+01=2 02+00=2')
    ,('##+##=99','00+99=99 01+98=99 02+97=99 03+96=99 04+95=99 05+94=99 06+93=99 07+92=99 08+91=99 09+90=99 10+89=99 11+88=99 12+87=99 13+86=99 14+85=99 15+84=99 16+83=99 17+82=99 18+81=99 19+80=99 20+79=99 21+78=99 22+77=99 23+76=99 24+75=99 25+74=99 26+73=99 27+72=99 28+71=99 29+70=99 30+69=99 31+68=99 32+67=99 33+66=99 34+65=99 35+64=99 36+63=99 37+62=99 38+61=99 39+60=99 40+59=99 41+58=99 42+57=99 43+56=99 44+55=99 45+54=99 46+53=99 47+52=99 48+51=99 49+50=99 50+49=99 51+48=99 52+47=99 53+46=99 54+45=99 55+44=99 56+43=99 57+42=99 58+41=99 59+40=99 60+39=99 61+38=99 62+37=99 63+36=99 64+35=99 65+34=99 66+33=99 67+32=99 68+31=99 69+30=99 70+29=99 71+28=99 72+27=99 73+26=99 74+25=99 75+24=99 76+23=99 77+22=99 78+21=99 79+20=99 80+19=99 81+18=99 82+17=99 83+16=99 84+15=99 85+14=99 86+13=99 87+12=99 88+11=99 89+10=99 90+09=99 91+08=99 92+07=99 93+06=99 94+05=99 95+04=99 96+03=99 97+02=99 98+01=99 99+00=99')
) | % {
    $s,$e = $_
    $r = $s|f
    "$($e-eq$r): $r"
}

Powershell, 'Asume que ambos términos> 0' es obligatorio, 110 bytes

filter f{$h,$t=$_-split'#',2
if($t){0..9|%{"$h$_$t"}|f}else{$a,$b,$c=$_-split'\D'
$_|?{+$a*+$b*!(+$a+$b-$c)}}}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.