Tarcze armii rzymskiej


26

Wpis w piaskownicy (usunięty)

Stare formacje armii rzymskiej są bardzo znane na całym świecie. W tych formacjach rzymscy legioniści zgrupowani w geometryczny kształt (zwykle prostokąt) chronią boki i ich większą część za pomocą swoich tarcz. Legioniści w pozycjach wewnętrznych zakrywali górną część, umieszczając tarczę nad głowami, legioniści na bokach nosili 2 lub więcej tarcz: jedną do ochrony części nadrzędnej i jedną lub więcej tarcz do ochrony boków (jeśli ktoś był w kącie miał 3 tarcze, jeśli ktoś był sam w formacji, miał 5 tarcz Tak, wiem, że człowiek nie może nosić 5 tarcz, ale jakoś to zrobił ). Korzystając z tej formacji, wszyscy rzymscy legioniści bronili się i byli wówczas najtrudniejszym przeciwnikiem.

Historia mówi, że był rzymski generał, który stwierdził, że najlepszym kształtem formacji był kwadrat (ta sama liczba legionistów w rzędach i kolumnach). Problem polegał na ustaleniu, ile formacji (i ich rozmiar) powinien podzielić swoją armię, aby:

  • Nie pozostawiaj żadnego legionisty poza formacją (chociaż przyznał się do jednej formacji legionowej)
  • Zmniejsz liczbę wymaganych osłon

Generał, po wykonaniu pewnych obliczeń matematycznych i obliczeń, doszedł do wniosku, że najlepszym sposobem na spełnienie tych 2 warunków jest rozpoczęcie od największego możliwego kwadratu, a następnie powtarzanie, dopóki legioniści nie opuścili .


Przykład:

Jeśli 35 legionistów w jego armii składało się z formacji

  • Kwadrat legionistów 5 x 5 (jest to największy możliwy kwadrat).

Z pozostałymi legionistami (10)

  • Kwadrat 3 x 3

Z pozostałymi legionistami (1)

  • Kwadrat 1x1.

Na koniec będzie wyglądać mniej więcej tak:

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

Legioniści w pozycjach wewnętrznych zakrywali górną część, umieszczając tarczę nad głowami . Potrzebowali tylko 1 tarczy.

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

Legioniści na flankach nosili 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 *               

Jeśli ktoś był w kącie, miał 3 tarcze

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               

Jeśli ktoś był sam w formacji, miał 5 tarcz

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               

Ta formacja wymagała łącznie 71 tarcz.


Wyzwanie

  • Oblicz liczbę tarcz potrzebnych dla X legionistów

Wkład

  • Liczba legionistów w armii

Wydajność

  • Potrzebna ilość osłon.

Przypadki testowe

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


11
Wynik Google dla „noszenia 5 tarcz” jest Amazon.com : Best-selling Nipple Shield Carrying Case, Perfect...taki, więc chyba nigdy się nie dowiem. Czy faktycznie nosili 5 tarcz - czy to miało sprawić, że pytanie zadziała: P?
Magic Octopus Urn

1
@MagicOctopusUrn Jestem pewien, że znasz odpowiedź xD Nie sądzę, żeby ktoś miał odwagę wyjść
Luis Felipe De

4
Nie zgadzam się z matematyką generała i obliczenia słuszne są do wniosku, że wielokrotne podejmowanie największego możliwego kwadratu minimalizuje osłony. Na przykład 32 legionistów można podzielić na dwa kwadraty 4 * 4 dla 64 tarcz ogółem, zamiast kwadratów 5 * 5 + 2 * 2 + 1 * 1 + 1 * 1 + 1 * 1 dla 72 tarcz ogółem.
xnor

6
@xnor Może w ogólnym przypadku generał nie miał racji, ale generał jest generałem (chociaż nie powinniśmy uogólniać).
pajonk

2
@AJFaraday Asterix i borsuki najemników ?
Chris H

Odpowiedzi:


14

Python 2 , 60 50 48 bajtów

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

Wypróbuj online!

Nowy w golfie kodowym, ale daje z siebie wszystko!

Metoda:

Suma, n^2 + 4ngdzie njest każdą z największych liczb kwadratowych, które sumują się do danych wejściowych.

Edytuj 1

Zmniejszony do 50 bajtów dzięki @Jonathan Frech!

Edytuj 2

