Multiplique com operações restritas


44

Há uma recompensa não oficial de 500 representantes por vencer a melhor resposta atual .

Objetivo

Seu objetivo é multiplicar dois números usando apenas um conjunto muito limitado de operações aritméticas e atribuição de variáveis.

  1. Adição x,y -> x+y
  2. Recíproco x -> 1/x( não divisão x,y -> x/y)
  3. Negação x -> -x( não subtração x,y -> x-y, embora você possa fazer isso como duas operações x + (-y))
  4. A constante 1(nenhuma outra constante é permitida, exceto como produzida pelas operações de 1)
  5. Atribuição variável [variable] = [expression]

Pontuação: Os valores começam nas variáveis ae b. Seu objetivo é salvar o produto a*bna variável cusando o mínimo de operações possível. Cada operação e atribuição +, -, /, =custa um ponto (equivalentemente, cada uso de (1), (2), (3) ou (4)). As constantes 1são gratuitas. A solução com menos pontos ganha. O desempate é o primeiro post.

Permissão: Sua expressão deve estar aritmeticamente correta para reais ae "aleatórios" b. Ele pode falhar num subconjunto medida de zero de R 2 , isto é, um conjunto que não tem nenhuma área se representados graficamente na a- bplano cartesiano. (É provável que isso seja necessário devido a recíprocas de expressões que possam ser 0semelhantes 1/a.)

Gramática:

Este é um . Nenhuma outra operação pode ser usada. Em particular, isso significa que não há funções, condicionais, loops ou tipos de dados não numéricos. Aqui está uma gramática para as operações permitidas (as possibilidades são separadas por |). Um programa é uma sequência de <statement>s, onde a <statement>é dada da seguinte maneira.

<statement>: <variable> = <expr>
<variable>: a | b | c | [string of letters of your choice]
<expr>: <arith_expr> | <variable> | <constant>
<arith_expr>: <addition_expr> | <reciprocal_expr> | <negation_expr> 
<addition_expr>: <expr> + <expr>
<reciprocal_expr>: 1/(<expr>)
<negation_expr>: -<expr>
<constant>: 1

Na verdade, você não precisa postar código nesta gramática exata, desde que fique claro o que você está fazendo e sua contagem de operações esteja correta. Por exemplo, você pode escrever a-bpara o a+(-b)e contá-lo como duas operações, ou definir macros para brevidade.

(Havia uma pergunta anterior Multiplicar sem Multiplicar , mas permitia um conjunto de operações muito mais flexível.)


4
Isso é possível?
Ypnypn

1
@Ypnypn Sim, e eu escrevi um exemplo para ter certeza.
xnor

2
Parece um desafio em que é provável que seja encontrada uma solução ideal (depois que qualquer solução for encontrada). Então, qual é o desempate nesse caso?
Martin Ender

1
@ MartinBüttner Tiebreak é a publicação mais antiga nesse caso. Eu acho que há muito espaço para otimizações, então não acho que seja apenas uma corrida para encontrar uma que funcione e escrevê-la de forma limpa. Pelo menos, foi o que eu achei ao tentar; talvez alguém encontre uma solução claramente mínima.
xnor

2
Ok, já que nem todo mundo pensou que minha resposta era tão engraçada quanto eu, excluí-a e comente aqui: A regra sobre o conjunto de medidas zero não é escolhida com muita sabedoria, pois os números racionais são um conjunto de medidas zero em relação à medida de libras, eu sugiro usando uma certa porcentagem. (Ou outro tipo) Mas eu gosto totalmente da ideia desse desafio!
flawr

Respostas:


34

22 operações

itx = 1/(1+a+b)     #4
nx = -1/(itx+itx)   #4
c = -( 1/(itx + itx + 1/(1+nx)) + 1/(1/(a+nx) + 1/(b+nx)) ) #14

Experimente online!

As operações são 10 adições, 7 inversas, 2 negações e 3 atribuições.

Então, como eu consegui isso? Comecei com o modelo de aparência promissora da soma de duas frações de dois andares, um motivo que havia aparecido em muitas tentativas anteriores.

c = 1/(1/x + 1/y) + 1/(1/z + 1/w)

Quando restringimos a soma x+y+z+w=0, ocorre um cancelamento bonito, fornecendo:

c = (x+z)*(y+z)/(x+y),

