Khiên quân đội La Mã


26

Bài Sandbox (đã xóa)

Các đội quân La Mã cũ rất nổi tiếng trên khắp thế giới. Trong các đội hình này, các quân đoàn La Mã được nhóm lại theo hình dạng hình học (thường là hình chữ nhật) bảo vệ sườn và phần vượt trội của nó bằng cách sử dụng khiên của họ. Các quân đoàn ở các vị trí bên trong che phần vượt trội đặt khiên của họ lên trên đầu, các quân đoàn ở hai bên mang theo 2 hoặc nhiều khiên: một để bảo vệ phần vượt trội và một hoặc nhiều khiên để bảo vệ sườn (nếu có ai đó ở trong góc anh ta có 3 khiên, nếu ai đó ở một mình trong đội hình thì anh ta có 5 khiên Có, tôi biết không thể nào một người mang 5 khiên, nhưng bằng cách nào đó họ đã làm được ). Sử dụng đội hình này, tất cả các quân đoàn La Mã đều tự bảo vệ mình và là đối thủ khó nhằn nhất vào thời điểm đó.

Lịch sử kể rằng có một vị tướng La Mã đã tuyên bố rằng hình dạng tốt nhất là hình vuông (cùng số lượng quân đoàn trong các hàng và cột). Vấn đề là tìm ra có bao nhiêu đội hình (và kích cỡ) anh ta nên chia quân đội của mình để:

  • Không để bất kỳ quân đoàn nào ra khỏi đội hình (mặc dù ông thừa nhận đội hình quân đoàn duy nhất)
  • Giảm số lượng khiên cần thiết

Đại tướng, sau khi thực hiện một số phép tính và tính toán, ông đã tìm ra cách tốt nhất để thực hiện 2 điều kiện này là bắt đầu với hình vuông lớn nhất có thể, và sau đó lặp lại cho đến khi không còn quân đoàn nào .


Thí dụ:

Nếu 35 quân đoàn trong quân đội của ông, đội hình bao gồm

  • Một hình vuông Legionaries 5x5 (Đây là hình vuông lớn nhất có thể).

Với các quân đoàn còn lại (10)

  • Một hình vuông 3x3

Với các quân đoàn còn lại (1)

  • Một hình vuông 1x1.

Cuối cùng, nó sẽ trông giống như thế này:

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

Các quân đoàn tại các vị trí bên trong bao phủ phần vượt trội đặt khiên của họ trên đầu của họ . Họ chỉ cần 1 khiên.

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

Các quân đoàn ở sườn mang 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 *               

Nếu ai đó ở trong góc, anh ta có 3 cái khiên

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               

Nếu ai đó ở một mình trong đội hình, anh ta có 5 khiên

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               

Đội hình này cần tổng cộng 71 lá chắn.


Thử thách

  • Tính số lượng khiên cần thiết cho một lượng quân đoàn X

Đầu vào

  • Số lượng quân đoàn trong quân đội

Đầu ra

  • Số lượng khiên cần thiết.

Các trường hợp thử nghiệm

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


11
Chà, kết quả google cho "mang 5 khiên" là Amazon.com : Best-selling Nipple Shield Carrying Case, Perfect...vì vậy tôi đoán tôi sẽ không bao giờ thực sự biết. Họ có thực sự mang theo 5 tấm khiên-- hay đây là để làm cho câu hỏi hoạt động: P?
Bạch tuộc ma thuật Urn

1
@MagicOctopusUrn Tôi chắc chắn bạn biết câu trả lời xD Tôi không nghĩ ai đó có can đảm ra ngoài trong một cuộc chiến với 5 lá chắn
Luis felipe De jesus Munoz

4
Tôi không tính toán và tính toán của đại tướng là đúng khi kết luận rằng việc liên tục lấy ô vuông lớn nhất có thể cần thiết sẽ giảm thiểu các lá chắn. Ví dụ: 32 quân đoàn có thể chia thành hai hình vuông 4 * 4 cho tổng số 64 khiên, thay vì hình vuông 5 * 5 + 2 * 2 + 1 * 1 + 1 * 1 + 1 * 1 cho 72 khiên tổng.
xnor

6
@xnor Có thể trong trường hợp chung, cái chung không đúng, nhưng cái chung là chung (mặc dù chúng ta không nên khái quát hóa).
pyjama

2
@AJFaraday Asterix và kẻ xấu đánh thuê ?
Chris H

Câu trả lời:


14

Python 2 , 60 50 48 byte

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

Hãy thử trực tuyến!

Mới chơi mã golf, nhưng cho nó cú swing tốt nhất của tôi!

Phương pháp:

Tổng n^2 + 4ntrong đó nmỗi số vuông lớn nhất tổng hợp với đầu vào.

Chỉnh sửa 1

Giảm xuống 50 byte nhờ @Jonathan Frech!

Chỉnh sửa 2

Đã chuyển int(s**.5)sang s**.5//1lưu 2 byte nhờ @ovs


8
Chào mừng đến với PPCG!
Luis felipe De jesus Munoz

2
Tôi nghĩ n*nlà ngắn hơn n**2để tiết kiệm cho bạn hai byte; nhiều hơn thế tôi không thể nói vì tôi không viết trăn ...
Giuseppe


2
int(s**.5)có thể rút ngắn thành s**.5//1.
trứng

2
@mypetlion Nó làm. //là phân chia tầng trong cả Python 2 và 3. 3**.5//1đánh giá 1.0trong cả hai phiên bản.
OVS

11

R , 51 50 byte

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

Hãy thử trực tuyến!

Một hình vuông có chiều dài cạnh phải có chính xác khiên. Chúng ta giảm bởi hình vuông lớn nhất nhỏ hơn hoặc bằng cho đến khi bằng 0, tích lũy số lượng khiên khi chúng ta đi.yy2+4yxx

Bằng chứng:

Cho một hình vuông hoàn hảo có chiều dài cạnh , chúng ta cần chính xác 1 khiên cho mỗi thành viên của hình vuông. Tiếp theo, đối với mỗi thành viên ở rìa, chúng ta cần một lá chắn bổ sung. Có thành viên không ở các cạnh, vì vậy có thành viên trên các cạnh. Cuối cùng, đối với mỗi góc, chúng ta cần một lá chắn bổ sung. Ngoài trường hợp , do đó chúng ta có thể thêm 4. Điều này đơn giản hóa thành , điều may mắn là cũng mang lại giá trị đúng là khi , cho phép chúng ta sử dụng nó cho tất cả .y(y2)2y2(y2)2y=1y2+4y5y=1y


Bạn có thể đơn giản hóa phần giải thích rất nhiều: mỗi ô vuông trên mái cần được che lại: và mỗi ô vuông bên cần phủ . Bây giờ rõ ràng là nó cũng hoạt động trong trường hợp một người lính. y24y
Todd Sewell

1
@ToddSewell chắc chắn, đó là lời giải thích Arnauld của , và nó xa tao nhã hơn, nhưng đây là cách tôi tiếp cận nó, vì vậy tôi gắn bó với nó! May mắn thay, đây không phải là một câu hỏi bằng chứng golf.
Giuseppe

10

JavaScript (ES7), 34 byte

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

Hãy thử trực tuyến!

Làm sao?

Ở mỗi lần lặp, chúng tôi tính chiều rộng của hình vuông lớn nhất có thể. Số lượng khiên cho hình vuông này được cho bởi:w=nsw

sw=w2+4w

Chẳng hạn, với :w=3

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

Công thức giữ cho , như .w=1s1=5



4

Julia 0,6 , 36 byte

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

Hãy thử trực tuyến!

Sử dụng cùng một phương pháp như câu trả lời R của @ Giuseppe, mặc dù phương pháp của tôi đến đó liên quan đến suy nghĩ ít ý nghĩa hơn và chỉ kiểm tra trực quan: hình vuông bên trong 1s có kích thước bởi , do đó có khiên. Xung quanh đó, có 4 bức tường gồm binh sĩ, mỗi người có 2 khiên - để có thêm khiên. Cuối cùng, có bốn số 3 ở bốn góc, để thêm 12 tấm khiên.n2+4n(n2)(n2)(n2)2n24(n2)2

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

Ung dung:

!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

(Điều này cũng có thể được thực hiện trong 35 byte với n>0?(s=isqrt(n))*s+4s+f(n-s*s):0, nhưng tôi đã viết điều này cho Julia 0.7 muốn tránh các cảnh báo khấu hao mới (yêu cầu khoảng trắng là ?:).)


Một lời giải thích quá phức tạp khác về số lượng khiên, hãy xem nhận xét của tôi về câu trả lời của @ Giuseppe.
Todd Sewell

2
@ToddSewell Vâng, diện tích + chu vi là một cách thanh lịch hơn để xem xét nó. Mặc dù vậy, tôi đã không làm theo cách đó và tương tự như Giuseppe, ý định của tôi là mô tả cách tiếp cận của tôi hơn là đưa ra bằng chứng rõ ràng nhất về công thức.
- Phục hồi Monica


3

Brachylog , 26 byte

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

Hãy thử trực tuyến!

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

Võng mạc 0.8.2 , 28 byte

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

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải trình:

.+
$*

Chuyển đổi thành số thập phân.