Przełączono int(s**.5)na, s**.5//1aby zapisać 2 bajty dzięki @ovs


8
Witamy w PPCG!
Luis felipe De jesus Munoz

2
Myślę, że n*njest krótszy niż n**2zaoszczędzić dwa bajty; co więcej, nie mogę powiedzieć, skoro nie piszę pytona ...
Giuseppe,


2
int(s**.5)można skrócić do s**.5//1.
ovs

2
@mypetlion Tak. //jest podział podłogi w obu Python 2 i 3. 3**.5//1ewaluuje 1.0w obu wersjach.
ovs

11

R , 51 50 bajtów

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

Wypróbuj online!

Kwadrat o długości boku musi mieć dokładnie tarczę . Zmniejszamy o największy kwadrat mniejszy lub równy aż wyniesie zero, kumulując liczbę tarcz wraz z upływem czasu.yy2+4yxx

Dowód:

Biorąc pod uwagę idealny kwadrat o długości boku , potrzebujemy dokładnie 1 tarczy dla każdego członka kwadratu. Następnie dla każdego członka na krawędzi potrzebujemy dodatkowej tarczy. Istnieje użytkowników nie na brzegach, tak, że są użytkowników na krawędziach. Wreszcie dla każdego rogu potrzebujemy dodatkowej tarczy. Oprócz przypadku, gdy , możemy w ten sposób dodać 4. Upraszcza to co na szczęście daje również prawidłową wartość gdy , co pozwala nam używać go przez cały .y(y2)2y2(y2)2y=1y2+4y5y=1y


Możesz bardzo uprościć eksplorację: każdy kwadrat dachu musi być przykryty: , a każdy kwadrat boczny musi być przykryty . Teraz jest oczywiste, że działa również w przypadku pojedynczego żołnierza. y24y
Todd Sewell,

1
@ToddSewell, jasne, to jest wytłumaczenie Arnaulda , i jest o wiele bardziej eleganckie, ale do tego podszedłem, więc trzymam się tego! Na szczęście nie jest to pytanie do gry w golfa.
Giuseppe,

10

JavaScript (ES7), 34 bajty

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

Wypróbuj online!

W jaki sposób?

w=nsw

sw=w2+4w

Na przykład dla :w=3

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

Formuła obowiązuje dla , ponieważ .s 1 = 5w=1s1=5



4

Julia 0.6 , 36 bajtów

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

Wypróbuj online!

Używa tej samej metody , co odpowiedź R @ Giuseppe, chociaż moja metoda dotarcia tam wymagała mniej znaczącego myślenia i bardziej tylko kontroli wzrokowej: wewnętrzny kwadrat 1s ma wymiary o , więc ma tarcze. Wokół tego znajdują się 4 ściany żołnierzy każda, każda z 2 tarczami - co dodaje tarcze. Wreszcie, są cztery 3 w czterech rogach, więc dodaje 12 tarcz.n2+4n(n2)(n2)(n2)2n24(n2)2

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

Nie golfowany:

!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

(Można to również zrobić w 35 bajtach n>0?(s=isqrt(n))*s+4s+f(n-s*s):0, ale napisałem to dla Julii 0.7 chciałem uniknąć nowych ostrzeżeń o wycofaniu (wymagające spacji są ?i :).)


Kolejne nadmiernie skomplikowane wyjaśnienie liczby tarcz, patrz mój komentarz do odpowiedzi @ Giuseppe.
Todd Sewell,

2
@ToddSewell Tak, obszar + obwód to bardziej elegancki sposób na to spojrzeć. Nie zrobiłem tego jednak w ten sposób i podobnie jak Giuseppe, moim zamiarem jest opisanie mojego podejścia, a nie dostarczenie najdokładniejszego dowodu tej formuły.
Sundar - Przywróć Monikę


3

Brachylog , 26 bajtów

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

Wypróbuj online!

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 bajtów

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

Wypróbuj online! Link zawiera przypadki testowe. Wyjaśnienie:

.+
$*

Konwertuj na dziesiętny.

(\G1|11\1)+

