Roma Ordusu Kalkanları


26

Sanal alan yayını (silindi)

Eski Roma ordusu oluşumları dünya çapında çok ünlüdür. Bu oluşumlarda, Roma lejyonerleri, yanları ve kalkanlarını kullanarak üst kısımlarını koruyan geometrik bir biçimde (genellikle bir dikdörtgen) gruplanmıştır. İç pozisyonlardaki lejyonerler kalkanlarını başlarının üstünde tutan üst kısmı, yanlarda bulunan lejyonerleri 2 veya daha fazla kalkan taşıyorlardı: biri üstün kısmı korumak için, diğeri ise kenarları korumak için bir veya daha fazla kalkan 3 kalkan vardı, eğer biri oluşum halinde yalnız olsaydı, 5 kalkanı vardı Evet, bir insanın 5 kalkan taşımasının imkansız olduğunu biliyorum, ama bir şekilde yaptılar ). Bu oluşumun kullanılmasıyla tüm roman lejyonları kendilerini korudular ve o zaman en zor rakiplerdi.

Tarih, en iyi oluşum şeklinin kare olduğunu söyleyen bir Roma generali olduğunu söylemektedir (satır ve sütunlarda aynı sayıda lejyoner). Buradaki sorun, ordusunu aşağıdakileri yapmak için ordusunu bölmesi gerektiğini (ve boyutlarını) bulmaktı.

  • Herhangi bir lejyon oluşumunu bırakmadı (tek lejyon oluşumunu kabul etmesine rağmen).
  • Gerekli kalkan miktarını azaltın

General, bazı matematik ve hesaplamaları yaptıktan sonra, bu 2 koşulu yerine getirmenin en iyi yolunun mümkün olan en büyük kareyle başlamak olduğunu ve daha sonra hiçbir lejyoner kalmayana kadar tekrar ettiğini buldu .


Örnek:

Ordusunda 35 lejyon varsa,

  • 5x5 lejyonerler karesi (Bu, mümkün olan en büyük karedir).

Kalan lejyonerler ile (10)

  • 3x3 kare

Kalan lejyonerler ile (1)

  • 1x1 kare.

Sonunda böyle bir şey görünecek:

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

İç pozisyondaki lejyonerler kalkanlarını başlarının üstünde tutan üstün kısmı kapladılar . Sadece 1 siper gerekliydi.

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

Yan kanatlarda bulunan lejyonerler 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 *               

Köşede biri varsa 3 kalkanı vardı.

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               

Biri oluşumunda yalnız olsaydı, 5 kalkanı vardı.

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               

Bu oluşum toplam 71 kalkan gerektiriyordu.


Meydan okuma

  • X miktarındaki lejyoner için gereken kalkan miktarını hesapla

Giriş

  • Ordudaki lejyoner miktarı

Çıktı

  • Gereken kalkan miktarı.

Test Kılıfları

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

  • Standart kuralları geçerlidir

11
"5 kalkan taşıma" nın google sonucu, Amazon.com : Best-selling Nipple Shield Carrying Case, Perfect...sanırım asla gerçekten bilemeyeceğimden. Aslında 5 kalkan taşıdılar mı ya da soruyu çalıştırmak için yaptım: P?
Magic Octopus Urn,

1
@MagicOctopusUrn xD cevabını bildiğinizden eminim xD Birinin 5 kalkanla kavga edecek cesareti olduğunu sanmıyorum
Luis felipe De jesus Munoz

4
Generalin matematiği yok ve hesaplamalar, mümkün olan en büyük kareyi tekrar tekrar almanın kalkanları en aza indirdiği sonucuna varmak doğru değil. Örneğin, 32 lejyoner, toplam kalkanlar için 5 * 5 + 2 * 2 + 1 * 1 + 1 * 1 + 1 * 1 kareler yerine 64 toplam kalkan için iki 4 * 4 kareye ayrılabilir.
xnor

