Проблема рису та шахів


41

Індійська легенда розповідає історію про передбачуваного винахідника гри в шахи, який вразив імператора Індії своєю грою настільки, що він отримав би нагороду за все, що просять.

Чоловік сказав, що хоче платити за рис. Він хотів зерна рису для першого квадрата шахової дошки, двох для другого, чотирьох для третього, восьмого для четвертого тощо, аж до 64-ї площі.

Імператор був вражений тим, що чоловік попросив таку маленьку винагороду, але, оскільки його математики почали рахувати, він закінчив втратити одну зі своїх провінцій.

Завдання

Враховуючи довжину сторони гіпотетичної шахової дошки (яка становить 8 на шаховій дошці за замовчуванням) та множник між квадратами (що в легенді 2), обчисліть кількість зерен рису, які імператор повинен заплатити людині.

Примітки

  • Бічна довжина завжди буде додатним цілим числом. Натомість множник може бути будь-яким раціональним числом.

  • Якщо ваша обрана мова не може відображати дуже великі цифри, це добре, поки ваша програма може правильно обробляти менші вводи.

  • Також якщо ваша мова вибору округляє більші значення (з експоненціальними позначеннями), добре, якщо ці значення є приблизно правильними.

Тестові шафи

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

Зверніть увагу, що явна формула

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

Виконує неправильно multiplier = 1, як

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

Оцінка балів

Це код-гольф. Найкоротша відповідь у байтах виграє.


4
Ви, мабуть, хочете тестовий випадок, коли множник дорівнює 1, а інший, де він дорівнює 0 (якщо обидва є дійсними). Крім того, "що-небудь" досить широке, чи вважається квадратний корінь від'ємного? Як щодо "картоплі"? ;) Я б рекомендував "будь-яку реальну кількість" чи щось таке.
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 inputsОбережно, що викликало проблеми в минулому. meta.codegolf.stackexchange.com/a/8245/31716
DJMcMayhem

24
... це, мабуть, було багатим провінцією, бо навіть сьогодні щорічне світове виробництво рису все ще менше 2 ^ 64 зерна.
vsz

1
@vsz Власне, хлопця вбили. Сума, додана королю, віддала чоловікові все царство, тож, природно, було взято простіший вихід.
cst1992

1
@ cst1992 версія, яку я прочитав, говорить, що чоловік відмовився від свого прохання і отримав провінцію в подарунок.
user6245072

Відповіді:


23

Желе , 4 байти

²b1ḅ

Для цього використовується підхід з розумної відповіді на APL @ APLDude .

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

²b1ḅ  Main link. Arguments: x (side length), y (multiplier)

²     Square; yield x².
 b1   Convert to base 1 (unary), yielding a list of x² ones.
   ḅ  Convert from base y to real number.
      This yields y^(x²-1) + ... + y + 1.


23

APL, 10 байт

⎕⊥1+0×⍳⎕*2

використовується для читання вводу користувача двічі. Якщо ми збережемо бічну довжину в s, а множник у m , отримаємо наступний код.

m⊥1+0×⍳s*2

Ось як APL аналізує цей код:

Пояснення алгоритму


4
Або як функціональний потяг: ⊣⊥1⍴⍨⊢×⊢(8 байт) Як інтерактивна команда REPL, ⎕⊥×⍳⎕*2так само працює (7 байт).
Денніс

19

Пітон, 40 байт

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

Створює та оцінює такий собі рядок

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

що кодує суму як хронізований многочлен з доданкамиn*n .

Дуже багато методів дало дуже схоже число байтів:

#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
Ага так, мій поганий. У будь-якому разі, мені дуже подобається бачити всі різні підходи, які ви взяли :)
FryAmTheEggman


11

Haskell, 25 байт

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

Підсумовує список [m^0, m^1, ..., m^(n*n-1)].


11

JavaScript (ES2016 / ES7), 31 29 28 байт

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

Просто @Bassdrop Cumberwubwubwub та версія ES6 @ Kaizo ES6, але з оператором експоненції. :) (Я не мав достатньо репутації, щоб коментувати замість цього.)

Редагувати: /+(b-1)змінено на /--b(дякую @Neil).

Редагувати: зараз використовується currying (спасибі @MamaFunRoll).


Ласкаво просимо до PPCG! Ваша відповідь досить гарна!
NoOneIsHere

Ласкаво просимо! +Оператор був тест , який я забув відредагувати, так що ви можете збрити 1 байт, опускаючи його :)
Bassdrop Cumberwubwubwub

