Valuta le proporzioni di un triangolo


35

Date tre lunghezze laterali di un triangolo, valutare le sue proporzioni AR data la seguente formula:

inserisci qui la descrizione dell'immagine

dove

inserisci qui la descrizione dell'immagine

Più un triangolo è vicino all'equilateralità, più è vicino al 1suo formato. Le proporzioni sono maggiori o uguali a 1per i triangoli validi.

ingressi

L'input è composto da tre numeri positivi reali che possono essere incapsulati in un elenco o qualcosa di simile se necessario.

Il tuo programma deve produrre lo stesso valore indipendentemente dall'ordine in cui sono inserite le tre sidelength.

Quei tre numeri saranno sempre validi per le sidelength di un triangolo (triangoli degenerati come uno con le sidelength 1, 1e 2non saranno dati come input). Non è necessario preoccuparsi delle imprecisioni in virgola mobile quando i valori diventano estremamente vicini a un triangolo degenerato (ad esempio, è accettabile che il programma commetta un errore division by 0per l'input [1, 1, 1.9999999999999999]).

L'input può essere fornito tramite STDIN, come argomento di funzione o qualcosa di simile.

Uscite

L'output è un numero reale maggiore o uguale 1all'accuratezza standard accettabile nella tua lingua.

L'output può essere stampato STDOUT, restituito da una funzione o qualcosa di simile.

Casi test

Inputs                   Output

  1      1      1         1
  3      4      5         1.25
 42     42   3.14         ≈ 6.9476
 14      6     12         1.575
  6     12     14         1.575
0.5    0.6    0.7         ≈ 1.09375

punteggio

Questo è , quindi vince la risposta più breve in byte.


Qualora s BE (a + b + c) / 3 ?
costrom

3
@costrom No, la formula è corretta. s è il semiperimetro del triangolo . la tua formula sarebbe indefinita per un triangolo equilatero.
Fatalizza il

Posso semplicemente ottenere float per l'input o devo avere anche numeri interi?
Erik the Outgolfer,

@ErikGolfer エ リ ッ ク ゴ ル フ ァ ー È accettabile inserire 42.0invece di 42.
Fatalizza il

@Fatalize Grazie. Inoltre, tutti gli input possono essere 0?
Erik the Outgolfer,

Risposte:


19

Gelatina , 6 byte

Questa risposta si basa sulla risposta 05AB1E di Emigna . Mille grazie a Dennis e Lynn per il loro aiuto nel capire questa risposta. Suggerimenti di golf benvenuti! Provalo online!

S_Ḥ⁸÷P

Ungolfing

           Implicit argument [a, b, c].
S          Take the sum, a+b+c or 2*s
  Ḥ        Take the double, [2*a, 2*b, 2*c].
 _         Vectorized subtract, giving us [2*(s-a), 2*(s-b), 2*(s-c)].
   ⁸÷      Vectorized divide the initial left argument, the input [a, b, c],
             by [2*(s-a), 2*(s-b), 2*(s-c)].
     P     Take the product giving us the aspect ratio, abc/8(s-a)(s-b)(s-c).

4
6 byte e vuoi ancora suggerimenti sul golf? MrGreen
Luis Mendo il

1
@LuisMendo Se è possibile, certo: D
Sherlock9,

1
"Push" non è una terminologia abbastanza corretta; Jelly non è basata su stack. Piuttosto, ⁸÷diventa molto fuori dalla catena come un'unità e dovrebbe essere letto come dividere l'argomento iniziale di sinistra per questo o qualcosa del genere.
Lynn,

1
@Lynn Sto giocando a golf da diversi mesi ormai. La terminologia basata sullo stack è saldamente incastrata nel mio cervello: D Ora dovrebbe essere risolto.
Sherlock9,

56

Gelatina , 7 byte

SH_÷@HP

Provalo online!

Spiegazione

enter image description here

Leggiamo questa catena:

  • L'argomento implicito è un elenco [a, b, c].

  • Prima leggiamo S. Questo richiede la somma: a + b + c.

  • Quindi leggiamo H. Questo dimezza esso: (a + b + c)/2. (Questo è s.)

  • Quindi, leggiamo una diade _(sottrarre), seguita da un'altra diade. Questo è un gancio : manca un argomento giusto, quindi riceve l'argomento a questa catena [a, b, c], dandoci [s-a, s-b, s-c]. (Questo è il quinto motivo a catena nella tabella qui .)

  • Quindi, leggiamo la coppia diade-monade ÷@H. Questo è un fork : ÷@è una divisione con gli argomenti capovolti, ed Hè dimezzata, quindi il nostro valore di lavoro ottiene tutti Hgli argomenti di questa catena ÷. Questo vettorializza; siamo rimasti con [(a/2)/(s-a), (b/2)/(s-b), (c/2)/(s-c)]. (Questo è il secondo modello di catena nella tabella qui .)

  • Infine, prendiamo il prodotto con P, ottenendoci abc/(8(s-a)(s-b)(s-c)).

Visualizza un grafico ad albero di come i collegamenti si incastrano.


8
Le immagini sembrano grandi! Bel tocco!
DavidC,

2
Ho ridotto l'immagine in prima persona e ho trasformato la seconda in un collegamento (nessun gioco di parole voluto).
Lynn,

Ho visto l'immagine e ho pensato subito: "Bello, Lynn!" prima di guardare chi l'ha pubblicato ;-)
ETHproductions