6
@xnor Belki genel durumda, genel doğru değildi, fakat genel (genel değil olmamıza rağmen) geneldir.
pajonk

2
@AJFaraday Asteriks ve paralı porsuklar ?
Chris H,

Yanıtlar:


14

Python 2 , 60 50 48 bayt

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

Çevrimiçi deneyin!

Golf kodunda yeni, ama elimden gelenin en iyisini yapıyor!

Yöntem:

Toplamı , girişe toplanan en büyük kare sayıların n^2 + 4nnerede nolduğu.

Düzenle 1

@ Jonathan Frech! Sayesinde 50 byte'a düşürüldü!

Düzenle 2

Anahtarlı int(s**.5)için s**.5//12 byte @ovs sayesinde kaydetmek için


8
PPCG'ye Hoşgeldiniz!
Luis felipe De jesus Munoz

2
Sanırım iki bayt kurtarmaktan n*ndaha kısa n**2; python yazmadığım için söyleyemediğimden daha fazla ...
Giuseppe


2
int(s**.5)kısaltılabilir s**.5//1.
ovs

2
@ mypetlion Yapar. //hem Python 2 hem de 3'teki taban bölümüdür. Her iki versiyonda da 3**.5//1değerlendirir 1.0.
ovs

11

R , 5150 bayt

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

Çevrimiçi deneyin!

yy2+4yxx

Kanıt:

y(y2)2y2(y2)2y=1y2+4y5y=1y


y24y

1
Emin @ToddSewell, Arnauld açıklaması ve bir çok daha şık, ama bu bırakmaya niyetim yüzden, o yaklaştı yoldur! Neyse ki, bu bir kanıt golf soru değil.
Giuseppe

10

JavaScript (ES7), 34 bayt

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

Çevrimiçi deneyin!

Nasıl?

Her yinelemede genişliğini hesaplıyoruzw=nsw

sw=w2+4w

w=3

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

Formül için de geçerlidir olarak, .s 1 = 5w=1s1=5



4

Julia 0.6 , 36 bayt

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

Çevrimiçi deneyin!

Kullanımları aynı Giuseppe'nin R cevap @ gibi yöntem, benim yöntem daha az anlamlı düşünme ve daha adil gözle kontrol orada yer gelmesi gerçi: 1s iç kare boyutu vardır ile , öyle ki kalkan var. Bunu çevreleyen , her birinde 2 kalkan olan 4 adet asker duvarı vardır - böylece kalkan eklenir . Son olarak, dört köşede dört tane 3 var, böylece 12 kalkan ekleniyor.n2+4n(n2)(n2)(n2)2n24(n2)2

(n2)2+4(n2)2+43=n2+44n+8n16+12=n2+4n

Ungolfed:

!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

(Bu işlem aynı zamanda 35 baytta da yapılabilir n>0?(s=isqrt(n))*s+4s+f(n-s*s):0, ancak bunu Julia 0.7 için yeni amortisman uyarılarından kaçınmak istediğimi yazdım (boşluklar gerektiren ?ve :).


Kalkan sayısı için bir başka aşırı karmaşık açıklama, @ Giuseppe'nin cevabı üzerine yorumuma bakın.
Todd Sewell

2
@ToddSewell Evet, alan + çevre buna bakmak için daha şık bir yoldur. Yine de öyle yapmadım ve Giuseppe'ye benzer olarak niyetim yaklaşımımı tanımlamak, formülü en iyi şekilde kanıtlamak.
sundar - Monica'yı


3

Brachylog , 26 bayt

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

Çevrimiçi deneyin!

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

Retina 0.8.2 , 28 bayt

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

Çevrimiçi deneyin! Link, test durumlarını içerir. Açıklama:

.+
$*

Ondalık dönüştür.

(\G1|11\1)+

Tek sayıları eşleştir. Gruptaki ilk paso \1henüz mevcut değil, bu yüzden sadece 1 \G1ile eşleşen eşleşebilir. Sonraki maçlar sadece maçın başlangıcındaki maçlardan \G1beri \Geşleşemez, bu yüzden bunun yerine 11\12 olandan daha fazlasını eşleştirmeliyiz. önceki maç. Olabildiğince tuhaf rakamlarla eşleşiyoruz ve bu nedenle toplam eşleşme kare bir sayıdır, oysa son yakalama onun iki katından daha azdır.

$&11$1$1

$&n2$12n1n2+4n=n2+2+2(2n1)

.

Topla ve ondalık dönüştür.


2

05AB1E , 17 bayt

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

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

Pratikte çünkü ΔDtïÐns4*+Šn-}O( 15 byte ) çalışmıyor gibi görünüyor . Ne ​​demek istediğimi görmek için çevrimiçi hata ayıklama modunda deneyin. Ben gitmek için beklediğiniz [45,'35',25]için [45,10]sonra -ve sonraki yineleme Δ, ama görünüşe göre son değer hariç yığını temizler ve olur [10]bu davranış veya bir hata amaçlanmaktadır emin değil .. en sonunda 0 sonuçlanan .. (EDIT: Amaçlanmıştır, aşağıya bakınız.)

