O problema do arroz e do xadrez

41

Uma lenda indiana conta a história do suposto inventor do jogo de xadrez, que impressionou tanto o imperador da Índia com seu jogo que ele seria recompensado com qualquer coisa que fosse solicitada.

O homem disse que queria ser pago em arroz. Ele queria um grão de arroz para o primeiro quadrado do tabuleiro de xadrez, dois para o segundo, quatro para o terceiro, oito para o quarto e assim por diante, até o 64º quadrado.

O imperador ficou surpreso que o homem pedisse uma recompensa tão pequena, mas quando seus matemáticos começaram a contar, ele acabou perdendo uma de suas províncias.

Tarefa

Dado o comprimento do lado de um tabuleiro de xadrez hipotético (que é 8 em um tabuleiro de xadrez padrão) e o multiplicador entre quadrados (que é 2 na legenda), calcule o número de grãos de arroz que o imperador deve pagar ao homem.

Notas

  • O comprimento do lado sempre será um número inteiro positivo. O multiplicador poderia ser qualquer tipo de número racional.

  • Se o seu idioma de escolha não puder exibir números muito grandes, tudo bem, desde que o seu programa possa processar corretamente entradas menores.

  • Além disso, se o seu idioma de escolha arredondar valores maiores (com notações exponenciais), tudo bem se esses valores estiverem aproximadamente corretos.

Casos de teste

Input (side length, multiplier) => Output
8, 2                            => 18446744073709551615
3, 6                            => 2015539
7, 1.5                          => 850161998.2854
5, -3                           => 211822152361
256, 1                          => 65536
2, 2                            => 15
2, -2                           => -5

Observe que a fórmula explícita

result = (multiplier ^ (side ^ 2) - 1) / (multiplier - 1)

Executa errado multiplier = 1, como

1 ^ (side ^ 2) - 1 = 0
1 - 1 = 0
0 / 0 != side ^ 2 (as it should be)

Pontuação

Isso é código-golfe. A resposta mais curta em bytes vence.

user6245072
fonte
4
Você provavelmente deseja um caso de teste em que o multiplicador seja 1 e outro em que seja 0 (supondo que ambos sejam válidos). Além disso, "qualquer coisa" é bastante ampla, a raiz quadrada de um negativo conta? Que tal "batata"? ;) Eu recomendaria "qualquer número real" ou algo assim.
FryAmTheEggman
4
If your language of choose can't display too large numbers, it's ok as long as your program can correctly process smaller inputsCuidado, isso causou problemas no passado. meta.codegolf.stackexchange.com/a/8245/31716
DJMcMayhem
24
... deve ter sido uma província rica, porque ainda hoje a produção mundial anual de arroz ainda é inferior a 2 ^ 64 grãos.
vsz
11
@vsz Na verdade, o cara foi morto. A quantia adicionada ao rei doar todo o reino ao homem, então naturalmente a saída mais fácil foi tomada.
cst1992
11
@ cst1992 a versão que li diz que o homem desistiu de seu pedido e recebeu uma província como presente.
User6245072

Respostas:

27

MATL , 6 bytes

2^:q^s

Experimente online!

2^   % Take implicit input, say N, and square it: N^2
:q   % Generate array [0 1 ... N^2-1]
^    % Take implicit input, M, and compute [M^0 M^1 ... M^(N^2-1)]
s    % Sum of the array. Implicit display
Luis Mendo
fonte
23

APL, 10 bytes

⎕⊥1+0×⍳⎕*2

é usado para ler a entrada do usuário duas vezes. Se armazenarmos o comprimento lateral em s e o multiplicador em m , obteremos o código a seguir.

m⊥1+0×⍳s*2

E aqui está como a APL analisa esse código:

Explicação do algoritmo

APL Dude
fonte
4
Ou como um trem de funções: ⊣⊥1⍴⍨⊢×⊢(8 bytes) Como um comando REPL interativo, ⎕⊥×⍳⎕*2(7 bytes) também funciona.
Dennis
19

Python, 40 bytes

lambda n,m:eval('1+m*('*n*n+'0'+')'*n*n)

Gera e avalia uma sequência como

1+m*(1+m*(1+m*(1+m*(0))))

que codifica a soma como um polinômio Hornerizado com n*ntermos.

Muitos métodos diferentes deram contagens de bytes muito semelhantes:

#String evaluation
lambda n,m:eval('1+m*('*n*n+'0'+')'*n*n)   #40

#Direct summation
lambda n,m:sum(m**i for i in range(n*n))   #40
lambda n,m:sum(map(m.__pow__,range(n*n)))  #41

