Números ausentes na soma aritmética

14

Desafio

Dando uma soma aritmética válida com alguns números ausentes, produza a expressão completa.

Exemplo:

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

Entrada

  • O formato da expressão pode ser uma matriz ["1#3", "45#", "579"], uma sequência "1#3+45#=579"ou 3 entradasf("1#3","45#","579")

Resultado

  • Igual à entrada
  • Você não precisa produzir o resultado

Notas

  • Os números ausentes serão representados usando #ou qualquer outro caractere não numérico constante desejado
  • Suponha que o resultado não terá um número ausente
  • Suponha que Entrada / Saída consistem em 2 termos e um resultado final
  • Suponha que ambos os termos> 0 e resultado> = 2
  • Pode haver várias soluções. Você pode produzir qualquer pessoa desde que a soma corresponda ao resultado

Casos de teste com possíveis saídas (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

Padrão regras se aplicam

Luis felipe De jesus Munoz
fonte
Precisamos remover zeros à esquerda?
@Mnemonic not necessariamente #
Luis felipe De jesus Munoz
posso pegar a entrada com os lados =trocados? por exemplo579=1#3+45#
dzaima 30/08
2
"Suponha que ambos os termos> 0" significa "suponha" significa que eu tenho que emitir os dois termos> 0 ou que posso assumir que sempre há uma solução com ambos> 0, mas que saída?
Dzaima 30/08/19
1
também o teste caso adicionado evita exatamente o que eu estava pedindo - os zeros à esquerda
dzaima

Respostas:

9

Braquilog , 22 16 bytes

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

Experimente online!

-6 bytes graças a @Fatelize

Explicação

{Ṣ∧Ị∋|}ᵐ²ịᵐ.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
Kroppeb
fonte
1
{"#"∧Ị∋|}ᵐ²ịᵐ.k+~té 4 bytes mais curto. Não sei por que você fez algo tão complicado no seu mapa.
Fatalize 31/08/18
Como podemos usar qualquer caractere não numérico, você deve usar, por exemplo, espaço com, em vez de "#"que salvará mais dois bytes.
Fatalize 31/08/19
8

JavaScript (ES6), 74 57 bytes

Toma de entrada como (a)(b)(result), onde um e b são cadeias com .para números desconhecidos e resultado é um número inteiro. Retorna uma matriz de 2 números inteiros.

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

Experimente online!

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
Arnauld
fonte
Ah, então é isso que está acontecendo. Eu tentei entender seu código sem explicação ontem (e sou ruim em JS), mas não entendi por -~nque não podia ser justo n+1e como F=(c,n)=>era usado. Agora que você adicionou uma explicação, tudo faz sentido. cé a terceira entrada, né indefinida (e ~undefinedse torna -1diferente undefined+1). Tudo claro agora (e não é algo que eu possa portar para Java, infelizmente, e foi por isso que tentei entender o xD). PS: Já votei ontem ontem, então acabei de votar em uma das suas outras respostas (que ainda não votei, não há muito disponível ..); p
Kevin Cruijssen
@KevinCruijssen FWIW, escrevi uma dica sobre isso algumas vezes atrás. Mas sim ... isso é coisa do JS e provavelmente não é portátil para muitas outras línguas.
precisa
Bem, talvez eu possa semi-portá-lo, mas apenas criando um segundo método recursivo e usando um ternary-if para verificar null, convertendo-o manualmente para -1. No entanto, o Java possui um limite StackOverflow recursivo (muito) limitado, portanto, usar um método recursivo com aleatoriedade, esperando que acabe correto em cerca de 1024 chamadas recursivas, não funcionará de maneira alguma em Java. Ah bem. Eu votei na sua dica. Tenha um bom fim de semana! :)
Kevin Cruijssen
@KevinCruijssen Minha primeira tentativa de JS foi exatamente isso: tentar valores aleatórios com uma função recursiva. E usualmente fazia iterações significativamente menos do que aquela que usa um contador. Fato interessante: mesmo assim ###+###=999, suas chances são de 1 em 1000. Portanto, com 1024 iterações, você deve ter sucesso um pouco mais frequentemente do que falha. :)
Arnauld
7

Matlab, 143 134 132 119 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 graças a @Luismendo

Experimente Online


Muito grande e muito estúpido. Ele simplesmente substitui todos #por dígitos aleatórios até encontrar os corretos.

DimChtz
fonte
5

R , 67 51 bytes

Rock simples e escalas horrivelmente, apenas grep todas as combinações de soma. Usar "." para dígitos desconhecidos. Ele não encontrará a mesma resposta que o caso de teste número 4, mas fornecerá uma resposta possível, que segue a letra das regras fornecidas.

-16 bytes grepping após formar a saída e substituir pastepelo ?operador.

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

Experimente online!

J.Doe
fonte
1
Idéia incrível, eu nunca teria pensado nisso. Você pode economizar alguns bytes usando * no lugar de grepl: tio.run/##PYzLCoMwEEX3/...
Jayce
1
Eu estava procurando por vários operadores e você apresentou ?... Acho que é o primeiro. a propósito, esqueci-me se já lhe contei, mas estamos tentando ser nomeado para o idioma de setembro do mês - você pode votar se ainda não o fez.
Jayce
Eu poderia ter escolhido qualquer coisa com baixa precedência. Parece que há deve ser uma maneira melhor de começar o jogo ...
J.Doe
3