Dopasuj liczby nieparzyste. Pierwsze przejście przez grupę \1jeszcze nie istnieje, więc \G1można dopasować tylko , które pasują 1. Kolejne mecze nie mogą się zgadzać, \G1ponieważ \Gtylko dopasowania na początku meczu, więc zamiast tego musimy dopasować, 11\1który jest o 2 większy niż poprzedni mecz. Dopasowujemy jak najwięcej liczb nieparzystych, jak to możliwe, a zatem całkowite dopasowanie jest liczbą kwadratową, podczas gdy ostatni chwyt jest o jeden mniej niż dwa razy większy od jego boku.

$&11$1$1

Dodaj boczne osłony do każdego meczu. $&jest i wynosi podczas gdy potrzebujemy . 2 n - 1 n 2 + 4 n = n 2 + 2 + 2 ( 2 n - 1 )n2$12n1n2+4n=n2+2+2(2n1)

.

Suma i przeliczenie na dziesiętne.


2

05AB1E , 17 bajtów

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

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Obejście, ponieważ ΔDtïÐns4*+Šn-}O( 15 bajtów ) wydaje się nie działać. Wypróbuj online w trybie debugowania, aby zobaczyć, co mam na myśli. Spodziewam się, że aby przejść od [45,'35',25]do [45,10]po -i następnej iteracji Δ, ale najwyraźniej to czyści stos z wyjątkiem ostatniej wartości i staje się [10], w wyniku czego 0 na samym końcu .. Nie wiem, czy to ma zachowanie lub błąd .. (EDYCJA: Jest zamierzone, patrz na dole).

Wyjaśnienie:

Używa również gdzie jest szerokością w pętli, jak większość innych odpowiedzi.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

EDYCJA: Najwyraźniej zachowanie, które opisałem powyżej, Δjest zamierzone. Oto dwie 17-bajtowe alternatywy dostarczone przez @ Mr.Xcoder , które wykorzystują Δumieszczając wartości w tablicy global_array (with ^) i odzyskując je później (with ¯):

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

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

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

Wypróbuj online lub sprawdź wszystkie przypadki testowe .


2

dc , 25 bajtów

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

Wypróbuj online!

Oblicza tarcze jako sum(n^2)(oryginalny numer) plus 4*sum(n), wciskając kopię każdej kwadratowej długości boku do rejestru stosu a, a następnie dodając wszystkie wartości z rejestru, agdy rekurencja „rozwija się”.





1

PHP , 67 bajtów

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

Aby uruchomić:

php -n <filename> <n>

Przykład:

php -n roman_army_shields.php 35

Lub wypróbuj online!


Za pomocą -Ropcji ta wersja ma 60 bajtów :

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

Przykład:

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

(w systemie Linux, należy wymienić "z ')


Uwaga: Korzystam z doskonałej formuły odpowiedzi Arnaulda , nie byłem w stanie znaleźć niczego krótszego.


1

Pyth , 19 bajtów

Funkcja rekurencyjna, którą należy wywołać za pomocą y(patrz link).

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

Wypróbuj tutaj!

Pyth , 21 bajtów

Historia zmian jest dość zabawna, ale koniecznie odwiedź ją, jeśli chcesz znacznie szybszej wersji :)

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

Wypróbuj tutaj!

Wyjaśnienie

sm*d+4deeDsI#I#@RL2./ Pełny program, nazwijmy wejście Q.
                   ./ Partycje całkowite Q. Daje wszystkie kombinacje dodatnie
                          liczby całkowite, które sumują się do Q.
               @ RL2 Weź pierwiastek kwadratowy ze wszystkich liczb całkowitych każdej partycji.
             I # Zachowaj tylko te partycje, które są niezmienne w:
          sI # Odrzucanie wszystkich liczb całkowitych. Zasadniczo zachowuje to tylko
                          partycje, które są w pełni utworzone z doskonałych kwadratów, ale
                          zamiast samych kwadratów, mamy ich korzenie.
       eeD Uzyskaj partycję (powiedzmy P) z najwyższym maksimum.
 m Dla każdego dw P ...
  * d + 4d ... Wydajność d * (d + 4) = d ^ 2 + 4d, wzór stosowany we wszystkich odpowiedziach.
s Sumuj wyniki tego odwzorowania i pośrednio uzyskaj wynik.

1

Swift 4 , 111 99 84 78 bajtów

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}

Wypróbuj online!

To uczucie przy ręcznym wdrażaniu pierwiastka kwadratowego z liczby całkowitej jest znacznie krótsze niż wbudowane ...

Nieoznakowany i wyjaśniony

// 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
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.