#Direct formula
lambda n,m:n*n*(1==m)or(m**n**2-1)/(m-1)   #40

#Iterative sequence
f=lambda n,m,j=0:j<n*n and 1+m*f(n,m,j+1)  #41
def f(n,m):s=0;exec"s=s*m+1;"*n*n;print s  #41

#Recursive expression
#Fails due to float imprecision of square root
f=lambda n,m:n and 1+m*f((n*n-1)**.5,m)    #39*
xnor
fonte
2
Ah, certo, meu mal. De qualquer forma, eu realmente gosto de ver todas as diferentes abordagens que levou :)
FryAmTheEggman
11

Haskell, 25 bytes

n%m=sum$(m^)<$>[0..n*n-1]

Soma a lista [m^0, m^1, ..., m^(n*n-1)].

xnor
fonte
11

JavaScript (ES2016 / ES7), 31 29 28 bytes

a=>b=>(b**(a*a)-1)/--b||a*a

Apenas o @Bassdrop Cumberwubwubwub e a versão ES6 do @ Kaizo, mas com o operador de exponenciação. :) (Eu não tinha reputação suficiente para comentar.)

Editar: /+(b-1)alterado para /--b(obrigado @ Neil).

Edit: agora usa currying (obrigado @MamaFunRoll).

gcampbell
fonte
Bem-vindo ao PPCG! Sua resposta é muito boa!
NoOneIsHere
Bem vinda! O +operador foi um teste Esqueci para editar, para que possa raspar 1 byte por omiti-lo :)
Bassdrop Cumberwubwubwub
A fórmula não funciona para m = 1: 3
user6245072
@ user6245072 você está no chrome canary? Ou no nó? Se no nó, ativar o sinalizador de harmonia
NiCk Newman
Você /--beconomizaria um byte ou dois?
Neil
10

Gelatina, 6 bytes

²R’*@S

Experimente online!

Freira Furada
fonte
8

MATLAB, 23 bytes

@(n,k)sum(k.^(0:n^2-1))

Teste aqui !

Stewie Griffin
fonte
8

Javascript ES6, 59 37 35 34 bytes