Carvão , 32 bytes

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

Experimente online! Link é a versão detalhada do código. Explicação:

F²⊞υ0

Empurre duas cordas 0s para a lista vazia predefinida upara obter o loop while.

W⁻ζΣIυ

Repita enquanto a soma da conversão dos valores upara inteiro não é igual ao resultado desejado.

≔E⟦θη⟧

Crie uma matriz das duas entradas e mapeie sobre ela.

⭆κ⎇⁼μ#‽χμυ

Substitua cada #um por um dígito aleatório e atribua o resultado novamente a u.

←Eυ⮌ι

Imprima o resultado justificado. (Justificado à esquerda seria apenas υpara uma economia de 4 bytes).

Neil
fonte
3

05AB1E (legado), 23 20 bytes

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

-3 bytes graças a @Emigna .

Dígitos desconhecidos são espaços ( ). A ordem de entrada deve ser: resultado esperado; corda mais longa; corda mais curta.

Experimente online .

Explicação:

[                 # 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]
Kevin Cruijssen
fonte
1
Substituir salva 3 sobre o if.
Emigna
@ Emigna Ah, é claro. Obrigado!
Kevin Cruijssen
3

Perl 6 , 81 74 bytes

-7 bytes graças ao nwellnhof!

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

Experimente online!

Bloco de código anônimo que recebe entrada como uma string que contém uma expressão aritmética, por exemplo, "12 # + 45 # = 579". Substitui cada uma #com possíveis permutações de dígitos, substitui =por ==e localiza o primeiro resultado válido.

Explicação:

{  # 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
Brincadeira
fonte
Você pode usar em S:g[\#]=$a[$++]vez de transpor 74 bytes .
Nwellnhof 1/09/18
@nwellnhof Eu não sabia que você poderia usar S///esse tipo de sintaxe! Obrigado!
Jo rei
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;}

Experimente online.

Explicação:

(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
Kevin Cruijssen
fonte
2

C (gcc) , 228 213 203 172 170 bytes

-15 Bytes graças a @ceilingcat . Eu nunca usei indexantes.

-10 bytes graças a @Logem . Magia do pré-processador

chamada refatorada para exit(0)with puts 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])));}

Experimente online!

cleblanc
fonte
Você pode salvar dois bytes substituindo a macro -DX=c=index(vpelo -DX=(c=index(vlink TIO no meu último comentário.
Logern
Obrigado rapazes. Não parece que eu ainda tentou golf isso 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);}

Porta da minha resposta Java 10 .
(Estou muito enferrujado no golfe em C # .NET, por isso posso definitivamente jogar golfe.)

-3 bytes implicitamente graças a @ user82593 e esta nova dica de C # que ele adicionou .
-29 bytes graças a @hvd .

Experimente online.

Explicação:

(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
Kevin Cruijssen
fonte
Você pode usar o regular em using System;vez disso, é mais curto que namespace System{}.
hvd 01/09
@hvd Era isso! .. Eu não faço C # há anos, lol .. Tentei using System.*;similar às importações em Java, mas isso não funcionou. Esqueci que tinha que remover a .*parte .. Obrigado pelos -5 bytes.
Kevin Cruijssen 01/09/19
1
Relendo agora, essa foi realmente uma sugestão subótima. Você pode escrever int.Parse(-4), usar new System.Random()(+7) e soltar using System;(-13) para salvar outros 10 bytes. :) Além disso, você não precisa .ToCharArray(), isso tira mais 14 bytes.
hvd 01/09
@hvd Obrigado! Não sei como eu me esqueci do int.Parsevs System.Int32.Parse... É basicamente o mesmo que System.Stringe string.. E não sabia que era possível fazer um loop sobre os personagens sem o .ToCharArray(). Obrigado por mais -24 bytes. : D
Kevin Cruijssen 01/09/19
1

Python 3 , 121 155 152 149 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)

Experimente online!

+34 Nova solução com regex para contornar o fato de que o python não suporta números com zeros à esquerda.

-3 graças a @Jonathan Frech


A solução antiga não funciona se # for o primeiro caractere de qualquer número (porque eval não aceita zeros à esquerda) e, portanto, é invá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)

Experimente online!

Black Owl Kai
fonte
1
Receio que este envio seja inválido pelo motivo indicado na postagem.
Erik the Outgolfer
2
Como sua função não contém nenhuma instrução composta, você pode condensá-la em apenas uma linha.
Jonathan Frech
0

PHP, 112 bytes

solução de força bruta coxa

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

pega a string como entrada, para na primeira solução. Execute como pipe -nRou experimente online .

Titus
fonte
0

Powershell, 91 bytes

O script encontra todas as soluções. O número total de iterações é 10 em relação ao número de caracteres #. A profundidade da recursão é igual ao 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 teste:

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, 'Suponha que ambos os termos> 0' sejam obrigatórios, 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)}}}
confuso
fonte