que contém um produto. (Muitas vezes é mais fácil obter t*u/vdo que t*uporque o primeiro tem o grau 1.)

Existe uma maneira mais simétrica de pensar sobre essa expressão. Com a restrição x+y+z+w=0, seus valores são especificados por três parâmetros p,q,rde suas somas em pares.

 p = x+y
-p = z+w
 q = x+z
-q = y+w
 r = x+w
-r = y+z

e nós temos c=-q*r/p. A soma pé distinguida como estando no denominador por corresponder aos pares (x,y)e (z,w)às variáveis ​​que estão na mesma fração.

Esta é uma boa expressão para cin p,q,r, mas a fração de dois andares está em, x,y,z,wportanto devemos expressar a primeira em termos da segunda:

x = ( p + q + r)/2
y = ( p - q - r)/2
z = (-p + q - r)/2
w = (-p - q + r)/2

Agora, queremos escolher p,q,rpara que c=-q*r/pseja igual a*b. Uma escolha é:

p = -4
q = 2*a
r = 2*b

Em seguida, os valores dobrados qe rsão convenientemente divididos pela metade em:

x = -2 + a + b
y = -2 - a - b
z =  2 + a - b
w =  2 - a + b

Salvar 2como variável te conectá-los à equação de cfornece uma solução 24-op.

#24 ops
t = 1+1   #2
c = 1/(1/(-t+a+b) + 1/-(t+a+b))  +  1/(1/(-b+t+a) + 1/(-a+b+t)) #1, 10, 1, 10

Existem 12 adições, 6 inversas, 4 negações e 2 atribuições.

Muitas operações são gastas expressando x,y,z,wem termos de 1,a,b. Para salvar ops, expresse xem p,q,r(e assim a,b,1) e depois escreva y,z,wem termos de x.

y = -x + p
z = -x + q
w = -x + r

Escolhendo

p = 1
q = a
r = b

e expressando ccom uma negação como c=-q*r/p, temos

x = (1+a+b)/2
y = -x + 1
z = -x + a
w = -x + b

Infelizmente, reduzir para metade xé caro. Isso precisa ser feito invertendo, adicionando o resultado a si próprio e invertendo novamente. Nós também negate para produzir nxpara -x, uma vez que é o que y,z,wuso. Isso nos dá a solução 23-op:

#23 ops
itx = 1/(1+a+b)     #4
nx = -1/(itx+itx)   #4
c = -( 1/(1/(-nx) + 1/(1+nx))  +  1/(1/(a+nx) + 1/(b+nx)) ) #15

itxé 1 / (2 * x) e nxé -x. Uma otimização final da expressão 1/xcomo em itx+itxvez do modelo 1/(-nx)corta um caractere e reduz a solução para 22 operações.


Há uma otimização fácil para 21 operações. itx + itxocorre duas vezes, mas itxnão ocorre em nenhum outro contexto. Defina em vez disso ix = (1+1)/(1+a+b)e substitua duas adições por uma.
Peter Taylor

E, ao extrair m = -1, é possível obter 20:nx = (1+a+b)/(m+m); c = m/(m/nx + 1/(1+nx)) + m/(1/(a+nx) + 1/(b+nx))
Peter Taylor

3
Ah, ambas as otimizações falham porque a operação suportada é recíproca ao invés de divisão.
Peter Taylor

Se ae bsão apenas um separados, então um a + nx = 0ou outro b + nx = 0, fazendo com que sua solução seja dividida por zero.
MooseOnTheRocks 17/03

1
@MooseOnTheRocks Tudo bem, veja a "permissão" no desafio de que o código pode falhar em um subconjunto de medida zero. Eu acho que o desafio é impossível de outra maneira.
xnor 17/03

26

23 operações

z = 1/(1/(1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1))-(1/a+1/b))
res = z+z

prova por explosão:

z = 1/(1/(1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1))-(1/a+1/b))
             1/(a+1)+1/(b+1)                            == (a+b+2) / (ab+a+b+1)
          1/(1/(a+1)+1/(b+1))                           == (ab+a+b+1) / (a+b+2)
          1/(1/(a+1)+1/(b+1))-1                         == (ab - 1) / (a+b+2)
          1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1)             == ab / (a+b+2)
       1/(1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1))            == (a+b+2) / ab
                                              1/a+1/b   == (a+b) / ab
       1/(1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1))-(1/a+1/b)  == 2 / ab
    1/(1/(1/(1/(a+1)+1/(b+1))-1+1/(a+b+1+1))-(1/a+1/b)) == ab / 2