7
La migliore spiegazione che ho visto su un programma Jelly. Ancora non capisco, ma più vicino!
Sparr,

Ho analizzato il campione con il test case "6.0,12,0,14,0" e ha dato "0,8888888888888888" anziché 1,575, come mostrato nei test case. È un problema con i casi di test o il tuo codice?
MBaas,

13

Gelatina , 6 byte

S÷_2Pİ

Provalo online!

Come funziona

S÷_2Pİ  Main link. Argument: [a, b, c]

S       Sum; compute 2s := a + b + c.
 ÷      Divide; yield [2s ÷ a, 2s ÷ b, 2s ÷ c].
  _2    Subtract 2; yield [2s ÷ a - 2, 2s ÷ b - 2, 2s ÷ c - 2].
    P   Product; yield (2s ÷ a - 2)(2s ÷ b - 2)(2s ÷ c - 2).
     İ  Invert; yield 1 ÷ (2s ÷ a - 2)(2s ÷ b - 2)(2s ÷ c - 2).

Ahh, e ho provato a usare ³⁴⁵come argomenti ...
Erik the Outgolfer,

11

JavaScript, 38 byte

Questo è un lambda (al curry ):

a=>b=>c=>a*b*c/(b+c-a)/(a+c-b)/(a+b-c)

(Se lo assegni a una variabile, fdovresti chiamarlo come f(3)(4)(5))


Battimi ad esso per alcuni secondi :) Ti dispiace spiegare come la formula funziona in modo simile a quella fornita dalla domanda?
Kritixi Lithos,

@KritixiLithos Basta inserire s = 1/2(a+b+c)la formula e semplificare: D (ad esempio s-a = .5*b+.5*c-.5*a, e i tre fattori di .5annullamento con 8)
flawr

5
(a,b,c)=>è della stessa lunghezza e costa meno byte da chiamare;)
ETHproductions

4
Ma adoro il curry: D
flawr,

9

05AB1E , 11 7 byte

05AB1E utilizza la codifica CP-1252 .

O¹·-¹/P

Provalo online!

Spiegazione

O         # sum input
 ¹        # push input again
  ·       # multiply by 2
   -      # subtract from sum
    ¹/    # divide by input
      P   # product

8

MATL , 8 7 byte

tsGE-/p

Provalo online!

Spiegazione

Usiamo l'input [3 4 5]come esempio

t    % Take input implicitly. Duplicate
     % STACK: [3 4 5], [3 4 5]
s    % Sum of array
     % STACK: [3 4 5], 12
G    % Push input again
     % STACK: [3 4 5], 12, [3 4 5]
E    % Multiply by 2, element-wise
     % STACK: [3 4 5], 12, [6 8 10]
-    % Subtract, element-wise
     % STACK: [3 4 5], [6 4 2]
/    % Divide, element-wise
     % STACK: [0.5 1 2.5]
p    % Product of array. Implicitly display
     % STACK: 1.25

8

R, 34 29 byte

x=scan();prod(x/(sum(x)-2*x))

Legge input da stdin e memorizzare come R-vettore x. Quindi usa la vettorializzazione di R per formare il denominatore.


7

Haskell, 36 byte

Questo definisce la funzione #che accetta tre argomenti.

