로마 군 방패


26

샌드 박스 게시물 (삭제됨)

고대 로마 군대는 전 세계적으로 매우 유명합니다. 이 포메이션에서 로마 군단병들은 측면을 보호하는 기하학적 모양 (보통 직사각형)으로 그룹화되어 측면을 보호합니다. 내부 위치에있는 병사들은 머리 위로 방패를 배치하는 상사 부분을 덮었 고, 측면에있는 병사들은 2 개 이상의 방패를 가지고있었습니다. 그는 3 개의 방패를 가지고있었습니다. 만약 누군가 혼자서 5 개의 방패를 가지고 있다면, 인간이 5 개의 방패를 가지고 다니는 것이 불가능하다는 것을 알고 있습니다 . 이 포메이션을 사용하여 모든 로마 병사들은 스스로를 보호했고 당시 가장 어려운 상대였습니다.

역사는 로마의 장군이 가장 좋은 형태는 정사각형 (행과 열에 같은 수의 군단병)이라고 언급했다. 문제는 그가하기 위해 군대를 몇 개나 (그리고 크기) 분할해야하는지 알아내는 것이 었습니다.

  • 군단에서 어떤 군단도 떠나지 마십시오 (단일 군단을 인정했지만)
  • 필요한 방패의 양을 줄입니다

그는 몇 가지 수학과 계산을 한 후,이 두 가지 조건을 달성하는 가장 좋은 방법은 가능한 가장 큰 제곱 으로 시작한 다음 군단병이 없을 때까지 반복 하는 것임을 알아 냈습니다 .


예:

그의 군대에 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
글쎄, "5 개의 방패를 들고"에 대한 구글 결과는 Amazon.com : Best-selling Nipple Shield Carrying Case, Perfect...내가 절대 알지 못할 것 같다. 그들은 실제로 5 개의 방패를 가지고 있었습니까?
매직 문어 Urn

1
@MagicOctopusUrn 임 확신 당신은 대답은 누군가가 5 방패와 싸움에서 갈 배짱이 있다고 생각하지 않습니다 XD 알고
루이스 펠리페 드 예수님 무 노즈

4
나는 장군의 수학과 계산이 아니며 가능한 한 가장 큰 사각형을 반복적으로 가져 가면 방패가 최소화된다는 결론을 내릴 수 있습니다. 예를 들어, 32 명의 군단병은 72 개의 총 방패에 5 * 5 + 2 * 2 + 1 * 1 + 1 * 1 + 1 * 1의 사각형이 아니라 64 개의 총 방패에 대해 2 개의 4 * 4 사각형으로 나눌 수 있습니다.
xnor

6
@xnor 어쩌면 일반적인 경우에는 장군이 옳지 않았지만 장군은 장군입니다 (일반화해서는 안되지만).
pajonk

2
@AJFaraday Asterix와 용병 오소리 ?
Chris H

답변:


14

파이썬 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

@Jonathan Frech 덕분에 50 바이트로 줄었습니다!

편집 2

전환 int(s**.5)하기 위해 s**.5//12 바이트를 @ovs 덕분에 저장


8
PPCG에 오신 것을 환영합니다!
Luis felipe De jesus Munoz

2
두 바이트를 절약하는 n*n것보다 짧다고 생각 n**2합니다. 내가 파이썬을 쓰지 않아서 말할 수없는 것 이상으로 ...
Giuseppe


2
int(s**.5)로 단축 할 수 있습니다 s**.5//1.
ovs

2
@mypetlion 그것은 않습니다. //파이썬 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 의 제곱y 은 정확히 쉴드를 가져야합니다 . 우리는 광장보다 최대로 줄이거 나 동일한 X 때까지 x는 우리가 가서 방패의 수를 축적, 제로이다.y2+4yxx

증명:

측면 길이 의 완벽한 제곱이 주어지면 각 제곱의 멤버마다 정확히 1 개의 쉴드가 필요합니다. 다음으로 가장자리의 각 멤버마다 추가 차폐가 필요합니다. 있습니다 ( Y - 2 ) 2 개 회원이 되지 가장자리에, 그래서 거기에 y를 2 - ( Y - 2 ) 2y(y2)2y2(y2)2 가장자리에 회원. 마지막으로 각 구석에 추가 방패가 필요합니다. 인 경우를 제외하고 4를 더할 수 있습니다. 이것은 y 2 + 4 y로 단순화하여 다행히도 올바른 값을 산출합니다.y=1y2+4yy = 1 일때 5 이므로 모든 y 에 사용할 수있습니다.5y=1y


모든 지붕 사각형을 덮을 필요가 있습니다 : , 모든 측면 사각형을 덮을 필요가 있습니다 : 4 y . 이제 단일 솔러 경우에도 작동한다는 것이 분명합니다. y24y
토드 세웰