z = ab / 2 and therefore z+z = ab

Eu abusei do wolfram alpha para obter essa imagem bonita (o wolfram alpha tentou me inscrever no pro para salvá-lo, mas depois ctrl-c ctrl-v ;-)):

score (com adição +de subtração):

z = ////++/++-+/++++-/+/
res = +

Parabéns pela solução mais curta!
xnor

@xnor obrigado por me dar minha primeira resposta aceita e minha primeira recompensa!
proud haskeller

Para não ser exigente, mas não deve ... (b + 1)) - 1 + 1 ... e ... 1)) - (1 / a + ... ser ... (b + 1 )) + - 1 + 1 ... e ... 1)) + - (1 / a + ..., respectivamente?
tfitzger

@ tfitzger Eu acho que é mais fácil assim. A pergunta diz que isso não importa. Nota eu contar a pontuação corretamente (Cada menos é um dois)
haskeller orgulhoso

O Wolfram Alpha tem uma avaliação gratuita de 7 dias, para sua informação.
ghosts_in_the_code

13

29 operações

Não funciona para o conjunto {(a, b) ∈ R 2 | a + b = 0 ou a + b = -1 ou ab = 0 ou ab = -1}. Provavelmente isso é zero?

sum = a+b
nb = -b
diff = a+nb
rfc = 1/(1/(1/sum + -1/(sum+1)) + -1/(1/diff + -1/(diff+1)) + nb + nb)  # rfc = 1/4c
c = 1/(rfc + rfc + rfc + rfc)

# sum  is  2: =+
# nb   is  2: =-
# diff is  2: =+
# rfc  is 18: =///+-/++-//+-/+++
# c    is  5: =/+++
# total = 29 operations

A estrutura de rfc(Recíproco-Quatro-C) é mais evidente se definirmos uma macro:

s(x) = 1/(1/x + -1/(x+1))              # //+-/+ (no = in count, macros don't exist)
rfc = 1/(s(sum) + - s(diff) + nb + nb) # =/s+-s++ (6+2*s = 18)

Vamos fazer as contas:

  • s(x), matematicamente, é o 1/(1/x - 1/(x+1))que é depois de um pouco de álgebra é x*(x+1)ou x*x + x.
  • Quando você submete tudo rfc, é realmente o 1/((a+b)*(a+b) + a + b - (a-b)*(a-b) - a + b + (-b) + (-b))que é justo 1/((a+b)^2 - (a-b)^2).
  • Depois diferença de quadrados, ou apenas a expansão simples, você tem que rfcé 1/(4*a*b).
  • Finalmente, cé o recíproco de 4 vezes rfc, assim 1/(4/(4*a*b))se torna a*b.

2
+1, eu estava no meio de terminar esse cálculo idêntico
Eric Tressler

1
Definitivamente, é a medida zero; é uma união de linhas.
xnor

Não vou fazer um comentário sobre união de linhas ... @algorithmshark Você pode nos dizer mais como surgiu essa identidade? Como você abordou o problema?
flawr

1
@ flawr Lembrei-me de que as propriedades se s(x)encaixavam nos requisitos da pergunta, do cálculo, o que significava que eu tinha uma função quadrada. Depois de algumas perguntas, descobri que poderia conseguir um a*btermo com o truque da diferença de quadrados. Uma vez que eu tive isso, era uma questão de experimentar quais atribuições salvavam operações.
algorithmshark

Como você usa -1três vezes rfc, você não pode jogar fora um personagem atribuindo-o a uma variável?
Isaacg

9

27 operações

tmp = 1/(1/(1+(-1/(1/(1+(-a))+1/(1+b))))+1/(1/(1/b+(-1/a))+1/(a+(-b))))
res = tmp+tmp+(-1)

# tmp is 23: =//+-//+-+/++///+-/+/+-
# res is 4: =++-

Não há teoria por trás disso. Eu apenas tentei começar (const1+a*b)/const2e comecei com (1/(1-a)+1/(1+b))e (-1/a+1/b).


Você tmptem 23 anos, alcançando 27 pontos.
algorithmshark
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.