Формула не працює для m = 1: 3
user6245072

@ user6245072 ти на хромовому канарі? Або на вузол? Якщо на вузлі, увімкніть прапор гармонії
NiCk Newman

Врятували б /--bвас байт чи два?
Ніл



8

Javascript ES6, 59 37 35 34 байт

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

Дякуємо @Kaizo за те, що голили цілих 19 байт, @Neil ще 2 та @gcampbell ще на 1!

Спробуйте тут

Альтернативні зламані версії

32 байти

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

Причини NaNдля b==1.

30 байт

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

Причини Infinityдля b==1.5.

28 байт

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

Виходи 1для деяких дійсних тестів.

Стара версія на 59 байт

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


Чому ви просто не обробили випадок b == 1 у випадку з 32 байтами? 40 байт: (a, b) => b-1? (Math.pow (b, a * a) -1) / (b-1): a * a
Кайзо

@Kaizo ти прав, я ідіот: D
Bassdrop Cumberwubwubwub

/~-bочевидно, це не добре для дробових b, але /--bмає працювати, ні?
Ніл

До речі, я переграв стару версію до 47 байт:(a,b)=>[...Array(a*a-1)].reduce(s=>s+=p*=b,p=1)
Ніл

@Neil, ти прав, звичайно. Ось що ви отримуєте, коли поспішаєте на свої відповіді: p Дякую!
Bassdrop Cumberwubwubwub

6

Java, 132 байти

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

Безумовно

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

Примітки

  • Це буде працювати для довільно великих виходів, як того вимагає ОП (Шкода, що Java підтримує великі числа, інакше це буде коротше).

Виходи

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 байт

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

Пояснення:

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


4

Haskell, 30 байт

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

або однаково довго

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

Перша версія починається з 1багаторазового множення m. Тоді він підсумовує перші n^2числа цієї послідовності. Друга версія - це чітка формула, як це видно в інших відповідях.


Ви не можете просто зробити n#m=sum$(m^)<$>[0..n*n-1]?
xnor

@xnor: о, це приємно. Я думаю, що це достатньо інакше для окремої відповіді. Будь ласка, опублікуйте його самостійно.
німі

4

J, 10 байт

+/@:^i.@*:

Використання

Я позначаю кілька цілих чисел xсуфіксом для використання розширених цілих чисел для отримання точних результатів.

   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

Пояснення

+/@:^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 байтів #.*:$*за APL чувак.
FrownyFrog

4

Mathcad, [tbd] байт (~ 11)

введіть тут опис зображення

Використовує вбудований оператор підсумовування Mathcad. Також демонструється символічне спрощення процесора для створення точної формули.

Mathcad ефективно працює два двигуни обробки паралельно - один стандартний плаваючою точкою IEEE 64/80, а другий символічний процес довільної чисельності (MuPad). Стандартне числове оцінювання позначається знаком рівності (=), а стрілка праворуч - символічною оцінкою.


Схема підрахунку Mathcad ще не визначена, тому кількість байтів не задана.

ctl- $ входить до оператора підсумовування (Sigma), включаючи порожні заповнювачі, щоб поставити змінну підсумовування, початкове значення, кінцеве значення та вираз. Орієнтовна кількість байтових еквівалентів = 11.


де код?
16:00

1
"Код" для фактичного виклику - це перший знак підсумовування (велика столиця Sigma), який ви бачите під заголовком "Рішення виклику". Інші біти "коду" наведені під заголовком "Варіанти рішення". Те, що ви бачите на зображенні, саме те, що записується на робочий аркуш Mathcad - Mathcad використовує математичні символи для різних операцій, таких як векторна сума чи продукт, інтеграція чи диференціація функцій або логічні операції. Більшість операторів можуть бути введені за допомогою комбінації клавіш (наприклад, ctl-4 для неявної векторної суми або ctl- & для ітераційної суми) або через меню або панель інструментів.
Стюарт Брюф

4

PostgreSQL, 67 66 байт

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

SqlFiddleDemo

Вхід: VALUES(side, multiplier)


Редагувати:

Введення переміщено до таблиці, всі випадки одразу:

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

SqlFiddleDemo

Вихід:

╔══════╦══════╦══════════════════════╗
║  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 байт

S- це бічна довжина і Mє множником.

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

3

Пітон, 40 байт

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

1
lambda l,m:(m**(l*l)-1)/(m-1)
Лина монашка

У звичайних мовах використання формули було б коротшим. Я використовував карту, оскільки в езолангах карти будуть коротшими.
Leaky Nun

