Scudi dell'esercito romano


26

Post sandbox (eliminato)

Le antiche formazioni dell'esercito romano sono molto famose in tutto il mondo. In queste formazioni i legionari romani raggruppati in una forma geometrica (di solito un rettangolo) proteggono i fianchi e la parte superiore di esso usando i loro scudi. I legionari nelle posizioni interne coprivano la parte superiore posizionando lo scudo sopra le loro teste, i legionari ai fianchi portavano 2 o più scudi: uno per proteggere la parte superiore e uno o più scudi per proteggere i fianchi (se c'era qualcuno nell'angolo aveva 3 scudi, se qualcuno era solo in una formazione aveva 5 scudi Sì, lo so che è impossibile per un essere umano portare 5 scudi, ma in qualche modo lo hanno fatto ). Usando questa formazione tutti i legionari romani si proteggevano e all'epoca erano gli avversari più difficili.

La storia racconta che c'era un generale romano che affermava che la migliore forma di formazione fosse la piazza (stesso numero di legionari in file e colonne). Il problema era capire quante formazioni (e dimensioni) avrebbe dovuto dividere il suo esercito per:

  • Non lasciare alcun legionario fuori da una formazione (sebbene abbia ammesso la formazione di un singolo legionario)
  • Ridurre la quantità di scudi richiesti

Il generale, dopo aver fatto un po 'di matematica e calcoli, ha capito che il modo migliore per raggiungere queste 2 condizioni è iniziare con il quadrato più grande possibile, e quindi ripetere fino a quando non sono rimasti legionari .


Esempio:

Se 35 legionari nel suo esercito, la formazione consisteva in

  • Un quadrato 5x5 legionari (questo è il quadrato più grande possibile).

Con i legionari rimanenti (10)

  • Un quadrato 3x3

Con i legionari rimanenti (1)

  • Un quadrato 1x1.

Alla fine sarà simile a questo:

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

I legionari nelle posizioni interne coprivano la parte superiore posizionando lo scudo sopra la testa . Avevano solo bisogno di 1 scudo.

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

I legionari ai fianchi trasportavano 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 *               

Se qualcuno era nell'angolo aveva 3 scudi

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               

Se qualcuno era solo in una formazione aveva 5 scudi

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               

Questa formazione ha richiesto un totale di 71 scudi.


Sfida

  • Calcola la quantità di scudi necessari per una quantità X di legionari

Ingresso

  • Quantità di legionari nell'esercito

Produzione

  • Quantità di scudi necessari.

Casi test

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

  • Si applicano le regole standard del

11
Bene, il risultato di Google per "trasportare 5 scudi" è Amazon.com : Best-selling Nipple Shield Carrying Case, Perfect...quindi credo che non lo saprò mai veramente. Avevano effettivamente 5 scudi ... o era questo per far funzionare la domanda: P?
Magic Octopus Urn

1
@MagicOctopusUrn Sono abbastanza sicuro di conoscere la risposta xD Non credo che qualcuno abbia il coraggio di uscire in una rissa con 5 scudi
Luis felipe De jesus Munoz

4
Non credo che la matematica del generale e i calcoli abbiano ragione a concludere che prendere ripetutamente il quadrato più grande possibile minimizza gli scudi. Ad esempio, 32 legionari possono essere divisi in due quadrati 4 * 4 per 64 scudi totali, anziché quadrati di 5 * 5 + 2 * 2 + 1 * 1 + 1 * 1 + 1 * 1 per 72 scudi totali.
xnor

6
@xnor Forse in generale il generale non aveva ragione, ma il generale è il generale (anche se non dovremmo generalizzare).
pajonk,

2
@AJFaraday Asterix e i tassi mercenari ?
Chris H,

Risposte:


14

Python 2 , 60 50 48 byte

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

Provalo online!

Nuovo nel code golf, ma dandogli il mio miglior swing!

Metodo:

Somma n^2 + 4ndove si ntrova ciascuno dei numeri quadrati più grandi che si sommano all'input.

Modifica 1

Ridotto a 50 byte grazie a @Jonathan Frech!

Modifica 2

Passato int(s**.5)a s**.5//1per salvare 2 byte grazie a @ovs


8
Benvenuti in PPCG!
Luis felipe De jesus Munoz,

2
Penso che n*nsia più breve di n**2salvarti due byte; più di questo non posso dire dal momento che non scrivo pitone ...
Giuseppe


2
int(s**.5)può essere abbreviato in s**.5//1.
Ovs

2
@mypetlion Lo fa. //è la divisione del piano sia in Python 2 che in 3. 3**.5//1valuta 1.0in entrambe le versioni.
Ovs

11

R , 51 50 byte

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

Provalo online!

Un quadrato di lunghezza laterale deve avere esattamente y 2 + 4 y scudi. Riduciamo per il quadrato più grande minore o uguale a x fino a quando x è zero, accumulando il numero di scudi mentre procediamo.yy2+4yXX

Prova:

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


y24y

1
@ToddSewell, certo, questa è la spiegazione di Arnauld , ed è molto più elegante, ma questo è il modo in cui mi sono avvicinato, quindi mi atterrò! Fortunatamente, questa non è una domanda da golf di prova.
Giuseppe,

