Le problème du riz et des échecs


41

Une légende indienne raconte l'histoire de l'inventeur présumé du jeu d'échecs, qui a tellement impressionné l'empereur des Indes avec son jeu qu'il serait récompensé par tout ce qui lui serait demandé.

L'homme a dit qu'il voulait être payé en riz. Il voulait un grain de riz pour le premier carré de l'échiquier, deux pour le second, quatre pour le troisième, huit pour le quatrième et ainsi de suite jusqu'au 64ème carré.

L'empereur était étonné que l'homme demande une si petite récompense, mais lorsque ses mathématiciens ont commencé à compter, il a fini par perdre l'une de ses provinces.

Tâche

Étant donné la longueur du côté d'un échiquier hypothétique (qui est 8 sur un échiquier par défaut) et le multiplicateur entre les carrés (qui est 2 dans la légende), calculez le nombre de grains de riz que l'empereur doit payer à l'homme.

Remarques

  • La longueur du côté sera toujours un entier positif. Le multiplicateur pourrait plutôt être n'importe quel type de nombre rationnel.

  • Si la langue de votre choix ne peut pas afficher de très grands nombres, c'est correct tant que votre programme peut traiter correctement des entrées plus petites.

  • De plus, si votre langue de choix arrondit les valeurs les plus grandes (avec des notations exponentielles), il est acceptable que ces valeurs soient approximativement correctes.

Testcases

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

Veuillez noter que la formule explicite

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

Effectue mal sur multiplier = 1, comme

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

Notation

C'est du code-golf. La réponse la plus courte en octets l'emporte.


4
Vous voulez probablement un scénario de test où le multiplicateur est 1 et un autre où il est égal à 0 (en supposant que les deux sont valides). Aussi, "n'importe quoi" est assez large, est-ce que la racine carrée du négatif est comptée? Que diriez-vous de "pomme de terre"? ;) Je recommanderais "n'importe quel nombre réel" ou quelque chose comme ça.
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 inputsAttention, cela a causé des problèmes dans le passé. meta.codegolf.stackexchange.com/a/8245/31716
DJMcMayhem

24
... ce devait être une province riche, car même aujourd'hui, la production mondiale annuelle de riz est toujours inférieure à 2 ^ 64 grains.
vsz

1
@vsz En fait, le gars a été tué. Le montant ajouté au roi donnant le royaume entier à l'homme, donc naturellement, la solution de facilité la plus facile a été prise.
cst1992

1
@ cst1992 la version que j'ai lue dit que l'homme a renoncé à sa demande et a reçu une province en cadeau.
user6245072

Réponses:



27

MATL , 6 octets

2^:q^s

Essayez-le en ligne!

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 octets

⎕⊥1+0×⍳⎕*2

est utilisé pour lire une entrée utilisateur deux fois. Si nous stockons la longueur des côtés dans s et le multiplicateur dans m , nous obtenons le code suivant.

m⊥1+0×⍳s*2

Et voici comment APL analyse ce code:

Explanation of algorithm


4
Ou comme train de fonctions: ⊣⊥1⍴⍨⊢×⊢(8 octets) En tant que commande REPL interactive, ⎕⊥×⍳⎕*2(7 octets) fonctionne également.
Dennis

19

Python, 40 octets

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

Génère et évalue une chaîne comme

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

qui encode la somme en tant que polynôme Hornerisé avec des n*ntermes.

Beaucoup de méthodes différentes donnaient des comptes d'octets très similaires:

#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 oui, mon mauvais. Quoi qu'il en soit, j'aime beaucoup voir les différentes approches que vous avez
adoptées


11

Haskell, 25 octets

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

Somme la liste [m^0, m^1, ..., m^(n*n-1)].


11

JavaScript (ES2016 / ES7), 31 29 28 octets

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

Juste @Bassdrop Cumberwubwubwub et la version ES6 de @ Kaizo, mais avec un opérateur d’exponentiation. :) (Je n'ai pas eu assez de réputation pour commenter.)

Modifier: /+(b-1)remplacé par/--b (merci @Neil).

Edit: utilise maintenant currying (merci @MamaFunRoll).


Bienvenue chez PPCG! Votre réponse est très bonne!
NoOneIsHere

Bienvenue! L’ +opérateur était un test que j’avais oublié d’éditer, vous pouvez donc supprimer 1 octet en l’omettant :)
Bassdrop Cumberwubwubwub

La formule ne fonctionne pas pour m = 1: 3
user6245072

@ user6245072 êtes-vous sur le canari chromé? Ou sur le noeud? Si sur le noeud,
active le

