Conta il numero di triangoli


22

Dato un elenco di numeri interi positivi, trova il numero di triangoli che possiamo formare in modo tale che le loro lunghezze laterali siano rappresentate da tre voci distinte dell'elenco di input.

(L'ispirazione viene da CR .)

Dettagli

  • Un triangolo può essere formato se tutte le permutazioni delle tre lunghezze laterali soddisfano la rigida disuguaglianza del triangolo(Ciò significa che , e b + c > a devono essere tutti validi).a,b,c
    a+b>c.
    a+b>ca+c>bb+c>a
  • Le tre lunghezze laterali a,b,c devono apparire in posizioni distinte nell'elenco, ma non devono necessariamente essere distinte in modo accoppiato.
  • L'ordine dei tre numeri nell'elenco di input non ha importanza. Se consideriamo un elenco ae i tre numeri a[i], a[j], a[k](dove i,j,ksono accoppiati in modo diverso), allora (a[i],a[j],a[k]), (a[i],a[k],a[j]), (a[j], a[i], a[k])ecc. Vengono considerati tutti come lo stesso triangolo.
  • Si presume che l'elenco di input contenga almeno 3 voci.
  • Si può presumere che l'elenco di input sia ordinato in ordine crescente.

Esempi

Un piccolo programma di test è disponibile qui su Provalo online!

Input, Output:
[1,2,3]  0
[1,1,1]  1
[1,1,1,1] 4
[1,2,3,4] 1
[3,4,5,7] 3
[1,42,69,666,1000000] 0
[12,23,34,45,56,67,78,89] 34
[1,2,3,4,5,6,7,8,9,10] 50

Per l'input di [1,2,3,...,n-1,n]questo è A002623 .

Per l'ingresso di [1,1,...,1](lunghezza n) questo è A000292 .

Per l'immissione dei primi nnumeri di Fibonacci ( A000045 ) questo è A000004 .


4
Penso che la sfida potrebbe essere più chiara su ciò che conta come un triangolo distinto. Dal link A000292 , suppongo che consenta di scegliere[1,1,1,1] 4 triangoli "diversi", [1,1,1]usando tre dei 1? Ma non sono 24 perché i tre 1 sono scelti non ordinati, ovvero è un sottoinsieme di tre indici anziché un elenco ordinato?
xnor

2
@xnor Thatnks per averlo sottolineato, sembra tutto corretto - ho appena aggiunto un punto nei dettagli. Spero che sia più chiaro ora.
Flawr

Risposte:


10

R , 62 52 40 34 byte

sum(c(1,1,-1)%*%combn(scan(),3)>0)

Provalo online!

La soluzione Octave di Port of Luis Mendo

Da allora a<=b<=c, la condizione del triangolo è equivalente a a+b-c>0. Il a+b-cè succintamente catturato dal prodotto matrice [1,1,-1] * X, dove Xè il 3-combinazioni della matrice di input.

Ci sono stati molti suggerimenti per i miglioramenti apportati da 3 persone diverse nei commenti:

R , 40 byte

y=combn(scan(),3);sum(y[3,]<y[1,]+y[2,])

Provalo online!



3
x[3]<x[1]+x[2]è equivalente a 2*x[3]<sum(x): 51 byte
Robin Ryder il

4
In realtà, rendere quei 45 byte . Ci scusiamo per i commenti multipli!
Robin Ryder,

1
@RobinRyder Questo [alias è lucido, pulisce davvero l'approccio.
CriminallyVulgar


9

Stax , 8 7 byte

Grazie a ricorsivo per -1!

é═rê÷┐↨

Eseguilo e esegui il debug su staxlang.xyz!

Spacchettato (8 byte) e spiegazione:

r3SFE+<+
r           Reverse
 3S         All length-3 combinations
   F        For each combination:
    E         Explode: [5,4,3] -> 3 4 5, with 3 atop the stack
     +        Add the two shorter sides
      <       Long side is shorter? 0 or 1
       +      Add result to total

È un bel trucco. Se hai una sequenza di istruzioni che comporterà sempre 0 o 1 e devi contare gli elementi di un array che producono il risultato di verità alla fine del tuo programma, F..+è un byte più corto di {..f%.

Presuppone che l'elenco iniziale sia in ordine crescente. Senza questo presupposto, attenersi oall'inizio per 8 byte.


1
r3SFE+<+pacchi a 7. Utilizza un ciclo foreach per aggiungere i risultati del filtro. L'aggiunta è una delle operazioni che non richiede operazioni quando è presente solo un singolo elemento.
ricorsivo il

6

Haskell , 49 byte

([]%)
[c,b,a]%l|a+b>c=1
p%(h:l)=(h:p)%l+p%l
_%_=0

Provalo online!

Genera in modo ricorsivo tutte le sottosequenze di l(invertite) e controlla quali lunghezze 3 formano triangoli.

50 byte

f l=sum[1|[a,b,c]<-filter(>0)<$>mapM(:[0])l,a+b>c]

Provalo online!

La stessa idea, generando le sottosequenze con mapM, mappando ciascun valore lsu se stesso (include) o 0(exclude).

50 byte

([]%)
p%(b:t)=sum[1|c<-t,a<-p,a+b>c]+(b:p)%t
_%_=0

Provalo online!

Cerca ogni punto di partizione per prendere l'elemento centrale b.

51 byte

f(a:t)=f t+sum[1|b:r<-scanr(:)[]t,c<-r,a+b>c]
f _=0

Provalo online!

La funzione q=scanr(:)[]genera l'elenco di suffissi. Molti problemi derivano dalla necessità di considerare l'inclusione di elementi uguali il giusto numero di volte.

52 byte

q=scanr(:)[]
f l=sum[1|a:r<-q l,b:s<-q r,c<-s,a+b>c]

Provalo online!

La funzione di aiuto q=scanr(:)[]genera l'elenco di suffissi.

57 byte

import Data.List
f l=sum[1|[a,b,c]<-subsequences l,a+b>c]

Provalo online!


4

Brachylog , 11 byte

{⊇Ṫ.k+>~t}ᶜ

Provalo online!

Potrei aver dimenticato di sfruttare l'input ordinato nella mia vecchia soluzione:

Brachylog , 18 17 15 byte

{⊇Ṫ¬{p.k+≤~t}}ᶜ

Provalo online!

{            }ᶜ    The output is the number of ways in which
 ⊇                 a sublist of the input can be selected
  Ṫ                with three elements
   ¬{       }      such that it is not possible to show that
     p             for some permutation of the sublist
       k+          the sum of the first two elements
         ≤         is less than or equal to
      .   ~t}      the third element.

4

Perl 6 , 35 byte

+*.combinations(3).flat.grep(*+*>*)

Provalo online!

Spiegazione

È un codice qualunque, ovvero una notazione concisa per le funzioni lambda (che funziona solo in casi molto semplici). Ognuno *è un segnaposto per un argomento. Quindi prendiamo l'elenco delle lunghezze (che appare nel primo *), creiamo tutte le combinazioni di 3 elementi (escono sempre nello stesso ordine dell'elenco originale, in modo che anche le combinazioni siano ordinate), appiattiamo l'elenco, e quindi prendi la lista 3 per 3 e filtra ( grep) solo quelle terzine che soddisfano *+*>*, ovvero che la somma dei primi due argomenti è maggiore della terza. Questo dà tutte le terzine e alla fine le contiamo costringendo il contesto numerico a +.

(Ovviamente dobbiamo testarlo solo per il caso della "somma di due più piccoli> il più grande". Se questo vale, l'altro vale banalmente, in caso contrario, la tripletta non indica la lunghezza corretta del triangolo e noi no bisogno di guardare oltre.)


4

Retina , 55 byte

\d+
*
L$`_+
$<'
%L$w`(,_+)\b.*\1(_*)\b(?<=^_+\2,.*)
_
_

Provalo online! Il collegamento include casi di test, ma con i valori nel 5 ° caso ridotti per consentirne il completamento oggi. Presuppone un input ordinato. Spiegazione: Ai regex non piace molto abbinare più di una cosa. Una regex normale sarebbe in grado di trovare tutti i valori che potrebbero essere una gamba più corta di un triangolo. L' vopzione di Retina non aiuta qui, tranne per evitare un lookahead. Tuttavia l' wopzione di Retina è leggermente più utile, in quanto sarebbe in grado di trovare sia la gamba più corta che quella più lunga allo stesso tempo. Questo non è abbastanza per questa sfida, poiché potrebbero esserci più gambe centrali.

\d+
*

Converti l'input in unario.

L$`_+

Per ciascun numero di input ...

$<'

... crea una linea che è l'array originale troncato per iniziare da quel numero. $'normalmente indica la stringa dopo la corrispondenza, ma la <modifica per indicare la stringa dopo il separatore precedente, evitando di sprecare 2 byte $&. Ogni linea rappresenta quindi tutte le potenziali soluzioni che usano quel numero come la gamba più corta.

%L$w`(,_+)\b.*\1(_*)\b(?<=^_+\2,.*)
_

Per ognuna di quelle linee, trova tutte le possibili gambe centrali e più lunghe, ma assicurandoti che la differenza sia inferiore rispetto all'andata. Output a _per ogni combinazione di gambe corrispondente.

_

Conta il numero totale di triangoli trovati.


3

Python 3 , 73 byte

lambda l:sum(a+b>c for a,b,c in combinations(l,3))
from itertools import*

Provalo online!

(un',B,c)un'+B>c



3

05AB1E , 12 10 9 byte

La mia prima volta che uso 05AB1E! Grazie a [Grimy] per -1!

3.Æʒ`α›}g

Provalo online! o suite di test

Una porta diretta della mia risposta Stax. Ottieni tutte le combinazioni di tre voci e conta quelle che potrebbero formare triangoli. È quella parte che mi ha davvero colpito. Trascorro un sacco di byte lì. Legato ad essere un errore da principiante lì.

3.Æʒ`α›}g
3.Æ          List of length-3 combinations
   ʒ   }g    Count truthy results under operation:
    `          Push the two shorter sides, then the long one
     α         Absolute difference (negated subtraction in this case)
      ›        Remaining short side is longer?

2
Sono sicuro che Grimy produrrà qualcosa di più breve, poiché di solito lo fa sulle mie risposte. ;) Ma la tua risposta sembra abbastanza simile a quella che avevo in mente. L'unica differenza è che ho usato ì(invertire ciascuno) prima del filtro anziché il Š(triple swap) all'interno del filtro. In alternativa, è possibile utilizzare anche ε...}Oinvece di ʒ...}g, ma il conteggio dei byte rimane lo stesso. PS: il numero di byte di 10 e TIO sono corretti, ma la risposta effettiva ha ancora un esplicito non necessario yche può essere rimosso. :) Bella prima risposta però, quindi +1 da parte mia.
Kevin Cruijssen,

Mi dispiace deludere @KevinCruijssen, tutto quello che ho è 3.ÆʒRÆd_}g, che è lo stesso conteggio.
Grimmy,

2
@KevinCruijssen Oh, in realtà credo che 3.Æʒ`α›}gsia 9.
Grimmy,