1
확실 @ToddSewell, Arnauld의 설명 , 그리고 그것은 이다 훨씬 더 우아하고,하지만 내가 그것을 고수하고있어, 그래서 내가 그것을 접근 방법입니다! 운 좋게도 이것은 증명 골프 문제가 아닙니다.
Giuseppe

10

자바 스크립트 (ES7), 34 바이트

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

온라인으로 사용해보십시오!

방법?

각 반복에서 너비 w = √를 계산합니다.가능한 가장 큰 제곱의 n. 방패의 수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)224(2)2방패. 마지막으로, 4 개의 모서리에 4 개의 3이있어 12 개의 방패가 추가됩니다.

(2)2+4(2)2+4=2+44+816+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,하지만 난 줄리아 0.7이 쓴 새로운 사용 중단 경고 (필요로하는 공간이 피하기 위해 원 ?하고 :).)


방패 수에 대한 또 다른 복잡한 설명은 @Giuseppe의 답변에 대한 내 의견을 참조하십시오.
토드 세웰

2
@ToddSewell 그래, 면적 + 둘레는 그것을 보는 더 우아한 방법입니다. 나는 그런 식으로하지 않았으며 주세페 (Giuseppe)와 비슷한 나의 의도는 공식의 가장 작은 증거를 제공하는 것보다 내 접근 방식을 설명하는 것입니다.
sundar-복원 모니카


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일치하는 항목 만 일치합니다. 일치하는 항목의 시작 부분에서만 일치 \G1하므로 후속 일치 항목은 일치하지 않습니다 \G.11\1 이상 2 인을 이전 경기. 우리는 가능한 한 많은 홀수를 매칭하므로, 총 매치는 제곱 수이며, 마지막 캡처는 측면의 두 배 미만입니다.

$&11$1$1

각 경기에 사이드 쉴드를 추가하십시오. $&이다2$1이다21 우리가 필요한 동안 2+4=2+2+2(21).

.

합계하고 10 진수로 변환합니다.


2

05AB1E , 17 바이트

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

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

ΔDtïÐns4*+Šn-}O( 15 바이트 )가 작동하지 않기 때문에 해결 방법. 디버그 모드에서 온라인으로 시도하여 무슨 뜻인지 확인하십시오. 나는에서 갈 기대 [45,'35',25][45,10]애프터- 과 다음 반복 Δ하지만, 분명히 그것은 마지막 값을 제외하고 스택을 지우고되고 [10]이 행동이나 버그를 목적으로하지 않습니다 확인하면 ... 맨 끝에 0의 결과로 .. (편집 : 의도 된 것입니다. 아래 참조).

설명:

또한 사용 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

편집 : 분명히 위에서 설명한 동작 Δ이 의도 된 것입니다. @ Mr.Xcoder 가 제공하는 2 개의 17 바이트 대안은 global_arrayΔ 에 값을 넣고 (with ^) 나중에 값을 다시 가져 와서 사용합니다 (with ¯).

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

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

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

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .


2

dc , 25 바이트

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

온라인으로 사용해보십시오!

각 정사각형 측면 길이의 사본을 스택 레지스터에 푸시 한 다음 레지스터의 모든 값을 재귀 "언 롤링"으로 추가 하여 쉴드를 sum(n^2)(원래 번호) 플러스 로 계산합니다 .4*sum(n)aa





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

(리눅스, 대체 "와 함께 ')


참고 :Arnauld의 대답을 사용하여 그보다 짧은 것을 찾을 수 없었습니다.


1

피스 , 19 바이트

재귀 함수는 다음을 사용하여 호출해야합니다 y(링크 참조).

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

여기 사용해보십시오!

피스 , 21 바이트

개정 기록은 매우 재미 있지만 훨씬 빠른 버전을 원하면 방문하십시오 :)

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

여기 사용해보십시오!

설명

sm*d+4deeDsI#I#@RL2./ 전체 프로그램, 입력 Q를 호출 해 봅시다.
                   ./ Q의 정수 ​​파티션. 양의 모든 조합을 나타냅니다.
                          Q를 더하는 정수
               @ RL2 각 파티션의 모든 정수의 제곱근을 취하십시오.
             I # 아래에 변하지 않는 파티션 만 유지하십시오.
          sI # 모든 비정 수를 삭제합니다. 이것은 기본적으로
                          완전한 사각형으로 완전히 형성된 칸막이
                          우리는 사각형 자체를 가지지 않고 뿌리를 가지고 있습니다.
       eeD 최대 값을 가진 파티션 (P)을 얻는다.
 m P의 각 d에 대해 ...
  * d + 4d ... 항복 d * (d + 4) = d ^ 2 + 4d, 모든 답에 사용되는 공식.
n이 맵핑 결과를 요약하고 내재적으로 출력합니다.

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
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.