Il problema del riso e degli scacchi


41

Una leggenda indiana racconta la storia del presunto inventore del gioco degli scacchi, che ha impressionato così tanto l'imperatore dell'India con il suo gioco da essere ricompensato da qualsiasi cosa gli fosse stata chiesta.

L'uomo disse che voleva essere pagato in riso. Voleva un chicco di riso per il primo quadrato della scacchiera, due per il secondo, quattro per il terzo, otto per il quarto e così via, fino al 64 ° quadrato.

L'imperatore fu sorpreso dal fatto che l'uomo avesse chiesto una ricompensa così piccola, ma quando i suoi matematici iniziarono a contare, finì per perdere una delle sue province.

Compito

Data la lunghezza del lato di un'ipotetica scacchiera (che è 8 su una scacchiera predefinita) e il moltiplicatore tra i quadrati (che è 2 nella legenda), calcola il numero di chicchi di riso che l'imperatore deve pagare all'uomo.

Gli appunti

  • La lunghezza del lato sarà sempre un numero intero positivo. Il moltiplicatore potrebbe invece essere qualsiasi tipo di numero razionale.

  • Se la tua lingua preferita non può visualizzare numeri molto grandi, va bene finché il tuo programma può elaborare correttamente input più piccoli.

  • Anche se la tua lingua preferita arrotonda valori più grandi (con notazioni esponenziali), va bene se questi valori sono approssimativamente corretti.

Casi test

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

Si prega di notare che la formula esplicita

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

Si comporta male su multiplier = 1, come

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

punteggio

Questo è code-golf. Vince la risposta più breve in byte.


4
Probabilmente vuoi un caso di test in cui il moltiplicatore è 1 e un altro in cui è 0 (supponendo che entrambi siano validi). Anche "qualunque cosa" è piuttosto ampia, conta la radice quadrata di quella negativa? Che ne dici di "patata"? ;) Consiglierei "qualsiasi numero reale" o qualcosa del genere.
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 inputsAttento, questo ha causato problemi in passato. meta.codegolf.stackexchange.com/a/8245/31716
DJMcMayhem

24
... deve essere stata una provincia ricca, perché anche oggi la produzione mondiale annuale di riso è ancora inferiore a 2 ^ 64 chicchi.
vsz,

1
@vsz In realtà, il ragazzo è stato ucciso. L'importo aggiunto al re che regalava l'intero regno all'uomo, così naturalmente fu presa la via più facile.
cst1992,

1
@ cst1992 la versione che ho letto dice che l'uomo ha rinunciato alla sua richiesta e ha ricevuto una provincia in regalo.
user6245072,

Risposte:



27

MATL , 6 byte

2^:q^s

Provalo 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

23

APL, 10 byte

⎕⊥1+0×⍳⎕*2

viene utilizzato per leggere due volte l'input dell'utente. Se conserviamo la lunghezza del lato di s e il moltiplicatore in m , otteniamo il seguente codice.

m⊥1+0×⍳s*2

Ed ecco come APL analizza questo codice:

Spiegazione dell'algoritmo


4
O come treno di funzioni: ⊣⊥1⍴⍨⊢×⊢(8 byte) Come comando interattivo REPL, funziona anche ⎕⊥×⍳⎕*2(7 byte).
Dennis,

19

Python, 40 byte

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

Genera e valuta una stringa come

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

che codifica la somma come un polinomio Hornerized con n*ntermini.

Molti metodi diversi hanno dato conteggi di byte molto simili:

#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*

2
Ah giusto, il mio male. Ad ogni modo, mi piace molto vedere tutti i diversi approcci che hai adottato :)
FryAmTheEggman,


11

Haskell, 25 byte

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

Somma l'elenco [m^0, m^1, ..., m^(n*n-1)].


11

JavaScript (ES2016 / ES7), 31 29 28 byte

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

Solo @Bassdrop Cumberwubwubwub e la versione ES6 di @ Kaizo, ma con operatore esponenziale. :) (Non avevo abbastanza reputazione per commentare invece.)

Modifica: /+(b-1)modificato in /--b(grazie @Neil).

Modifica: ora usa il curry (grazie @MamaFunRoll).


Benvenuti in PPCG! La tua risposta è abbastanza buona!
NoOneIsHere

Benvenuto! L' +operatore è stato un test che ho dimenticato di modificare, quindi puoi radere via 1 byte omettendolo :)
Bassdrop Cumberwubwubwub

La formula non funziona per m = 1: 3
user6245072

@ user6245072 sei su Chrome Canary? O sul nodo? Se sul nodo, abilita il flag harmony
NiCk Newman

Ti /--brisparmieresti un byte o due?
Neil,



