Римські армійські щити


26

Повідомлення в пісочниці (видалено)

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

Історія розповідає, що римський генерал заявив, що найкраща форма формації - площа (однакова кількість легіонерів у рядах та колонах). Проблема полягала у з'ясуванні, на скільки формувань (і чисельність) він повинен розбити свою армію, щоб:

  • Не залишайте жодного легіонера поза формацією (хоча він визнав єдину легіонерську формацію)
  • Зменшіть кількість необхідних щитів

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


Приклад:

Якщо 35 легіонерів в його армії, формація складалася в

  • Площа легіонерів 5х5 (Це найбільший можливий квадрат).

З рештою легіонерами (10)

  • Площа 3х3

З рештою легіонерами (1)

  • Квадрат 1х1.

Наприкінці це буде виглядати приблизно так:

   5x5      
* * * * *        3x3            
* * * * *       * * *      1x1  
* * * * *       * * *       *
* * * * *       * * *       
* * * * *               

Легіонери на внутрішніх позиціях накривали верхню частину, розміщуючи щит над головою . Їм знадобився лише 1 щит.

* * * * *                   
* 1 1 1 *       * * *       
* 1 1 1 *       * 1 *       *
* 1 1 1 *       * * *       
* * * * *               

Легіонери на флангах несли 2

* 2 2 2 *                   
2 1 1 1 2       * 2 *       
2 1 1 1 2       2 1 2       *
2 1 1 1 2       * 2 *       
* 2 2 2 *               

Якщо хтось був у кутку, у нього було 3 щита

3 2 2 2 3               
2 1 1 1 2       3 2 3       
2 1 1 1 2       2 1 2       *
2 1 1 1 2       3 2 3       
3 2 2 2 3               

Якщо хтось був один у формації, у нього було 5 щитів

3 2 2 2 3               
2 1 1 1 2       3 2 3       
2 1 1 1 2       2 1 2       5
2 1 1 1 2       3 2 3       
3 2 2 2 3               

Для цього формування потрібно було всього 71 щит.


Виклик

  • Обчисліть кількість щитів, необхідних для X кількості легіонерів

Вхідні дані

  • Кількість легіонерів в армії

Вихідні дані

  • Необхідна кількість щитів.

Випробування

35 => 71
20 => 44
10 => 26
32 => 72


11
Ну і результат Google за "перенесенням 5 щитів", Amazon.com : Best-selling Nipple Shield Carrying Case, Perfect...тому я думаю, я ніколи не дізнаюся справді. Вони насправді несли 5 щитів - чи це було для того, щоб питання спрацювало: P?
Чарівний восьминога Урна

1
@MagicOctopusUrn Я впевнений, що ти знаєш відповідь xD Я не думаю, що хтось має кишки вийти у бій з 5 щитами
Луїс Феліпе Де Ісус Муноз

4
Я не вважаю, що математика генерала є правильним для того, щоб зробити висновок, що багаторазове взяття найбільшого можливого квадрата мінімізує екрани. Наприклад, 32 легіонери можуть розділитись на два квадрати 4 * 4 на 64 загальних щити, а не на квадрати 5 * 5 + 2 * 2 + 1 * 1 + 1 * 1 + 1 * 1 на 72 загальних щити.
xnor

6
@xnor Можливо, в загальному випадку генерал був неправий, але загальний - це загальне (хоча ми не повинні узагальнювати).
pajonk

2
@AJFaraday Asterix та корисливі барсуки ?
Кріс Х

Відповіді:


14

Python 2 , 60 50 48 байт

def f(s):n=s**.5//1;return s and(n+4)*n+f(s-n*n)

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

Новий в коді гольф, але даю йому найкращий хит!

Спосіб:

Сума n^2 + 4nдеn кожне з найбільших квадратних чисел, яке дорівнює вхідному.

Редагуйте 1

Зменшено до 50 байт завдяки @Jonathan Frech!

Редагувати 2

Switched int(s**.5)для , s**.5//1щоб зберегти 2 байти завдяки @ovs


8
Ласкаво просимо до PPCG!
Luis felipe De jesus Munoz

2
Я думаю, що n*nце коротше, ніж n**2заощадити два байти; більше того я не можу сказати, оскільки не пишу python ...
Джузеппе


2
int(s**.5)можна скоротити до s**.5//1.
ов

2
@mypetlion Це так. //це поділ підлоги в обох Python 2 і 3. 3**.5//1оцінюється 1.0в обох версіях.
ов

11

R , 51 50 байт

f=function(x,y=x^.5%/%1)"if"(x,y^2+4*y+f(x-y^2),0)

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