a=>b=>(Math.pow(b,a*a)-1)/--b||a*a` 

Graças a @Kaizo por eliminar 19 bytes, @Neil por mais 2 e @gcampbell por mais 1!

Experimente aqui

Versões quebradas alternativas

32 bytes

(a,b)=>(Math.pow(b,a*a)-1)/(b-1)

Causas NaNpara b==1.

30 bytes

(a,b)=>(Math.pow(b,a*a)-1)/~-b

Causas Infinitypara b==1.5.

28 bytes

(a,b)=>~-Math.pow(b,a*a)/~-b

Saídas 1para alguns casos de teste válidos.

Versão antiga para 59 bytes

(a,b)=>Array(a*a).fill``.reduce((c,d,i)=>c+Math.pow(b,i),0)

Bassdrop Cumberwubwubwub
fonte
Por que você apenas não tratou o caso b == 1 no caso de 32 bytes? (B) (a, b) => b-1? (Math.pow (b, a * a) -1) / (b-1): a * a
Kaizo
@Kaizo você está certo, eu sou um idiota: D
Bassdrop Cumberwubwubwub
/~-bobviamente não é bom para fracionário b, mas /--bdeve funcionar, não?
Neil
A propósito, eu joguei a versão antiga em 47 bytes:(a,b)=>[...Array(a*a-1)].reduce(s=>s+=p*=b,p=1)
Neil
@ Neil você está certo, é claro. É isso que você ganha quando apressa suas respostas: p Obrigado!
Bassumber Cumberwubwubwub
6

Java, 132 bytes

import java.math.*;Object e(int n,BigDecimal m){BigDecimal r=BigDecimal.ONE,a=r;for(n*=n;n>1;n--)r=r.add(a=a.multiply(m));return r;}

Ungolfed

import java.math.*;

Object e(int n, BigDecimal m) {
    BigDecimal r = BigDecimal.ONE, a = r;
    for (n *= n; n > 1; n--)
        r = r.add(a = a.multiply(m));
    return r;
}

Notas

  • Isso funcionará para resultados arbitrariamente grandes, conforme exigido pelo OP (Java muito ruim suporta grandes números, isso seria mais curto caso contrário).

Saídas

Input:      8 2.0
Expected:   18446744073709551615
Actual:     18446744073709551615

Input:      3 6.0
Expected:   2015539
Actual:     2015539

Input:      7 1.5
Expected:   850161998.2854
Actual:     850161998.285399449204543742553141782991588115692138671875

Input:      5 -3.0
Expected:   211822152361
Actual:     211822152361

Input:      256 1.0
Expected:   65536
Actual:     65536

Input:      2 2.0
Expected:   15
Actual:     15

Input:      2 -2.0
Expected:   -5
Actual:     -5

Input:      263 359.9
Expected:   ?
Actual:     9709...[176798 digits]...7344.7184...[69160 digits]...6291
Marv
fonte
6

R, 18 bytes

sum(m^(1:s^2-1))

Explicação:

sum(               # Calculate sum
    m              # Multiplier
     ^             # Exponentiate
      (1:s^2-1))   # Generate sequence from 1 to s(ide)^2-1
Forgottenscience
fonte
5

05AB1E , 5 bytes

Código:

nL<mO

Explicação:

n      # Compute i ** 2
 L     # Push the list [1, ..., i ** 2]
  <    # Decrement by 1, [0, ..., i ** 2 - 1]
   m   # Power function with implicit input, [0 ** j, ..., (i ** 2 - 1) ** j]
    O  # Sum that all up

Experimente online! .

Adnan
fonte
4

Haskell, 30 bytes

n#m=sum$take(n^2)$iterate(*m)1

ou igualmente longo

n%1=n^2
n%m=(m**(n*n)-1)/(m-1)

A primeira versão começa com 1multiplica-se repetidamente com m. Em seguida, soma os primeiros n^2números dessa sequência. A segunda versão é a fórmula explícita, como visto em outras respostas.

nimi
fonte
Você não pode simplesmente fazer n#m=sum$(m^)<$>[0..n*n-1]?
Xnor 03/03
@ xnor: oh, isso é legal. Eu acho que é diferente o suficiente para uma resposta separada. Por favor, publique-o.
nimi
4

J, 10 bytes

+/@:^i.@*:

Uso

Eu marco alguns números inteiros com o xsufixo para usar números inteiros estendidos para obter resultados exatos.

   f =: +/@:^i.@*:
   2x f 8
18446744073709551615
   3x f 6
75047317648499560
   6x f 3
2015539
   1.5 f 7
8.50162e8
   _3x f 5
211822152361
   1 f 256
65536
   2 f 2
15
   _2 f 2
_5

Explicação

+/@:^i.@*:
        *:  Square the value s to get s^2
     i.@    Make a range from 0 to s^2 exclusive, [0, 1, ..., s^2-1]
    ^       Using m as the base, calculate the power with the range
            [m^0, m^1, ..., m^(s^2-1)]
+/@:        Sum the entire list and return it
milhas
fonte
6 bytes #.*:$*conforme o APL Dude.
FrownyFrog
4

Mathcad, [tbd] bytes (~ 11)

insira a descrição da imagem aqui

Usa o operador de soma incorporado do Mathcad. Também demonstra a simplificação simbólica do processador para gerar a fórmula exata.

O Mathcad efetivamente executa dois mecanismos de processamento em paralelo - um um ponto flutuante padrão IEEE de 64/80 bits e o outro um processo simbólico arbitrário de comprimento de número (MuPad). A avaliação numérica padrão é indicada pelo sinal de igual (=), enquanto uma seta para a direita indica avaliação simbólica.


Esquema de contagem do Mathcad ainda a ser determinado, portanto, nenhuma contagem de bytes fornecida.

ctl- $ entra no operador de soma (Sigma), incluindo espaços reservados vazios para colocar a variável de soma, valor inicial, valor final e expressão. Contagem aproximada de equivalentes em bytes = 11.

Stuart Bruff
fonte
onde está o código?
Abr001am 04/04
11
O "código" para o desafio real é o primeiro sinal de soma (capital Sigma) que você vê sob o título "Solução de Desafio". Os outros bits do "código" são fornecidos sob o título "Variantes da solução". O que você vê na imagem é exatamente o que é anotado em uma planilha do Mathcad - o Mathcad usa símbolos matemáticos para várias operações, como soma ou produto de vetores, integração ou diferenciação de funções ou operações lógicas. A maioria dos operadores pode ser inserida com uma combinação de teclas (por exemplo, ctl-4 para uma soma implícita de vetor ou ctl- & para uma soma iterada) ou através de um menu ou barra de ferramentas.
Stuart Bruff #
4

PostgreSQL, 67 66 bytes

SELECT SUM(m^v)FROM(VALUES(3,6))t(s,m),generate_series(0,s*s-1)s(v)

SqlFiddleDemo

Entrada: VALUES(side, multiplier)


EDITAR:

Entrada movida para a tabela, todos os casos de uma vez:

SELECT s,m,SUM(m^v)FROM i,generate_series(0,s*s-1)s(v)GROUP BY s,m

SqlFiddleDemo

Saída:

╔══════╦══════╦══════════════════════╗
║  s   ║  m   ║         sum          ║
╠══════╬══════╬══════════════════════╣
║   7  ║ 1.5  ║ 850161998.2853994    ║
║   2  ║ 2    ║ 15                   ║
║   2  ║ -2   ║ -5                   ║
║ 256  ║ 1    ║ 65536                ║
║   5  ║ -3   ║ 211822152361         ║
║   8  ║ 2    ║ 18446744073709552000 ║
║   3  ║ 6    ║ 2015539              ║
╚══════╩══════╩══════════════════════╝
lad2025
fonte
3

TI-Basic, 19 bytes

Sé o comprimento lateral e Mé o multiplicador.

Prompt S,M:Σ(M^I,I,0,S²-1
Timtech
fonte
3

Python, 40 bytes

lambda l,m:sum(m**i for i in range(l*l))
orlp
fonte
11
lambda l,m:(m**(l*l)-1)/(m-1)
Leaky Nun
Em idiomas regulares, usar fórmula seria mais curto. Eu usei o mapa porque em esolangs os mapas seriam mais curtos.
Leaky Nun
Onde está o tachado?
Freira vazando
@KennyLau Eu ainda estava trabalhando na minha resposta, postei isso antes de ver seu comentário.
orlp
Tudo bem, (mais 7 para ir ...) #
Leaky Nun
3

Ruby: 39 bytes

->s,m{(0...s*s).reduce(0){|a,b|a+m**b}}

Teste:

f = ->s,m{(0...s*s).reduce(0){|a,b|a+m**b}}

f[8,2]   # 18446744073709551615
f[3,6]   # 2015539
f[7,1.5] # 850161998.2853994
f[5,-3]  # 211822152361
f[256,1] # 65536
f[2,2]   # 15
f[2,-2]  # -5
f[1,1]   # 1
br3nt
fonte
Quando Ruby conseguiu uma sumfunção ??? Isso está mudando o jogo
Value Ink
Ah não! O que eu pensei que era um método central de rubi é na verdade um rosto triste do método rails . Eu atualizei a resposta.
Br3nt # 13/16
Você pode apenas mudar seu idioma para Rails? Eu não sei sobre quaisquer importações que você pode precisar para que
Valor Ink
3

Python, 41 bytes

Totalmente novo nessa coisa do golfe, críticas bem-vindas!

lambda n,m:sum(m**i for i in range(n**2))
Lang Tran
fonte
É realmente muito bom; )
user6245072
Haha, obrigada. Eu tive que pesquisar no google como fazer lambdas em python novamente, já que não tocava em python há algum tempo.
Lang Tran
Bem-vindo à programação de quebra-cabeças e código de golfe! Esta é uma boa resposta, mas é bastante semelhante a esta .
Dennis
Ah, não vi se havia outras soluções. Ele salvou um byte ao l**linvés do que eu fiz?
Lang Tran
l*lna verdade, que é mais curto que l**2.
Dennis
2

Jolf, 18 15 10 bytes

Obrigado a Cᴏɴᴏʀ O'Bᴏɴᴏʀ por salvar 3 bytes e me indicar o mapeamento

uΜzQjd^JwH

Experimente aqui!

 ΜzQj       Map over an array of 1 -> square(side length)
     d^JwH  Set the current array value to multiplier^(current value - 1)
u           Sum the array
incha
fonte
Bom trabalho! Você pode remover o a antes do zeta, pois isso é explicitamente explicado. Você também pode usar Mu (mapa) em vez de para cada um, e acho que você pode substituir o D pelo anúncio e remover o final}.
Conor O'Brien
11
@ Cᴏɴᴏʀ O'Bʀɪᴇɴ Bem, continue esquecendo as partes implícitas de Jolf, elas certamente são algumas das melhores maneiras de economizar alguns bytes.
swells
2

CJam , 9 bytes

q~2#,f#:+

As entradas estão na ordem inversa, separadas por uma nova linha ou um espaço.

Experimente online!

q~    e# Read input. Evaluate: pushes the two numbers, M and N, onto the stack
2#    e# Square: compute N^2
,     e# Range: generates array [0 1 ... N^2-1]
f#    e# Compute M raised to each element of the array [0 1 ... N^2-1]
:+    e# Fold addition: compute sum of the array [M^0 M^1 ... M^(N^2-1)]
Luis Mendo
fonte
2

PHP, 58 54 bytes

<?function a($n,$m){$n*=$n;echo(1-$m**$n)/(1-$m)?:$n;}

Isso apenas usa a fórmula de soma para mostrar o valor, depois de verificar se o multiplicador é 1 (que retorna NAN na fórmula).

Xanderhall
fonte
2

Mathematica, 22 bytes

Tr[#^(Range[#2^2]-1)]&

Cria um intervalo de {1, 2, ... s^2}, subtrai 1 sobre ele para criar {0, 1, ..., s^2-1}. Em seguida, eleve cada um ao poder de mfazer {m^0, m^1, ..., m^(s^2-1)}e devolva a soma.

Como alternativa, o Mathematica pode usar a fórmula explícita tomando seu limite. Isso requer 29 bytes.

Limit[(s^#^2-1)/(s-1),s->#2]&
milhas
fonte
Você pode escrever sua primeira versão comoTr[#^Range[#2^2]/#]&
Simon Woods
1

PARI / GP , 25 bytes

f(s,m)=sum(i=0,s^2-1,m^s)

Mais longo, mas mais rápido (35 bytes):

f(s,m)=if(m==1,s^2,(m^s^2-1)/(m-1))

Bonito (30 bytes):

f(s,m)=vecsum(powers(m,s^2-1))
Charles
fonte
1

C #, 56 bytes

double f(int n,double q){return(Math.Pow(q,n*n)-1)/--q;}
downrep_nation
fonte
Testcase 256, 1?
User6245072 4/16
Não é 256 ^ 2?
Downrep_nation
11
(Math.Pow(1, 256 * 256) - 1) / --1= 0/0.
User6245072 4/16
11
Você precisa usar o System; ou System.Math.Pow. E seu código não funciona, quando q = 1, conforme declarado por @ user6245072.
Horváth Dávid
1

Lua, 54 47 bytes

r=0l,m=...for i=0,l^2-1 do r=r+m^i end print(r)

Execute da linha de comando com o comprimento do lado do quadro como o primeiro argumento e o multiplicador como o segundo.

Agradecemos a user6245072 por salvar 6 bytes e a Katenkyo por salvar 1 adicional.


Versão original de 54 bytes:

a,b=...c=1 d=1 for i=2,a^2 do c=c*b d=d+c end print(d)
kidfrommars
fonte
Olá, e bem-vindo ao PPCG! Ótima resposta!
NoOneIsHere
l,m=...r=0 for i=0,l^2 do r=r+m^i end print(r)
User6245072 4/16
Isso deve salvar alguns bytes.
User6245072 4/16
renomear d economiza um byte porque permite pular o espaço em c=1 d=1=> a,b=...c=1g=1 for i=2,a^2 do c=c*b g=g+c end print(g). if @ 's obras sugestão user6245072, você poderia salvar um byte no mesmo princípio =>r=0l,m=...for i=0,l^2 do r=r+m^i end print(r)
Katenkyo
O espaço em branco entre r=0e l,m=...é obrigatório de qualquer maneira, para que não mude. Também o loop deve ser, for i=0,l^2-1mas isso é culpa minha lol.
User6245072
1

11, 11 caracteres / 14 bytes

⨭⩥ î²)ⓜⁿ⁽í$

Try it here (Firefox/WebKit Nightly only).

Sim, agora funciona no WebKit Nightly! O suporte ao Chrome é o próximo.

Explicação

⨭⩥ î²)ⓜⁿ⁽í$ // implicit: î = input1, í = input2
   ⩥ î²)       // generate a range [0..î^2)
                     ⓜ      // map over range ($ is mapitem):
        ⁿ⁽í$  //   í^$
⨭            // sum resulting range
              // implicit output
Mama Fun Roll
fonte
1

RETURN , 32 bytes

[a:2^0\
{[$¥][a;\^]#[¤¥][+]#]!

Try it here.

Lambda anônima que deixa o resultado no Stack2. Uso:

8 2[a:2^0\
{[$¥][a;\^]#[¤¥][+]#]!

Explicação

[                              ]!  lambda
 a:                                store multiplier to a
   2^                              square side-length
     0\␊                           create range [0..result)
        {                          set current stack to range
         [  ][     ]#              while loop
          $¥                         check if TOS is truthy
              a;\^␌                  if so, push a^TOS to Stack2
                     ␁            set current stack to Stack2
                       [¤¥][+]#    sum Stack2
Mama Fun Roll
fonte