โล่กองทัพโรมัน


26

โพสต์ Sandbox (ถูกลบ)

การก่อตัวของกองทัพโรมันที่โด่งดังไปทั่วโลก ในกองทหารโรมันเหล่านี้ก่อตัวเป็นรูปทรงเรขาคณิต (โดยปกติจะเป็นรูปสี่เหลี่ยมผืนผ้า) เพื่อปกป้องปีกและส่วนที่เหนือกว่าของมันโดยใช้โล่ของพวกเขา กองทหารที่อยู่ในตำแหน่งภายในครอบคลุมส่วนที่เหนือกว่าวางโล่ไว้เหนือหัวของพวกเขากองทหารที่อยู่ด้านข้างนั้นมีเกราะตั้งแต่สองโล่ขึ้นไปหนึ่งอันเพื่อปกป้องส่วนที่เหนือกว่าและหนึ่งหรือหลายโล่สำหรับปกป้องปีก เขามี 3 โล่ถ้ามีใครคนเดียวในขบวนเขามี 5 โล่ใช่ฉันรู้ว่ามันเป็นไปไม่ได้ที่มนุษย์จะมี 5 โล่ แต่อย่างใดพวกเขาก็ทำมัน ) การใช้รูปแบบนี้กองทหารโรมันทุกคนป้องกันตนเองและเป็นคู่ต่อสู้ที่ยากที่สุดในเวลานั้น

ประวัติศาสตร์บอกว่ามีนายพลโรมันที่ระบุว่ารูปร่างที่ดีที่สุดคือรูปสี่เหลี่ยม (กองทหารจำนวนเท่ากันในแถวและคอลัมน์) ปัญหาคือการหาจำนวนการก่อตัว (และขนาด) ที่เขาควรแบ่งกองทัพของเขาเพื่อ:

  • อย่าปล่อยกองทหารออกจากรูปแบบ (แม้ว่าเขาจะยอมรับกองทหารกองพลเดียว)
  • ลดจำนวนโล่ที่ต้องการ

โดยทั่วไปหลังจากทำการคำนวณและคำนวณทางคณิตศาสตร์แล้วเขาพบว่าวิธีที่ดีที่สุดในการบรรลุ 2 เงื่อนไขนี้คือเริ่มต้นด้วยสี่เหลี่ยมที่ใหญ่ที่สุดเท่าที่จะเป็นไปได้จากนั้นทำซ้ำจนกว่าจะไม่มีกองทหารเหลืออยู่


ตัวอย่าง:

หากกองทหาร 35 นายในกองทัพของเขาการก่อตัวประกอบด้วย

  • กองทหารราบ 5x5 (นี่คือจัตุรัสที่ใหญ่ที่สุดเท่าที่จะเป็นไปได้)

กับกองทหารที่เหลือ (10)

  • ตาราง 3x3

กับกองทหารที่เหลือ (1)

  • ตาราง 1x1

ในตอนท้ายมันจะมีลักษณะดังนี้:

   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 shields" เป็นAmazon.com : Best-selling Nipple Shield Carrying Case, Perfect...ดังนั้นฉันเดาว่าฉันจะไม่มีทางรู้ จริง ๆ แล้วพวกเขามีโล่ 5 ใบ - หรือนี่เพื่อทำให้คำถามใช้งานได้: P
Magic Octopus Urn

1
@ MagicOctopusUrn ฉันค่อนข้างแน่ใจว่าคุณรู้คำตอบ xD ฉันไม่คิดว่ามีใครกล้าพอที่จะออกไปต่อสู้กับ 5 shields
Luis felipe De jesus Munoz

4
ฉันไม่ได้คณิตศาสตร์และการคำนวณทั่วไปของมีสิทธิ์ที่จะสรุปว่าการซ้ำสี่เหลี่ยมที่ใหญ่ที่สุดที่เป็นไปได้ที่จำเป็นในการลดโล่ ตัวอย่างเช่น 32 กองทหารสามารถแบ่งออกเป็นสอง 4 * 4 สี่เหลี่ยมสำหรับ 64 โล่รวมมากกว่าสี่เหลี่ยม 5 * 5 + 2 * 2 + 1 * 1 + 1 * 1 + 1 * 1 1 1 สำหรับ 72 โล่รวม
xnor

6
@ xnor บางทีในกรณีทั่วไปทั่วไปไม่ถูกต้อง แต่ทั่วไปเป็นเรื่องทั่วไป (แม้ว่าเราไม่ควรพูดคุยทั่วไป)
pajonk