Квадрат бічної довжини повинен мати рівно y 2 + 4 y екрани. Ми зменшимо на найбільший квадрат менше або дорівнює x до xyy2+4yxx не дорівнює нулю, накопичуючи кількість щитів, як ми йдемо.

Доказ:

y(y2)2y2(y2)2y=1y2+4y що, на щастя, також дає правильне значення5y=1y


y24y

1
@ToddSewell впевнений, що це пояснення Arnauld в , і це набагато елегантніше, але це шлях , я підійшов до нього, так що я приклеїти до нього! На щастя, це не запитання про гольф.
Джузеппе

10

JavaScript (ES7), 34 байти

f=n=>n&&(w=n**.5|0)*w+w*4+f(n-w*w)

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

Як?

w=nsw

sw=w2+4w

w=3

(323212323)=(s3=21)(111111111)+(3²=9)(111000000)+(001001001)+(000000111)+(100100100)(4×3=12)

w=1s1=5



4

Джулія 0,6 , 36 байт

!n=(s=isqrt(n))*s+4s+(n>0&&!(n-s*s))

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

н2+4н(н-2)(н-2)(н-2)2н-2 солдатів кожен, кожен з 2 щитами - так, що додає 4(н-2)2щити. Нарешті, в чотирьох кутах є три 3-х, так що додається 12 екранів.

(н-2)2+4(н-2)2+43=н2+4-4н+8н-16+12=н2+4н

Безголівки:

!n = begin       # Assign to ! operator to save bytes on function parantheses
  s = isqrt(n)   # Integer square root: the largest integer m such that m*m <= n
  s * s +
    4 * s +
      (n > 0 &&  # evaluates to false = 0 when n = 0, otherwise recurses
        !(n - s * s))
end

(Це також можна зробити в 35 байтах за допомогою n>0?(s=isqrt(n))*s+4s+f(n-s*s):0, але я написав це для Julia 0.7, хотів уникнути нових попереджень про депресію (вимагаючи пробілів ?і :).)


Ще одне надскладне пояснення щодо кількості щита, дивіться у моєму коментарі до відповіді @ Джузеппе.
Тодд Сьюелл

2
@ToddSewell Так, площа + периметр - це більш елегантний спосіб поглянути на це. Я цього не зробив, але подібно до Джузеппе мій намір полягає в тому, щоб описати свій підхід, ніж дати найновіший доказ формули.
sundar


3

Брахілог , 26 байт

0|⟧^₂ᵐ∋N&;N-ℕ↰R∧N√ȧ×₄;N,R+

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

0           % The output is 0 if input is 0
|           % Otherwise,
⟧           % Form decreasing range from input I to 0
^₂ᵐ         % Get the squares of each of those numbers
∋N          % There is a number N in that list
&;N-ℕ       % With I - N being a natural number >= 0 i.e. N <= I
            % Since we formed a decreasing range, this will find the largest such number
↰           % Call this predicate recursively with that difference I - N as the input
R           % Let the result of that be R
∧N√ȧ        % Get the positive square root of N
×₄          % Multiply by 4
;N,R+       % Add N and R to that
            % The result is the (implicit) output

2

Сітківка 0,8,2 , 28 байт

.+
$*
(\G1|11\1)+
$&11$1$1
.

Спробуйте в Інтернеті! Посилання включає тестові випадки. Пояснення:

.+
$*

Перетворити в десятковий.

(\G1|11\1)+

Збіг непарних чисел. Першого проходу через групу \1ще не існує, тому \G1може відповідати лише той , який відповідає 1. Подальші матчі не можуть відповідати, \G1оскільки \Gлише матчі на початку матчу, тож натомість ми маємо відповідати тому, 11\1що на 2 більше попередній матч. Ми співставляємо стільки непарних чисел, і тому загальна відповідність - це квадратне число, тоді як останнє захоплення - це менше, ніж удвічі більше його сторони.

$&11$1$1

Додайте бічні щити до кожного матчу. $&єн2і $1є2н-1 поки нам потрібно н2+4н=н2+2+2(2н-1).

.

Підсумовуйте та конвертуйте в десяткові.


2

05AB1E , 17 байт

[Ð_#tïÐns4*+Šn-}O

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

Подолання, тому що ΔDtïÐns4*+Šn-}O( 15 байт ), схоже, не працює. Спробуйте в режимі налагодження в Інтернеті, щоб побачити, що я маю на увазі. Я очікував би , щоб перейти від [45,'35',25]до [45,10]після -і наступної ітерації Δ, але , мабуть , вона очищає стек для останнього значення , за винятком , і стає [10], в результаті 0 в самому кінці .. Не впевнений , якщо це призначено поведінку або помилка .. (EDIT: Це призначено, див. Знизу.)