@Grimy Haha, lo sapevo. xD Golf piuttosto diretto ora che lo vedo .. Ma di solito è meglio inventare quel tipo di golf (o golf in generale ..), come ho già detto nel mio primo commento. ; p
Kevin Cruijssen,



2

Zsh , 66 byte

for a;z=$y&&for b (${@:2+y++})for c (${@:3+z++})((t+=c<a+b))
<<<$t

Provalo online!

Relativamente semplice, sfruttando l'input ordinato e incrementando fornell'intestazione (l'incremento avviene una volta per ciclo genitore ).

for a;{
  z=$y
  for b (${@:2+y++});{   # subarray starting at element after $a
    for c (${@:3+z++})   # subarray starting at element after $b
      ((t+=c<a+b))
  }
}

2

Excel VBA, 171 164 152 byte

-26 byte grazie a TaylorScott

Sub z
t=[A:A]
u=UBound(t)
For i=1To u-2
For j=i+1To u-1
For k=j+1To u
a=t(i,1):b=t(j,1):c=t(k,1)
r=r-(a+b>c)*(b+c>a)*(c+a>b)
Next k,j,i
Debug.?r
End Sub

L'input è compreso nell'intervallo A:Adel foglio attivo. L'output è nella finestra immediata.

Dal momento che questo esamina ogni combinazione di ogni cella in una colonna alta 2 20 celle (che è quasi 2 60 combinazioni), questo codice non è ... veloce. Potresti renderlo molto più veloce ma a spese dei byte.


È possibile eliminare la ()nell'istruzione secondaria, lo spazio in Debug.? re può cadere Next:Next:Nexta Next k,j,i. a parte questo - beh sta ancora facendo 2 ** 60 combinazioni ma funziona
Taylor Scott

Oh ehi, puoi abbandonare un altro po 'sostituendo la linea if conr=r-(a+b>c)*(b+c>a)*(c+a>b)
Taylor Scott

1

Carbone , 17 byte

IΣ⭆θ⭆…θκ⭆…θμ›⁺νλι

Provalo online! Il collegamento è alla versione dettagliata del codice. Presuppone un input ordinato. Spiegazione:

   θ                Input array
  ⭆                 Map over elements and join
      θ             Input array
     …              Truncated to length
       κ            Outer index
    ⭆               Map over elements and join
          θ         Input array
         …          Truncated to length
           μ        Inner index
        ⭆           Map over elements and join
              ν     Innermost value
             ⁺      Plus
               λ    Inner value
            ›       Is greater than
                ι   Outer value
 Σ                  Take the digital sum
I                   Cast to string for implicit print




1

Pyth , 14 byte

*1sm>sPded.cQ3

Provalo online!

          .cQ3  # All combinations of length 3 from Q (input), sorted in ascending order
   m            # map over that lambda d:
     sPd        #   sum(d[:-1])
    >   ed      #     > d[-1]
  s             # sum all of those (uses the fact that True = 1)
*1              # multiply by 1 so it doesn't output True if there's only one triangle

Alternativa (anche 14 byte):

lfTm>sPded.cQ3

1

Perl 5 ( -p), 55 52 byte

usando regex backtracking, -3 byte grazie al quack @Cows usando ^invece di (?!)fallire e tornare indietro.

$d='(\d++)';$_=/$d.* $d.* $d(?{$n++if$1+$2>$3})^/+$n

o

$_=/(\d++).* (\d++).* (\d++)(?{$n++if$1+$2>$3})^/+$n

TIO


Può (?!)essere ^?
Kritixi Lithos,

grazie non riesce / torna indietro bene
Nahuel Fouilleul,

1

Gelatina , 9 byte

œc3+>ƭ/€S

Provalo online!

Un collegamento monadico che prende un elenco ordinato di numeri interi come argomento e restituisce il numero di triangoli.

Spiegazione

œc3       | Combinations of length 3
     ƭ/€  | Reduce each using each of the following in turn:
   +      | - Add
    >     | - Greater than
        S | Sum (counts the 1s)

Alternative 9s:

œc3Ṫ€<§ƊS
œc3Ṫ<SƊ€S


0

Bash , 123 byte

for a;do for((i=2;i<=$#;i++)){ b=${!i};for((j=$[i+1];j<=$#;j++)){ c=${!j};T=$[T+(a<b+c&b<a+c&c<a+b)];};};shift;done;echo $T

Provalo online!

Una divertente.


0

SNOBOL4 (CSNOBOL4) , 181 byte

	S =TABLE()
R	X =X + 1
	S<X> =INPUT	:S(R)
I	I =J =K =I + 1	LT(I,X)	:F(O)
J	J =K =J + 1	LT(J,X)	:F(I)
K	K =K + 1	LT(K,X - 1)	:F(J)
	T =T + 1 GT(S<I> + S<J>,S<K>)	:(K)
O	OUTPUT =T
END

Provalo online!

Forza bruta O(n3)algoritmo. Prende l'input come un elenco separato da una nuova riga e genera il numero di triangoli o una riga vuota per 0. Ciò è probabilmente consentito poiché SNOBOL tratta la stringa vuota come 0per i calcoli numerici.


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.