Де закреслене?
Leaky Nun

@KennyLau Я все ще працював над своєю відповіддю, опублікував це, перш ніж побачити ваш коментар.
orlp

Гаразд, (ще ​​7…)
Лина монашка

3

Рубін: 39 байт

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

Тест:

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

Коли Рубі отримала sumфункцію ??? Це змінюється в грі
Value Ink

О ні! Те, що я вважав методом рубінового ядра, - це насправді метод рельсів сумного обличчя . Я оновив відповідь.
br3nt

Чи можете ви просто змінити мову на Rails? Я не знаю про будь-який імпорт, який вам може знадобитися
Value Ink

3

Пітон, 41 байт

Зовсім нове в цій справі з гольфу, вітаємо критику!

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

Це насправді досить добре; )
користувач6245072

Ха-ха, дякую. Мені довелося google, як робити лямбда з python знову, оскільки я вже не торкався python.
Ланг Тран

Ласкаво просимо до головоломки програмування та коду для гольфу! Це приємна відповідь, але досить схожа на цю .
Денніс

Ах, я не бачив, чи є інші рішення. Він врятував байт, зробивши l**lзамість того, що я зробив?
Ланг Тран

l*lнасправді, що коротше, ніж l**2.
Денніс

2

Джольф, 18 15 10 байт

Дякую Cᴏɴᴏʀ O'Bʀɪᴇɴ за збереження 3-х байт та спрямованість мене на картування

uΜzQjd^JwH

Спробуйте тут!

 Μ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

Хороша робота! Ви можете видалити a до zeta, оскільки це неявно відключено. Ви також можете використовувати Mu (карту) замість кожного, і я думаю, ви можете замінити D на рекламу та видалити закінчення}.
Conor O'Brien

1
@ Cᴏɴᴏʀ O'Bʀɪᴇɴ Охайно, не забувай про неявні частини Джольфа, вони, безумовно, одні з найкращих способів відголити кілька байтів.
набрякає

2

CJam , 9 байт

q~2#,f#:+

Вводи в зворотному порядку розділені новою лінією або пробілом.

Спробуйте в Інтернеті!

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 байти

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

Це просто використовує формулу підсумовування, щоб показати значення, перевіривши, чи є множник 1 (який повертає NAN у формулі).


2

Математика, 22 байти

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

Створює діапазон {1, 2, ... s^2}, віднімає 1 над ним, щоб зробити {0, 1, ..., s^2-1}. Потім піднесіть кожного до сили mвиготовлення {m^0, m^1, ..., m^(s^2-1)}і поверніть його суму.

Альтернативно, Mathematica може використовувати явну формулу, приймаючи її межа. Для цього потрібно 29 байт.

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

Ви можете написати свою першу версію якTr[#^Range[#2^2]/#]&
Simon Woods

1

PARI / GP , 25 байт

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

Більше, але швидше (35 байт):

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

Симпатичний (30 байт):

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


1

Луа, 54 47 байт

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

Запустіть з командного рядка довжину сторони дошки як перший аргумент, а множник як другий.

Завдяки user6245072 за збереження 6 байтів, а Katenkyo за збереження додаткового 1.


Оригінальна версія 54 байтів:

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

Привіт, і ласкаво просимо до PPCG! Чудова відповідь!
NoOneIsHere

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

Це має зберегти кілька байт.
user6245072

перейменування d зберігає один байт, оскільки дозволяє пропустити простір у c=1 d=1=> a,b=...c=1g=1 for i=2,a^2 do c=c*b g=g+c end print(g). якщо пропозиція @ user6245072 працює, ви можете зберегти байт за тим самим принципом =>r=0l,m=...for i=0,l^2 do r=r+m^i end print(r)
Katenkyo

Пробіл між r=0і l,m=...все одно є обов'язковим, тому він не змінюється. Також цикл повинен бути, for i=0,l^2-1але це моя вина, хаха.
user6245072

1

𝔼𝕊𝕄𝕚𝕟, 11 символів / 14 байт

⨭⩥ î²)ⓜⁿ⁽í$

Try it here (Firefox/WebKit Nightly only).

Так, 𝔼𝕊𝕄𝕚𝕟 зараз працює у WebKit Nightly! Наступна підтримка Chrome.

Пояснення

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

1

ПОВЕРНЕННЯ , 32 байти

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

Try it here.

Анонімна лямбда, яка залишає результат на Stack2. Використання:

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

Пояснення

[                              ]!  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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.