Voulez- /--bvous économiser un octet ou deux?
Neil



8

Javascript ES6, 59 37 35 34 octets

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

Merci à @Kaizo pour avoir rasé 19 octets, @Neil pour 2 autres et @gcampbell pour 1 de plus!

Essayez-le ici

Versions brisées alternatives

32 octets

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

Causes NaNdeb==1.

30 octets

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

Causes Infinityde b==1.5.

28 octets

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

Sorties 1pour certains cas de test valides.

Ancienne version pour 59 octets

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


Pourquoi n'avez-vous pas traité le cas b == 1 dans le cas des 32 octets? 40 octets: (a, b) => b-1? (Math.pow (b, a * a) -1) / (b-1): a * a
Kaizo

@ Kaizo tu as raison, je suis un idiot: D
Bassdrop Cumberwubwubwub

/~-best évidemment pas bon pour fractionnaire b, mais /--bdevrait travailler, non?
Neil

A propos, j'ai joué au golf avec l'ancienne version jusqu'à 47 octets: (a,b)=>[...Array(a*a-1)].reduce(s=>s+=p*=b,p=1)
Neil,

@ Neil tu as raison, bien sûr. C'est ce que vous obtenez lorsque vous précipitez vos réponses: p Merci!
Bassdrop Cumberwubwubwub

6

Java, 132 octets

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

Remarques

  • Cela fonctionnera pour des sorties arbitrairement grandes comme l'exige l'OP (Dommage que Java prenne en charge les grands nombres, cela serait plus court sinon).

Les sorties

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 octets

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

Explication:

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

5

05AB1E , 5 octets

Code:

nL<mO

Explication:

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

Essayez-le en ligne! .


4

Haskell, 30 octets

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

ou tout aussi long

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

La première version commence par 1multiplier à plusieurs reprises par m. Ensuite, il additionne les premiers n^2nombres de cette séquence. La deuxième version est la formule explicite comme on le voit dans d’autres réponses.


Tu ne peux pas faire juste n#m=sum$(m^)<$>[0..n*n-1]?
xnor

@xnor: oh, c'est gentil. Je pense que c'est assez différent pour une réponse séparée. S'il vous plaît poster vous-même.
Nimi

4

J, 10 octets

+/@:^i.@*:

Usage

Je marque certains entiers avec le xsuffixe pour utiliser des entiers étendus pour obtenir des résultats exacts.

   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

Explication

+/@:^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 octets #.*:$*selon APL Dude.
FrownyFrog

4

Mathcad, [à déterminer] octets (~ 11)

enter image description here

Utilise l'opérateur de sommation intégré de Mathcad. Montre également la simplification symbolique du processeur pour générer une formule exacte.

Mathcad exécute efficacement deux moteurs de traitement en parallèle: l'un à virgule flottante IEEE 64/80 standard et l'autre, un processus symbolique de longueur numérique (MuPad). L'évaluation numérique standard est indiquée par le signe égal (=), tandis qu'une flèche droite indique une évaluation symbolique.


Le schéma de comptage Mathcad reste à déterminer, donc pas de compte d'octets.

ctl- $ entre l'opérateur de sommation (Sigma), y compris les espaces réservés vides pour mettre la variable de somme, la valeur initiale, la valeur finale et l'expression. Nombre approximatif équivalent en octets = 11.


où est le code?
Abr001am

1
Le "code" du défi réel est le premier signe de sommation (majuscule Sigma) que vous voyez sous le titre "Solution difficile". Les autres bits de "code" sont donnés dans la rubrique "Variantes de solution". Ce que vous voyez dans l'image correspond exactement à ce qui est écrit dans une feuille de calcul Mathcad: Mathcad utilise des symboles mathématiques pour diverses opérations, telles que la somme ou le produit vectoriel, l'intégration ou la différenciation de fonctions ou les opérations logiques. La plupart des opérateurs peuvent être entrés avec une combinaison de touches (par exemple, ctl-4 pour une somme vectorielle implicite ou ctl- & pour une somme itérée), ou via un menu ou une barre d'outils.
Stuart Bruff

4

PostgreSQL, 67 66 octets

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

SqlFiddleDemo

Contribution: VALUES(side, multiplier)


MODIFIER:

Entrée déplacée vers la table, tous les cas en même temps:

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

SqlFiddleDemo

Sortie:

╔══════╦══════╦══════════════════════╗
║  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 octets

Sest la longueur du côté, et Mest le multiplicateur.

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

3

Python, 40 octets

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

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