(\G1|11\1)+

Ghép các số lẻ. Lần đầu tiên đi qua nhóm, \1chưa tồn tại, do đó chỉ \G1có thể khớp, khớp với 1. Các trận đấu tiếp theo không thể khớp \G1\Gchỉ khớp ở đầu trận đấu, vì vậy thay vào đó chúng tôi phải khớp với 11\1hơn 2 trận đấu trước. Chúng tôi khớp nhiều số lẻ nhất có thể, và do đó, tổng số trận đấu là một số vuông, trong khi lần chụp cuối cùng là một ít hơn hai lần cạnh của nó.

$&11$1$1

Thêm các lá chắn bên cho mỗi trận đấu. $&là và là trong khi chúng ta cần .n2$12n1n2+4n=n2+2+2(2n1)

.

Tổng và chuyển thành số thập phân.


2

05AB1E , 17 byte

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

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm việc xung quanh vì ΔDtïÐns4*+Šn-}O( 15 byte ) dường như không hoạt động .. Hãy thử trực tuyến trong chế độ gỡ lỗi để xem ý tôi là gì. Tôi hy vọng nó sẽ đi từ [45,'35',25]đến [45,10]sau -lần lặp lại và tiếp theo Δ, nhưng rõ ràng nó sẽ xóa ngăn xếp ngoại trừ giá trị cuối cùng và trở thành [10], dẫn đến 0 ở cuối .. Không chắc đây là hành vi có chủ đích hay lỗi .. (EDIT: Dự định, xem phía dưới.)

Giải trình:

Cũng sử dụng trong đó là chiều rộng trong một vòng lặp như hầu hết các câu trả lời khác.ww2+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: Rõ ràng hành vi tôi mô tả ở trên Δlà nhằm mục đích. Ở đây, hai lựa chọn thay thế 17 byte được cung cấp bởi @ Mr.Xcoder sử dụng Δbằng cách đặt các giá trị trong global_array (with ^) và truy xuất lại chúng sau đó (with ¯):

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

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

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

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .


2

dc , 25 byte

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

Hãy thử trực tuyến!

Tính toán các khiên dưới dạng sum(n^2)(số ban đầu) cộng với 4*sum(n)bằng cách đẩy một bản sao của mỗi chiều dài cạnh vuông vào thanh ghi ngăn xếp a, sau đó thêm tất cả các giá trị từ thanh ghi adưới dạng đệ quy "hủy đăng ký ".





1

PHP , 67 byte

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

Để chạy nó:

php -n <filename> <n>

Thí dụ:

php -n roman_army_shields.php 35

Hoặc dùng thử trực tuyến!


Sử dụng -Rtùy chọn, phiên bản này là 60 byte :

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

Thí dụ:

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

(trên Linux, thay thế "bằng ')


Lưu ý: Đây là sử dụng công thức tuyệt vời trả lời của Arnauld , tôi không thể tìm thấy bất cứ điều gì ngắn hơn thế.


1

Bình thường , 19 byte

Một hàm đệ quy, nên được gọi bằng cách sử dụng y(xem liên kết).

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

Hãy thử nó ở đây!

Bình thường , 21 byte

Lịch sử sửa đổi khá buồn cười, nhưng hãy nhớ truy cập nếu bạn muốn có phiên bản nhanh hơn nhiều :)

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

Hãy thử nó ở đây!

Giải trình

sm*d+4deeDsI#I#@RL2./ Chương trình đầy đủ, hãy gọi đầu vào Q.
                   ./ Phân vùng số nguyên của Q. Mang lại tất cả các kết hợp dương
                          số nguyên cộng với Q.
               @ RL2 Lấy căn bậc hai của tất cả các số nguyên của mỗi phân vùng.
             Tôi # Chỉ giữ lại những phân vùng bất biến dưới:
          sI # Loại bỏ tất cả các số nguyên. Điều này về cơ bản chỉ giữ
                          phân vùng được hình thành đầy đủ các hình vuông hoàn hảo, nhưng
                          thay vì có hình vuông, chúng ta có nguồn gốc của chúng.
       eeD Lấy phân vùng (giả sử P) với mức tối đa cao nhất.
 m Với mỗi d trong P ...
  * d + 4d ... Hiệu suất d * (d + 4) = d ^ 2 + 4d, công thức được sử dụng trong tất cả các câu trả lời.
s Tổng kết quả của ánh xạ này và đầu ra ngầm.

1

Swift 4 , 111 99 84 78 byte

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}

Hãy thử trực tuyến!

Cảm giác rằng khi thực hiện nguyên căn bậc hai tay là xa ngắn hơn được xây dựng trong ...

Ungolfed và giải thích

// 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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.