2
@AJFaraday Asterix และแบดเจอร์รับจ้าง ?
Chris H

คำตอบ:


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

เปลี่ยนint(s**.5)เป็นs**.5//1บันทึก 2 ไบต์ขอบคุณ @ovs


8
ยินดีต้อนรับสู่ PPCG!
Luis felipe De jesus Munoz

2
ฉันคิดว่าn*nสั้นกว่าที่n**2จะช่วยคุณสองไบต์ ยิ่งกว่านั้นฉันไม่สามารถพูดได้ตั้งแต่ที่ฉันไม่ได้เขียนหลาม ...
Giuseppe

2
50 ไบต์
Jonathan Frech

2
int(s**.5)s**.5//1สามารถลงไป
OVS

2
@mypetlion มันทำ //เป็นการแบ่งชั้นในทั้ง Python 2 และ 3 3**.5//1ประเมินเป็น1.0ทั้งสองเวอร์ชัน
ovs

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เป็นศูนย์สะสมจำนวนของเกราะในขณะที่เราไป

พิสูจน์:

ด้วยสี่เหลี่ยมจัตุรัสที่สมบูรณ์แบบของความยาวด้านเราต้องมี 1 โล่อย่างแม่นยำสำหรับสมาชิกของจัตุรัส ต่อไปสำหรับสมาชิกแต่ละคนบนขอบเราต้องการเกราะป้องกันเพิ่มเติม มีสมาชิก( y - 2 ) 2คนที่ไม่ได้อยู่บนขอบดังนั้นจึงมีสมาชิกy 2 - ( y - 2 ) 2คนที่อยู่บนขอบ ในที่สุดสำหรับแต่ละมุมเราจำเป็นต้องมีเกราะป้องกันเพิ่มเติม นอกเหนือจากกรณีที่y = 1เราสามารถเพิ่ม 4 ได้ซึ่งทำให้y 2 + 4 y 5 ง่ายขึ้นเมื่อy = 1y(y2)2y2(y2)2y=1y2+4yที่จะให้ค่าที่ถูกต้องของ5y=1ช่วยให้เราสามารถใช้งานได้ทุกปีy


คุณสามารถลดความซับซ้อน explenation มาก: หลังคาทุกตารางความต้องการที่จะได้รับการคุ้มครอง: และทุกด้านตารางความต้องการที่จะครอบคลุม4 Y ตอนนี้เห็นได้ชัดว่ามันยังใช้งานได้ในกรณีของทหารโสด Y24Y
ทอดด์ซีเวลล์

1
@ToddSewell แน่นอนว่านั่นเป็นคำอธิบายของ Arnauldและมันก็ดูสง่างามกว่า แต่นี่คือวิธีที่ฉันเข้าหามันดังนั้นฉันเลยติดมัน! โชคดีที่นี่ไม่ใช่คำถามพิสูจน์กอล์ฟ
Giuseppe

10

JavaScript (ES7), 34 ไบต์

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

ลองออนไลน์!

อย่างไร?

ในแต่ละซ้ำเราคำนวณความกว้างของสี่เหลี่ยมที่ใหญ่ที่สุดที่เป็นไปได้ จำนวนโล่sWสำหรับตารางนี้จะได้รับโดย:w=nsW

sW=W2+4W

เช่นสำหรับ :W=3

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

W=1s1=5



4

Julia 0.6 , 36 bytes

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

ลองออนไลน์!

n2+4n(n-2)(n-2)(n-2)2n-24* * * *(n-2)* * * *2โล่ ในที่สุดมีสี่สี่ในสี่มุมดังนั้นเพิ่ม 12 โล่

(n-2)2+4* * * *(n-2)* * * *2+4* * * *3=n2+4-4n+8n-16+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