Dans les langues normales, utiliser une formule serait plus court. J'ai utilisé map car dans esolangs les cartes seraient plus courtes.
Leaky Nun

Où est le barré?
Leaky Nun

@KennyLau Je travaillais toujours sur ma réponse, j'ai posté ceci avant de voir votre commentaire.
Orlp

Très bien, (il en reste 7 de plus ...)
Leaky Nun

3

Ruby: 39 octets

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

Tester:

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

Quand Ruby a-t-il eu une sumfonction ??? C'est un changement de jeu
Value Ink,

Oh non! Ce que je pensais être une méthode de base ruby ​​est en fait une méthode de rails face triste . J'ai mis à jour la réponse.
br3nt

Pouvez-vous simplement changer votre langue en Rails? Je ne connais aucune importation dont vous pourriez avoir besoin pour cela
Value Ink

3

Python, 41 octets

Totalement nouveau dans cette affaire de golf, la critique est la bienvenue!

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

C'est en fait assez bon; )
user6245072

Haha merci. Je devais google comment faire des lambdas en python à nouveau, puisque je n’ai pas touché au python depuis un moment.
Lang Tran

Bienvenue dans Programming Puzzles & Code Golf! C'est une bonne réponse, mais elle est assez similaire à celle-ci .
Dennis

Ah, je n'ai pas vu s'il y avait d'autres solutions. A-t-il économisé un octet en faisant l**lce que j'ai fait?
Lang Tran

l*l en fait, ce qui est plus court que l**2 .
Dennis

2

Jolf, 18 15 10 octets

Merci à Cᴏɴᴏʀ O'Bʀɪᴇɴ pour avoir économisé 3 octets et m'avoir orienté vers la cartographie

uΜzQjd^JwH

Essayez-le ici!

 Μ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

Bon travail! Vous pouvez supprimer le a avant le zeta, car cela est implicitement supprimé. Vous pouvez également utiliser Mu (map) au lieu de pour chacun, et je pense que vous pouvez remplacer le D par ad et supprimer la fin}.
Conor O'Brien

1
@ Cᴏɴᴏʀ O'Bʀɪᴇɴ Neat, continuez d'oublier les parties implicites de Jolf, elles sont certainement l'une des meilleures façons de réduire quelques octets.
gonfle

2

CJam , 9 octets

q~2#,f#:+

Les entrées sont dans l'ordre inverse, séparées par une nouvelle ligne ou un espace.

Essayez-le en ligne!

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 octets

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

Ceci utilise simplement la formule de somme pour montrer la valeur, après avoir vérifié si le multiplicateur est 1 (ce qui retourne NAN dans la formule).


2

Mathematica, 22 octets

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

Crée une plage de {1, 2, ... s^2}, soustrait 1 dessus pour faire {0, 1, ..., s^2-1}. Ensuite, élevez chacun au pouvoir de mfaire {m^0, m^1, ..., m^(s^2-1)}et retournez la somme.

Mathematica peut également utiliser la formule explicite en prenant sa limite. Cela nécessite 29 octets.

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

Vous pouvez écrire votre première version en tant queTr[#^Range[#2^2]/#]&
Simon Woods

1

PARI / GP , 25 octets

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

Plus long mais plus rapide (35 octets):

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

Mignon (30 octets):

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


1

Lua, 54 47 octets

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

Exécuter à partir de la ligne de commande avec la longueur du côté du tableau comme premier argument et le multiplicateur comme second.

Merci à user6245072 pour la sauvegarde de 6 octets et à Katenkyo pour la sauvegarde de 1 supplémentaire.


Version originale de 54 octets:

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

renommer d enregistre un octet car il permet de sauter l’espace dans c=1 d=1=> a,b=...c=1g=1 for i=2,a^2 do c=c*b g=g+c end print(g). Si la suggestion de @ user6245072 fonctionne, vous pouvez enregistrer un octet sur le même principe =>r=0l,m=...for i=0,l^2 do r=r+m^i end print(r)
Katenkyo

Les espaces entre r=0et l,m=...sont de toute façon obligatoires, donc ils ne changent pas. Aussi la boucle devrait être for i=0,l^2-1mais c'est de ma faute lol.
user6245072

1

, 11 caractères / 14 octets

⨭⩥ î²)ⓜⁿ⁽í$

Try it here (Firefox/WebKit Nightly only).

Oui, fonctionne maintenant dans WebKit Nightly! Le support de Chrome est le suivant.

Explication

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

1

RETOUR , 32 octets

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

Try it here.

Lambda anonyme qui laisse le résultat sur Stack2. Usage:

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

Explication

[                              ]!  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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.