10

JavaScript (ES7), 34 byte

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

Provalo online!

Come?

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 byte

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

Provalo online!

n2+4n(n-2)(n-2)(n-2)2n-24*(n-2)*2scudi. Infine, ci sono quattro 3 nei quattro angoli, in modo da aggiungere 12 scudi.

(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

(Questo può anche essere fatto in 35 byte con n>0?(s=isqrt(n))*s+4s+f(n-s*s):0, ma ho scritto questo per Julia 0.7 volevo evitare i nuovi avvisi di deprecazione (che richiedono spazi sono ?e :).)


Un'altra spiegazione complicata per il conteggio degli scudi, vedi il mio commento sulla risposta di @ Giuseppe.
Todd Sewell,

2
@ToddSewell Sì, area + perimetro è un modo più elegante di vederlo. Non l'ho fatto in questo modo, e in modo simile a Giuseppe la mia intenzione è di descrivere il mio approccio piuttosto che fornire la prova più accurata della formula.
Sundar - Ripristina Monica il


3

Brachylog , 26 byte

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

Provalo 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 byte

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

Provalo online! Il link include casi di test. Spiegazione:

.+
$*

Converti in decimale.

(\G1|11\1)+

Abbina numeri dispari. Il primo passaggio attraverso il gruppo \1non esiste ancora, quindi \G1può corrispondere solo , che corrisponde a 1. Le partite successive non possono corrispondere \G1poiché \Gsolo le partite all'inizio della partita, quindi invece dobbiamo abbinare la 11\1quale è 2 in più di la partita precedente. Abbiniamo il maggior numero possibile di numeri dispari e la corrispondenza totale è quindi un numero quadrato, mentre l'ultima acquisizione è uno meno del doppio del suo lato.

$&11$1$1

$&n2$12n-1n2+4n=n2+2+2(2n-1)

.

Somma e converti in decimale.


2

05AB1E , 17 byte

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

Provalo online o verifica tutti i casi di test .

Soluzione perché ΔDtïÐns4*+Šn-}O( 15 byte ) non sembra funzionare. Provalo online in modalità debug per vedere cosa intendo. Mi aspetto che vada da [45,'35',25]a [45,10]dopo l' -iterazione successiva e successiva Δ, ma a quanto pare cancella lo stack tranne l'ultimo valore e diventa [10], risultando in 0 alla fine .. Non sono sicuro se si tratti di comportamento previsto o di un bug .. (EDIT: è previsto, vedere in basso.)

Spiegazione:

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: Apparentemente Δè inteso il comportamento che ho descritto sopra . Ecco due alternative a 17 byte fornite da @ Mr.Xcoder che usano Δinserendo valori in global_array (con ^) e recuperandoli successivamente (con ¯):

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

Provalo online o verifica tutti i casi di test .

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

Provalo online o verifica tutti i casi di test .


2

dc , 25 byte

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

Provalo online!

Calcola gli scudi come sum(n^2)(il numero originale) più 4*sum(n)spingendo una copia di ogni lunghezza del lato quadrato nel registro dello stack amentre procede, quindi aggiungendo tutti i valori dal registro amentre la ricorsione "si svolge".





1

PHP , 67 byte

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

Per eseguirlo:

php -n <filename> <n>

Esempio:

php -n roman_army_shields.php 35

O provalo online!


Utilizzando l' -Ropzione, questa versione è di 60 byte :

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

Esempio:

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

(su Linux, sostituisci "con ')


Nota: questo sta usando la formula eccezionale della risposta di Arnauld , non sono stato in grado di trovare niente di più breve.


1

Pyth , 19 byte

Una funzione ricorsiva, che dovrebbe essere chiamata usando y(vedi il link).

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

Provalo qui!

Pyth , 21 byte

La cronologia delle revisioni è piuttosto divertente, ma assicurati di visitarla se vuoi una versione molto più veloce :)

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

Provalo qui!

Spiegazione

sm*d+4deeDsI#I#@RL2./ Programma completo, chiamiamo l'ingresso Q.
                   ./ Partizioni intere di Q. Produce tutte le combinazioni di positivo
                          numeri interi che si sommano a Q.
               @ RL2 Prendi la radice quadrata di tutti i numeri interi di ogni partizione.
             I # Mantiene solo quelle partizioni invarianti sotto:
          sI # Scarta tutti i numeri non interi. Questo in sostanza mantiene solo il
                          partizioni che sono formate completamente da quadrati perfetti, ma
                          invece di avere i quadrati stessi, abbiamo le loro radici.
       eeD Ottieni la partizione (diciamo P) con il massimo massimo.
 m Per ogni d in P ...
  * d + 4d ... Resa d * (d + 4) = d ^ 2 + 4d, la formula utilizzata in tutte le risposte.
s Somma i risultati di questa mappatura e l'output implicito.

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}

Provalo online!

Questa sensazione quando si implementa manualmente la radice quadrata intera è molto più breve rispetto al ...

Ungolfed e spiegato

// 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
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.