Açıklama:

w2+4ww

[        }     # 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: Görünüşe göre yukarıda açıklanan davranış için Δtasarlanmıştır. Burada global_array (with ) değerlerini koyarak ve sonra tekrar alarak (with ) kullanarak @ Mr.Xcoder tarafından sağlanan iki 17-bayt alternatif :Δ^¯

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

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

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

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .


2

dc , 25 bayt

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

Çevrimiçi deneyin!

Her kare kenar uzunluğunun bir kopyasını olduğu gibi yığın yazmacına iterek kalkanları sum(n^2)(orijinal sayı) artı olarak hesaplayın , ardından kayıt özdeyişlerini "unrolls" olarak kayıttan tüm değerleri ekleyin.4*sum(n)aa





1

PHP , 67 bayt

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

Çalıştırmak için:

php -n <filename> <n>

Örnek:

php -n roman_army_shields.php 35

Veya çevrimiçi deneyin!


Kullanımı -Rseçeneği, bu versiyonu 60 byte :

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

Örnek:

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

(Linux üzerinde yerini "ile ')


Not: Bu Arnauld'un cevap harika formülünü kullanıyor, ondan daha kısa bir şey bulamadım.


1

Pyth , 19 bayt

Kullanılması gereken tekrarlamalı fonksiyon y(bağlantıya bakınız).

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

Burada dene!

Pyth , 21 bayt

Revizyon tarihi oldukça komik, ancak çok daha hızlı bir sürüm istiyorsanız onu ziyaret ettiğinizden emin olun :)

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

Burada dene!

açıklama

sm*d+4deeDsI#I#@RL2./ Tam program, hadi Q girişini çağıralım.
                   ./ Q'nun tamsayı bölümleri. Pozitifin tüm kombinasyonlarını sağlar
                          Q ekleyen tamsayılar.
               @ RL2 Her bölümün tüm tam sayılarının karekökünü alın.
             Ben # Sadece değişmeyen bölümleri tut:
          sI # Tüm tam sayıların atılması. Bu temelde sadece tutar
                          Tamamen mükemmel karelerden oluşan bölümler, ancak
                          karelerin kendilerinin olması yerine, köklerine sahibiz.
       eeD En yüksek en yüksek bölmeyi alın (P deyin).
 m P'deki her d için ...
  * d + 4d ... Verim d * (d + 4) = d ^ 2 + 4d, tüm cevaplarda kullanılan formül.
s Bu haritalamanın sonuçlarını ve örtük olarak çıktılarını toplayın.

1

Swift 4 , 111 99 84 78 bayt

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}

Çevrimiçi deneyin!

Tamsayı karekök manüel olarak uygulandığı zaman bu yerleşikten çok daha kısadır.

Ungolfed ve Açıklaması

// 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
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.