(สิ่งนี้สามารถทำได้ใน 35 ไบต์ด้วยn>0?(s=isqrt(n))*s+4s+f(n-s*s):0แต่ฉันเขียนสิ่งนี้สำหรับ Julia 0.7 ต้องการหลีกเลี่ยงคำเตือนการคัดค้านใหม่ (ต้องมีช่องว่าง?และ:)


คำอธิบายที่ซับซ้อนเกินไปสำหรับจำนวนโล่ดูความคิดเห็นของฉันในคำตอบของ @ Giuseppe
ทอดด์ซีเวลล์

2
@ToddSewell ใช่พื้นที่ + ปริมณฑลเป็นวิธีที่ดูสง่างามกว่า ฉันไม่ได้ทำแบบนั้นและคล้ายกับจูเซปเป้ที่ฉันตั้งใจจะอธิบายวิธีการของฉันมากกว่าที่จะพิสูจน์สูตรที่ประณีตที่สุด
sundar - Reinstate Monica


3

Brachylogขนาด 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

เพิ่มแผ่นป้องกันด้านข้างในการแข่งขันแต่ละครั้ง $&คือn2และ$1เป็น2n-1 ในขณะที่เราต้องการ n2+4n=n2+2+2(2n-1).

.

ผลรวมและแปลงเป็นทศนิยม


2

05AB1E , 17 ไบต์

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

ลองมันออนไลน์หรือตรวจสอบกรณีทดสอบทั้งหมด

หลีกเลี่ยงเพราะ ΔDtïÐns4*+Šn-}O ( 15 ไบต์ ) ดูเหมือนจะไม่ทำงาน .. ลองออนไลน์ในโหมดดีบักเพื่อดูว่าฉันหมายถึงอะไร ฉันคาดหวังว่ามันจะไปจาก[45,'35',25]ไป[45,10]หลังจาก-และซ้ำถัดไปของΔแต่เห็นได้ชัดว่ามันล้างสแต็คยกเว้นสำหรับค่าสุดท้ายและกลายเป็น[10]ผลใน 0 ในตอนท้ายมาก .. ไม่แน่ใจว่านี่เป็นพฤติกรรมที่ตั้งใจหรือข้อผิดพลาด .. (แก้ไข: ตั้งใจดูด้านล่าง)

คำอธิบาย:

ยังใช้ W2+4W ที่ไหน W ความกว้างในลูปเหมือนกับคำตอบอื่น ๆ

[        }     # 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

แก้ไข: เห็นได้ชัดว่าพฤติกรรมที่ฉันอธิบายข้างต้นΔมีวัตถุประสงค์ ที่นี่มีทางเลือก 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เป็นเร็กคอร์ด "unrolls"





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 แทนที่"ด้วย')


หมายเหตุ:นี่คือการใช้สูตรตอบที่ดีของ Arnauldฉันไม่สามารถหาอะไรที่สั้นกว่านั้นได้


1

Pyth , 19 ไบต์

ฟังก์ชั่นวนซ้ำซึ่งควรจะเรียกว่าการใช้y(ดูลิงค์)

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

ลองที่นี่!

Pyth , 21 ไบต์

ประวัติการแก้ไขค่อนข้างตลก แต่อย่าลืมเยี่ยมชมหากคุณต้องการเวอร์ชั่นที่เร็วกว่ามาก :)

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

ลองที่นี่!

คำอธิบาย

sm*d+4deeDsI#I#@RL2./ โปรแกรมเต็มรูปแบบลองเรียกอินพุตถาม
                   ./ พาร์ทิชัน Integer ของ Q. Yields การรวมกันเป็นบวกทั้งหมด
                          จำนวนเต็มที่รวมกันเป็น Q
               @ RL2 นำสแควร์รูทของจำนวนเต็มทั้งหมดของแต่ละพาร์ติชั่น
             ฉันเก็บเฉพาะพาร์ติชั่นที่ไม่เปลี่ยนแปลงใน:
          sI # การยกเลิกไม่ใช่จำนวนเต็มทั้งหมด ซึ่งโดยทั่วไปจะรักษา
                          พาร์ทิชันที่เกิดขึ้นอย่างสมบูรณ์ของสี่เหลี่ยมที่สมบูรณ์แบบ แต่
                          แทนที่จะมีสี่เหลี่ยมเองเรามีรากของมัน
       รับพาร์ติชัน (พูด P) ด้วยค่าสูงสุดสูงสุด
 m สำหรับแต่ละ d ใน P ...
  * d + 4d ... ผลตอบแทน d * (d + 4) = d ^ 2 + 4d สูตรที่ใช้ในคำตอบทั้งหมด
ผลรวมของการทำแผนที่นี้และเอาท์พุทโดยปริยาย

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}

ลองออนไลน์!

ความรู้สึกเมื่อใช้จำนวนเต็มรากตนเองให้ห่างไกลสั้นกว่าในตัว ...

Ungolfed และอธิบาย

// 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
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.