8

Javascript ES6, 59 37 35 34 byte

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

Grazie a @Kaizo per aver rasato ben 19 byte, @Neil per altri 2 e @gcampbell per altri 1!

Provalo qui

Versioni rotte alternative

32 byte

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

Cause NaNdib==1 .

30 byte

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

Cause Infinitydib==1.5 .

28 byte

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

Uscite 1 per alcune prove valide.

Vecchia versione per 59 byte

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


Perché non hai appena trattato il caso b == 1 nel caso 32 byte? 40 byte: (a, b) => b-1? (Math.pow (b, a * a) -1) / (b-1): a * a
Kaizo

@Kaizo hai ragione, sono un idiota: D
Bassdrop Cumberwubwubwub

/~-bovviamente non va bene per il frazionario b, ma /--bdovrebbe funzionare, no?
Neil,

A proposito, ho giocato a golf la vecchia versione fino a 47 byte:(a,b)=>[...Array(a*a-1)].reduce(s=>s+=p*=b,p=1)
Neil

@Neil hai ragione, ovviamente. Questo è ciò che ottieni quando affretti le tue risposte: p Grazie!
Bassdrop Cumberwubwubwub

6

Java, 132 byte

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;
}

Gli appunti

  • Questo funzionerà per output arbitrariamente grandi come richiesto da OP (Peccato che Java supporti numeri grandi, altrimenti sarebbe più corto).

Uscite

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

6

R, 18 byte

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

Spiegazione:

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

5

05AB1E , 5 byte

Codice:

nL<mO

Spiegazione:

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

Provalo online! .


4

Haskell, 30 byte

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

o ugualmente lungo

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

La prima versione inizia con 1si moltiplica ripetutamente con m. Quindi somma i primi n^2numeri di questa sequenza. La seconda versione è la formula esplicita vista in altre risposte.


Non puoi farlo n#m=sum$(m^)<$>[0..n*n-1]?
xnor

@xnor: oh, è carino. Penso che sia abbastanza diverso per una risposta separata. Per favore, pubblicalo tu stesso.
nimi,

4

J, 10 byte

+/@:^i.@*:

uso

Contrassegno alcuni numeri interi con il xsuffisso per utilizzare numeri interi estesi per ottenere risultati esatti.

   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

Spiegazione

+/@:^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

6 byte #.*:$*come da APL Dude.
FrownyFrog,

4

Mathcad, [tbd] byte (~ 11)

enter image description here

Utilizza l'operatore di sommatoria incorporato di Mathcad. Dimostra anche la semplificazione del processore simbolico per generare una formula esatta.

Mathcad esegue effettivamente due motori di elaborazione in parallelo: uno un IEEE standard 64/80 bit in virgola mobile e l'altro un processo simbolico di lunghezza numerica arbitraria (MuPad). La valutazione numerica standard è indicata dal segno di uguale (=), mentre una freccia destra indica la valutazione simbolica.


Schema di conteggio Mathcad ancora da determinare, quindi nessun conteggio dei byte indicato.

ctl- $ inserisce l'operatore di sommatoria (Sigma), inclusi segnaposto vuoti per inserire la variabile di sommatoria, il valore iniziale, il valore finale e l'espressione. Conteggio approssimativo equivalente in byte = 11.


dov'è il codice?
Abr001am

1
Il "codice" per la vera sfida è il primo segno di somma (capitale Sigma) che vedi sotto la voce "Soluzione di sfida". Gli altri bit di "codice" sono riportati sotto l'intestazione "Varianti di soluzione". Quello che vedi nell'immagine è esattamente ciò che viene scritto su un foglio di lavoro di Mathcad: Mathcad utilizza simboli matematici per varie operazioni, come una somma o un prodotto vettoriale, l'integrazione o la differenziazione delle funzioni o le operazioni logiche. La maggior parte degli operatori può essere inserita con una combinazione di tasti (ad esempio ctl-4 per una somma vettoriale implicita o ctl- e per una somma iterata) o tramite un menu o una barra degli strumenti.
Stuart Bruff,

4

PostgreSQL, 67 66 byte

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

SqlFiddleDemo

Ingresso: VALUES(side, multiplier)


MODIFICARE:

Input spostato nella tabella, tutti i casi contemporaneamente:

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

SqlFiddleDemo

Produzione:

╔══════╦══════╦══════════════════════╗
║  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              ║
╚══════╩══════╩══════════════════════╝

3

TI-Basic, 19 byte

Sè la lunghezza laterale ed Mè il moltiplicatore.

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

3

Python, 40 byte

lambda l,m:sum(m**i for i in range(l*l))

1
lambda l,m:(m**(l*l)-1)/(m-1)
Leaky Nun,