(a#b)c=a*b*c/(b+c-a)/(a+c-b)/(a+b-c)

Devi chiamarlo come segue: (3#4)5

Un po 'più a lungo ma forse più golfabile:

p=product
f v=p v/p((sum v-).(2*)<$>v)

6

MATLAB, 64 38 25 byte

Questa è una funzione ononima che implementa la formula come previsto:

@(v)prod(v./(sum(v)-2*v))

Presuppone che l'input sia un elenco di tre valori, ad es [3,4,5]. Questo esempio viene utilizzato nella seguente spiegazione:

             sum(v)        = 3+4+5 = 12
             sum(v)-2*v    = 12 - 2*[3,4,5] = 12 - [6,8,10] = [6,4,2]
         v./(sum(v)-2*v))  = [3,4,5] ./ [6,4,2] = [0.5,1,2.5]
    prod(v./(sum(v)-2*v))  = 0.5 * 1 * 2.5 = 1.25

6

Mathematica, 20 byte

1##&@@(#/(Tr@#-2#))&

Prende l'input come un elenco di tre valori, che viene indicato come #all'interno della funzione. Tr@è il modo più breve per sommare un elenco (per ottenere 2s) e 1##&@@(...)moltiplica i tre fattori i/(2s-2i)per iin a, b, c.

Se gli input sono numeri interi o numeri razionali, otterrai un risultato esatto.



5

OCaml, 51 byte

fun a b c->a*.b*.c/.(b+.c-.a)/.(a+.c-.b)/.(a+.b-.c)

Sì, operatori separati per i galleggianti ...


5

Meraviglia , 48 byte

@@@prod[#0#1#2/1- +#1#0#2/1- +#2#0#1/1- +#2#1#0]

RIPOSA IN PACE

Uso:

(((@@@prod[#0#1#2/1* * - +#1#0#2- +#2#0#1- +#2#1#0])3)4)5

Spiegazione

Le chiamate a funzioni sono costose in Wonder rispetto agli operatori infix in altre lingue. Per questo motivo, ho contenuto tutti i termini in un array e ho ottenuto il prodotto del risultato invece di moltiplicare ogni singolo termine. Il codice sarebbe equivalente a qualcosa del tipo:

(a,b,c)=>product([a,b,c,1/(b+c-a),1/(a+c-b),1/(a+b-c)])

1
Hmm, perché "RIP"?
Luis Mendo,

È molto più lungo del necessario / previsto
Mama Fun Roll

5

In realtà , 10 8 byte

Questa risposta si basa sull'eccellente risposta di Jelly di Dennis . Suggerimenti di golf benvenuti! Provalo online!

;Σ♀/♂¬πì

Ungolfing

     Implicit input [a, b, c].
;    Duplicate [a, b, c].
Σ    sum() to get twice the semiperimeter, 2*s.
♀/   Vectorized divide 2*s by [a, b, c] to get [2*s/a, 2*s/b, 2*s/c].
♂¬   Vectorized subtract 2 to get [2*s/a-2, 2*s/b-2, 2*s/c-2].
π    Get the product of the above to get 8*(s/a-1)*(s/b-1)*(s/c-1).
     This is the same as 8(s-a)(s-b)(s-c)/abc.
ì    Invert to get the aspect ratio, abc/8(s-a)(s-b)(s-c).
     Implicit return.

5

Minecraft 1.8, 1607 byte + 85 blocchi = 1692 blytes

Avvertenza: non golfato. Golfed ci vorranno fino a 1 / 3 meno blytes.

Ecco uno screenshot commentato:

enter image description here

  • Gli input sono a, be c, e l'output èfin

  • fine tutte le altre variabili in Minecraft sono numeri interi, quindi l'accuratezza standard di Minecraft è 0 punti decimali

  • Il bordo verde: i blocchi di comando a sinistra si attiveranno dopo quelli a destra, che sono solo inizializzazioni variabili.

  • La leva (rettangolo grigio-marrone in basso a destra) è il grilletto di aggancio

  • Ci vuole molto a causa del modo in cui Minecraft gestisce le variabili . Una panoramica molto semplificata:

    • /scoreboard objectives add name dummycrea una nuova variabile denominata " name"

    • /scoreboard players set @p name numberimposta la variabile namesu number. Il numero deve essere un numero reale, non una variabile.

    • /scoreboard players operation @p name += @p name2incrementi namedi name2. name2deve essere una variabile, non un numero.

      • -=, /=, *=, =E più può essere usato al posto +=di decremento, moltiplicare, dividere, etc.
  • Non ho intenzione di pubblicare tutti i 43 comandi qui. Aiuterebbe a giocare a golf, ma aiuterebbe anche a farmi impazzire copypasting

  • Se si utilizzassero i blocchi di comandi 1.9, la soluzione userebbe (almeno) 42 blocchi in meno. Se si utilizzassero variabili di una lettera, verrebbero salvati quasi 200 byte.


4

Java, 38 byte

(a,b,c)->a*b*c/(b+c-a)/(a-b+c)/(a+b-c)

Test e non golf

public class Pcg101234 {
  interface F {
    double f(double a, double b, double c);
  }
  public static void main(String[] args) {
    F f = (a,b,c)->a*b*c/(b+c-a)/(a-b+c)/(a+b-c);

    System.out.println(f.f(1,1,1));
    System.out.println(f.f(3,4,5));
    System.out.println(f.f(42,42,3.14));
    System.out.println(f.f(14,6,12));
    System.out.println(f.f(6,12,14));
    System.out.println(f.f(0.5,0.6,0.7));
  }
}

Provalo!

Produzione

1.0
1.25
6.947606226693615
1.575
1.575
1.09375

Sento che (a,b,c)è un po 'barare qui, perché non contiene informazioni sul tipo. IMO l'interfaccia lambda implicita (nel tuo caso F) dovrebbe contare nella somma totale dei byte.
F. George,

4
@ mEQ5aNLrK3lqs3kfSa5HbvsTWe0nIu Lambdas è fortemente raccomandato. Inoltre, la maggior parte delle voci Java 8 funziona in questo modo senza alcuna osservazione. Se non sei d'accordo e consideri che ho tradito, ti invito a chiedere formalmente in meta se questa notazione è accettata o meno. Nel frattempo, mi allineo alle precedenti risposte di Java 8.
Olivier Grégoire,

4

Medusa , 17 16 byte

Grazie a Zgarb per aver salvato 1 byte.

p%/*-)/+i
    2%

Provalo online!

Spiegazione

Questo si basa sulla stessa formula reciproca della risposta di Dennis .

Nella notazione funzionale più tradizionale, il programma sopra riportato recita come segue:

print(
  1 / fold(
    multiply,
    fold(add, i) / i - 2
  )
)

Dov'è il'elenco di input. Si noti che fold(multiply, ...)calcola solo il prodotto e fold(add, ...)la somma, quindi possiamo semplificare ulteriormente questo per:

print(1 / product(sum(i) / i - 2))

Il sum(i) / iavviene tramite il gancio )/+che definisce una nuova funzione unaria fare due passaggi contemporaneamente.


Salva un byte con un hook .
Zgarb,

4

Dyalog APL , 10 9 byte

×/⊢÷+/-+⍨

Questo è un treno di funzioni anonimo (in cima a un fork di un fork di un fork), il che significa che ogni sub-funzione viene applicata all'argomento, all'interno della seguente struttura:

 ┌─┴─┐          
×/ ┌─┼───┐      
    ÷ ┌─┼──┐  
      +/ - +⍨

ProvaAPL online!

×/ il prodotto di

gli argomenti

÷ diviso per

+/ la somma degli argomenti

- meno

+⍨ gli argomenti raddoppiati (lett. aggiunti a se stessi)

Sfondo matematico.

ngn ha rasato un byte.


Ciao Adám, pls. ricordami di chiederti di ´⊢´ la prossima settimana se lo dimentico :-)
MBaas

Non so come il collegamento "background" presumibilmente riguardi questa risposta perché non vedo alcun algoritmo lì. Inoltre, è possibile aggiungere alcune informazioni sull'ordine delle operazioni? Ho provato a riprodurre questa risposta in alcune lingue diverse con un ordine delle operazioni diverso ma ho sempre una risposta diversa da quella nella domanda.
cat

@cat Beh, non è stato concepito per fornire l'algoritmo, ma solo per spiegare quali sono le proporzioni, dato che non esiste una pagina simile su Wikipedia. APL è da destra a sinistra, il che significa che ogni funzione prende tutto ciò che è alla sua destra come argomento. Pertanto, può essere letto da sinistra a destra come nella spiegazione.
Adám


3

dc, 49 byte

5k?dsa?dsb?dsc++2/sslalblc**lsla-lslb-lslc-8***/p

Un'implementazione diretta della formula fornita. Richiede i tre input al momento dell'invocazione su tre righe separate e genera un valore a virgola mobile con 5 cifre dopo il punto decimale alla riga successiva.

Spiegazione

5k                                                # Set the output precision to 5 digits after the decimal
  ?dsa                                            # Prompt for first input value on first line, duplicate it, and then store it in register `a`
      ?dsb                                        # Prompt for second input, duplicate it, and store it in register `b`
          ?dsc                                    # Prompt for third input, duplicate it, and store it in register `c`
              ++2/ss                              # Sum up the 3 values on the main stack, then divide sum by 2 and store the result in register `s`
                    lalblc**                      # Copy all three values from registers `a`,`b`,`c` onto the main stack, find their product, and push result to top of main stack
                            lsla-                 # Copy value from register `s` onto main stack, subtract register `a`'s value from it, and push result to main stack
                                 lslb-            # Copy value from register `s` onto main stack, subtract register `b`'s value from it, and push result to main stack
                                      lslc-       # Copy value from register `s` onto main stack, subtract register `c`'s value from it, and push result to main stack
                                           8***   # Find the product of the top three values and 8 and then push the result to main stack
                                               /p # Divide the second to top value (a*b*c) by the top of stack value (8*(s-a)*(s-b)*(s-c)), push the result to the main stack, and then output the result to STDOUT

3

TI-Basic, 11 byte

L'input dovrebbe essere sotto forma di un elenco, come {A B C}.

prod(Ans)/prod(sum(Ans)-2Ans

Forse questo visual aiuterà (ricordalo 2s = a+b+c ):

      abc abc abc prod (Ans)
---------------- = --------------------- = ----------- -------- = -------------------
8 (sa) (sb) (sc) (2s-2a) (2s-2b) (2s-2c) (a + b + c) (1-2 {a, b, c}) prod (sum (Ans) -2Ans)



2

Avanti, 83 byte

Presuppone che i parametri in virgola mobile inizino nello stack in virgola mobile. Lascia il risultato sulla pila a virgola mobile. Usare lo stack per params / return è lo standard per Forth.

: p 3 fpick ;
: T p p p ;
: f 0 s>f T f- f+ f- T f+ f- f* T f- f- f* 1/f f* f* f* ;

Provalo online : contiene tutti i casi di test

Usa la formula a*b*c * 1/ ( -(a+b-c) * -(b+c-a) * (a+c-b) ). Praticamente l'intero programma utilizza solo lo stack in virgola mobile. L'eccezione è 3in 3 fpick. Questo programma richiede un interprete che supporti fpick(Ideone funziona, sostitu.it no).

Spiegazione: leggermente meno golf

\ 3 fpick takes the 3rd element (0-indexed) and pushes a copy
\ Used to copy parameters on the stack over another number 'x' ( a b c x -> a b c x a b c )
: f3p 3 fpick 3 fpick 3 fpick ;

: f                     \ define a function f
0 s>f f3p f- f+ f-      \ push a zero, copy params, compute 0-(a+b-c)
                        \ the zero allows me to copy (I need an 'x' to jump over)
f3p f+ f- f*            \ copy params and compute -(b+c-a), multiply by previous result
                        \ the negatives miraculously cancel
f3p f- f- f*            \ copy and compute (a+c-b), multiply by previous result
1/f f* f* f* ;          \ take the reciprocal and multiply by a*b*c
                        \ the result is left on the floating point stack

2

ised : 19 byte

@*$1/@*{@+$1-2.*$1}

Chiamalo come ised --l 'inputfile.txt' '@*$1/@*{@+$1-2.*$1}' dove inputfile.txtpuò essere un file con array separato da spazio o -per ricevere da pipe / stdin.

Versione Unicode (stesso byte ma 3 caratteri in meno):

Π$1/Π{Σ$1-2.*$1}

Sfortunatamente, isedspreca molti caratteri per la sua sintassi dell'argomento input.


2

vba, 76

Function r(a,b,c)
s=(a+b+c)/2:r=(a*b*c)/(8*(s-a)*(s-b)*(s-c))
End Function

Chiama con

? R (3,4,5)

o in Excel con

= R (5,12,13)


Risparmieresti 6 byte con l'algoritmo di @ SuperJedi224:Public Function r(a,b,c):r=a*b*c/(b+c-a)/(a-b+c)/(a+b-c):End Function
steenbergh,

2

C #, 82 byte

void ar(double a,double b,double c)=>Console.Write(a*b*c/(b+c-a)/(a+c-b)/(a+b-c));

Uso:

ar(42, 42, 3.14);


2

k, 19 byte

{(*/x)%8*/-x-+/x%2}

Valuta da destra a sinistra: dividi l'elenco x per 2, somma il risultato e sottralo dalla x originale. Nega la risposta e ottieni il prodotto del risultato e 8. Il risultato è il denominatore, il numeratore è il prodotto dell'elenco.


1

Lua, 45 byte

a,b,c=...print(a*b*c/(b+c-a)/(a+c-b)/(a+b-c))

Fortemente basato sulla risposta JavaScript.

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.