Пояснення:

Також використовує ш2+4ш де ш - ширина в циклі, як і більшість інших відповідей.

[        }     # Start an infinite loop:
 Ð             #  Triplicate the value at the top of the stack
  _#           #  If the top is 0: break the infinite loop
 t             #  Take the square-root of the value
               #   i.e. 35 → 5.916...
  ï            #  Remove any digits by casting it to an integer, so we have our width
               #   i.e. 5.916... → 5
   Ð           #  Triplicate that width
    n          #  Take the square of it
               #   i.e. 5 → 25
     s         #  Swap so the width is at the top again
      4*       #  Multiply the width by 4
               #   i.e. 5 → 20
        +      #  And sum them together
               #   i.e. 25 + 20 → 45
 Š             #  Triple-swap so the calculated value for the current width
               #  is now at the back of the stack
               #   i.e. [35,5,45] → [45,35,5]
  n            #  Take the square of the width again
               #   5 → 25
   -           #  Subtract the square of the width from the value for the next iteration
               #   i.e. 35 - 25 → 10
          O    # Take the sum of the stack
               #   i.e. [45,21,5,0,0] → 71

EDIT: Мабуть, призначена поведінка, яку я описав вище Δ. Ось дві 17- байтові альтернативи, надані @ Mr.Xcoder , які використовують Δ, додаючи значення в global_array (з ^) та отримуючи їх знову після (з ¯):

ΔЈtïnα}¯¥ÄDt··+O

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

ΔЈtïnα}¯¥ÄtD4+*O

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


2

DC , 25 байт

d[dvddSa*-d0<MLa+]dsMx4*+

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

Обчислює екрани як sum(n^2)(оригінальне число) плюс 4*sum(n), натискаючи копію кожної квадратної довжини сторони в регістр стека aв aміру проходження , а потім додаючи всі значення з регістру, коли рекурсія "розгортається".





1

PHP , 67 байт

<?for($n=$argv[1];$w=(int)sqrt($n);$n-=$w**2)$a+=$w**2+$w*4;echo$a;

Щоб запустити його:

php -n <filename> <n>

Приклад:

php -n roman_army_shields.php 35

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


Використовуючи -Rопцію, ця версія становить 60 байт :

for(;$w=(int)sqrt($argn);$argn-=$w**2)$a+=$w**2+$w*4;echo$a;

Приклад:

echo 35 | php -nR "for(;$w=(int)sqrt($argn);$argn-=$w**2)$a+=$w**2+$w*4;echo$a;"

(в Linux замінити "на ')


Примітка. Це з використанням чудової формули відповіді Арнальда, я не зміг знайти нічого коротшого за це.


1

Pyth , 19 байт

Рекурсивна функція, яку слід викликати за допомогою y(див. Посилання).

L&b+*Ks@b2+4Ky-b^K2

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

Pyth , 21 байт

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

sm*d+4deeDsI#I#@RL2./

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

Пояснення

sm*d+4deeDsI#I#@RL2./ Повна програма, назвемо вхідний Q.
                   ./ Цілі розділи Q. Дає всі комбінації додатного
                          цілі числа, що складаються з Q.
               @ RL2 Візьміть квадратний корінь усіх цілих чисел кожного розділу.
             Я # Майте лише ті розділи, які є інваріантними під:
          sI # Відхилення всіх не цілих чисел. Це в основному тільки зберігає
                          перегородки, сформовані повністю з ідеальних квадратів, але
                          замість того, щоб мати самі квадрати, ми маємо їх коріння.
       eeD Отримайте розділ (скажімо, P) з найвищим максимумом.
 м для кожного d у P ...
  * d + 4d ... Вихід d * (d + 4) = d ^ 2 + 4d, формула, яка використовується у всіх відповідях.
s Підсумуйте результати цього відображення та неявно виведіть.

1

Швидкий 4 , 111 99 84 78 байт

func f(_ x:Int)->Int{var y=x;while y*y>x{y-=1};return x>0 ?(y+4)*y+f(x-y*y):0}

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

Це відчуття при ручній реалізації цілого квадратного кореня набагато коротше, ніж вбудований ...

Необов’язаний і пояснений

// Define a function f that takes an integer, x, and returns another integer
// "_" is used here to make the parameter anonymous (f(x:...) -> f(...))
func f(_ x: Int) -> Int {

    // Assign a variable y to the value of x

    var y = x

    // While y squared is higher than x, decrement y.

    while y * y > x {
        y -= 1
    }

    // If x > 0, return (y + 4) * y + f(x - y * y), else 0.

    return x > 0 ? (y + 4) * y + f(x - y * y) : 0
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.