Nelle lingue normali l'uso della formula sarebbe più breve. Ho usato map perché in esolangs le mappe sarebbero più brevi.
Leaky Nun,

Dov'è il barrato?
Leaky Nun,

@KennyLau Stavo ancora lavorando sulla mia risposta, l'ho postato prima di vedere il tuo commento.
orlp,

Bene, (altri 7 per andare ...)
Leaky Nun

3

Rubino: 39 byte

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

Test:

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

Quando ha avuto una sumfunzione Ruby ??? Questo è gamechanging
Value Ink

Oh no! Quello che pensavo fosse un metodo di base rubino è in realtà una faccia triste del metodo rails . Ho aggiornato la risposta.
1616

Puoi semplicemente cambiare la tua lingua in Rails? Non sono a conoscenza di importazioni di cui potresti aver bisogno
Value Ink,

3

Python, 41 byte

Totalmente nuovo in questa cosa del golf, le critiche sono benvenute!

lambda n,m:sum(m**i for i in range(n**2))

In realtà è abbastanza buono; )
user6245072,

Haha grazie. Ho dovuto cercare su Google come eseguire lambda in Python, dato che non ho toccato Python per un po '.
Lang Tran,

Benvenuto in Programmazione di puzzle e codice golf! Questa è una bella risposta, ma è piuttosto simile a questa .
Dennis,

Ah, non ho visto se c'erano altre soluzioni. Ha salvato un byte facendo l**linvece di quello che ho fatto?
Lang Tran,

l*lin realtà, che è più breve di l**2.
Dennis,

2

Jolf, 18 15 10 byte

Grazie a Cᴏɴᴏʀ O'Bʀɪᴇɴ per aver salvato 3 byte e mi ha indicato la mappatura

uΜzQjd^JwH

Provalo qui!

 Μ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

Bel lavoro! Puoi rimuovere la a prima della zeta, poiché è implicitamente eliminata. Puoi anche usare Mu (mappa) invece di ciascuno, e penso che puoi sostituire la D con l'annuncio e rimuovere la fine}.
Conor O'Brien,

1
@ Cᴏɴᴏʀ O'Bʀɪᴇɴ Neat, continua a dimenticare le parti implicite di Jolf, sono sicuramente alcuni dei modi migliori per radere qualche byte.
gonfia

2

CJam , 9 byte

q~2#,f#:+

Gli input sono in ordine inverso separati da una nuova riga o uno spazio.

Provalo 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)]

2

PHP, 58 54 byte

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

Questo utilizza solo la formula di somma per mostrare il valore, dopo aver verificato se il moltiplicatore è 1 (che restituisce NAN nella formula).


2

Mathematica, 22 byte

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

Crea un intervallo di {1, 2, ... s^2}, sottrae 1 da esso per crearlo {0, 1, ..., s^2-1}. Quindi aumenta ciascuno al potere di mfare{m^0, m^1, ..., m^(s^2-1)} and return the sum of it.

In alternativa, Mathematica può utilizzare la formula esplicita assumendone il limite. Ciò richiede 29 byte.

Limit[(s^#^2-1)/(s-1),s->#2]&

You could write your first version as Tr[#^Range[#2^2]/#]&
Simon Woods

1

PARI/GP, 25 bytes

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

Longer but faster (35 bytes):

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

Cute (30 bytes):

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


1

Lua, 54 47 bytes

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

Run from the command line with the board side length as the first argument and the multiplier as the second.

Thanks to user6245072 for saving 6 bytes, and Katenkyo for saving an additional 1.


Original 54 byte version:

a,b=...c=1 d=1 for i=2,a^2 do c=c*b d=d+c end print(d)

Hello, and welcome to PPCG! Great answer!
NoOneIsHere

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

This should save some bytes.
user6245072

renaming d saves one byte because it allows to skip the space in 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 @user6245072 's suggestion works, you could save a byte on the same principle => r=0l,m=...for i=0,l^2 do r=r+m^i end print(r)
Katenkyo

The whitespace between r=0 and l,m=... is anyway compulsory, so it doesn't change. Also the loop should be for i=0,l^2-1 but this is my fault lol.
user6245072

1

𝔼𝕊𝕄𝕚𝕟, 11 chars / 14 bytes

⨭⩥ î²)ⓜⁿ⁽í$

Try it here (Firefox/WebKit Nightly only).

Yes, 𝔼𝕊𝕄𝕚𝕟 now works in WebKit Nightly! Chrome support is next.

Explanation

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

1

RETURN, 32 bytes

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

Try it here.

Anonymous lambda that leaves result on Stack2. Usage:

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

Explanation

[                              ]!  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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.