Determina la valle più ampia


12

Immagina di ottenere una fetta di qualche regione montuosa, questo comporterebbe una forma simile a questa:

4                   _
3   _    _       __/ \
2  / \__/ \    _/     \_   /
1 /        \  /         \_/
0           \/
  12322223210012233343221112

Come possiamo vedere, possiamo rappresentarlo (in una certa misura) con una sequenza di numeri interi.

Ai fini di questa sfida, definiamo una valle come una sottosequenza contigua in cui i valori inizialmente diminuiscono e da un certo punto in poi aumentano. Più formalmente per una sequenza (ai)i=1n a valle saranno gli indici 1s<r<tn per i quali vale quanto segue:

  • l'inizio e l'endpoint della valle sono gli stessi: as=at
  • la valle inizia e finisce quando la regione si abbassa: as>as+1at1<at
  • la valle non è piatta: asararat
  • la valle inizialmente diminuisce: i[s,r):aiai+1
  • la valle ad un certo punto aumenterà: j[r,t):ajaj+1

Ora definiamo la larghezza di una tale valle come la dimensione degli indici [s,t] , cioè. ts+1 .

Sfida

Dato un profilo di altezza (sequenza di numeri interi non negativi), il tuo compito è determinare la larghezza della valle più ampia.

Esempio

Dato il profilo di altezza [1,2,3,2,2,2,2,3,2,1,0,0,1,2,2,3,3,3,4,3,2,2,1,1,1,2], possiamo visualizzarlo come prima:

4                   _
3   _    _       __/ \
2  / \__/ \    _/     \_   /
1 /        \  /         \_/
0           \/
  12322223210012233343221112
    aaaaaa             ccccc
         bbbbbbbbb

Nota come la seconda valle [3,2,1,0,0,1,2,2,3]non si estende ulteriormente a destra perché il punto più a sinistra è 3 e non 4 . Inoltre non aggiungiamo i restanti due 3 s perché richiediamo che l'endpoint sia più alto rispetto al penultimo punto.

Pertanto la larghezza della valle più ampia è 9 .

Regole

  • L'input sarà una sequenza di numeri interi non negativi (mi dispiace per gli olandesi)
    • puoi presumere che ci sia sempre almeno una valle
  • L'output sarà la dimensione della valle più ampia come definito sopra

Casi test

[4,0,4] -> 3
[1,0,1,0,1] -> 3
[1,0,2,0,1,2] -> 4
[13,13,13,2,2,1,0,1,14,2,13,14] -> 4
[1,2,3,2,2,2,2,3,2,1,0,0,1,2,2,3,3,3,4,3,2,2,1,1,1,2] -> 9
[3,2,0,1,0,0,1,3] -> 4

2
Test case: [3,2,0,1,0,0,1,3]. Tutte le risposte attuali restituiscono 8, secondo la tua definizione credo che dovrebbe essere 4.
Zgarb

La pendenza della montagna sarà mai più ripida di 1? (es. [3,1,2,3])
Maniglia della porta

@Zgarb: esatto, sì. L'ho aggiunto alle prove.
ბიმო

@Doorknob: non c'è nulla che lo impedisca, sì. Ad esempio [4,0,4]sarebbe un caso del genere.
ბიმო

1
"L' input sarà una sequenza di numeri interi non negativi (mi dispiace per gli olandesi) " Lol, come un olandese ho ridacchiato quando ho letto questo. ;)
Kevin Cruijssen,

Risposte:


3

Gelatina , 15 byte

ẆµIṠḟ0ṢƑaMIḢ)Ṁ‘

Provalo online!

Oppure vedi una suite di test (aggiunti altri due casi di test che in precedenza non avevo soddisfatto).

Come?

ẆµIṠḟ0ṢƑaMIḢ)Ṁ‘ - Link: list of integers
Ẇ               - all contiguous substrings
 µ          )   - for each substring, X:
  I             -   deltas
   Ṡ            -   sign (-ve:-1, 0:0, +ve:1)
    ḟ0          -   filter out zeros
       Ƒ        -   is invariant under:
      Ṣ         -     sort
         M      -   get maximal indices of X
        a       -   (vectorising) logical AND
          I     -   deltas
           Ḣ    -   head
             Ṁ  - maximum
              ‘ - increment

3

JavaScript (ES6), 111 108 99 97 byte

a=>a.map(o=(p,x)=>a.some(P=q=>(~x?x<0?i?q<P:q>P&&i++:i=0:q>=p)||(o=o<--x|q==P|q-p?o:x,P=q,0)))|-o

Provalo online!

Commentate

a =>                        // a[] = input array
  a.map(o =                 // initialize the output o to a non-numeric value
    (p, x) =>               // for each value p at position x in a[]:
    a.some(P =              //   initialize P to a non-numeric value
      q =>                  //   for each value q in a[]:
      (                     //     exit if something goes wrong:
        ~x ?                //       if x is not equal to -1:
          x < 0 ?           //         if x is negative:
            i ?             //           if we're in the increasing part:
              q < P         //             exit if q is less than P
            :               //           else:
              q > P && i++  //             increment i if q is greater than P
          :                 //         else:
            i = 0           //           initialize i to 0 (decreasing part)
        :                   //       else:
          q >= p            //         exit if q is greater than or equal to p
      ) || (                //     if we didn't exit:
        o =                 //       update the output o:
          o < --x |         //         decrement x; if o is less than x
          q == P |          //         or the last value is equal to the previous one
          q - p ?           //         or the last value is not equal to the first one
            o               //           leave o unchanged
          :                 //         else:
            x,              //           update o to x
        P = q,              //       update the previous value P to q
        0                   //       force this iteration to succeed
      )                     //
    )                       //   end of some()
  ) | -o                    // end of map(); return -o

3

Python 2 , 120 115 89 87 86 152 149 byte

lambda a:max(r-l+1for l,v in e(a)for r,w in e(a)if max(a[l+1:r]+[0])<v==w*any(s(a[l:i])[::-1]+s(a[i:r])==a[l:r]for i,_ in e(a)));e=enumerate;s=sorted

Provalo online!


1

Retina 0.8.2 , 77 byte

\d+
$*
M&!`\b(1+),((?!\1)(?!1+\2)1*,)+((?!\1)1*(?(3)\3|\2))*\1\b
1

O^`
\G,|$

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

\d+
$*

Converti in unario.

M&!`

Elenca, anziché contare, corrispondenze sovrapposte.

\b(1+),

L'inizio della valle è catturato in \1. Questo non deve quindi corrispondere di nuovo fino alla fine. Poiché non catturiamo la virgola, ciò impedisce anche la corrispondenza di valori più alti.

((?!\1)(?!1+\2)1*,)+

Abbina i valori decrescenti. L' (?!1+\2)impedisce la qualsiasi passaggio attraverso il ciclo da essere maggiore del precedente. (La prima volta \2non è impostato, quindi non riesce a corrispondere in modo banale.) La cattura include la virgola finale poiché è più golfista.

((?!\1)1*(?(3)\3|\2))*

Abbina i valori crescenti. Questa volta ((?3)\3|\2)significa che ogni corrispondenza deve essere almeno lunga quanto il valore precedente o l'ultima acquisizione decrescente la prima volta attraverso il ciclo.

\1\b

Infine, la fine della valle deve avere la stessa altezza della partenza.

1

Elimina le altezze, lasciando le virgole. (Questo è leggermente più semplice del conteggio delle altezze poiché alcuni potrebbero essere zero.)

O^`

Ordinare in ordine inverso, ovvero prima la maggior parte delle virgole.

\G,|$

Contare il numero di virgole sulla prima riga, più uno.


1

Buccia , 13 byte

→▲mΓ€fȯΛEtġ≤Q

Provalo online!

Spiegazione

Uso un algoritmo simile a Jonathan Allan .

→▲mΓ€fȯΛEtġ≤Q  Input is a list, say [3,1,0,1,1,0,2,3]
            Q  Nonempty slices: [[3],[1],[3,1],[0],...,[3,1,0,1,1,0,2,3]]
     f         Keep those that satisfy this:
                Argument is a slice, say [3,1,0,1,1,0,2]
          ġ≤    Cut into non-increasing pieces: [[3,1,0],[1,1,0],[2]]
         t      Drop first piece: [[1,1,0],[2]]
      ȯΛ        Each remaining piece
        E       has all elements equal: false, [1,1,0] has different elements
  m            Map over remaining slices:
                Argument is a slice, say [1,0,1,1]
   Γ            Break into head 1 and tail [0,1,1]
    €           Index of first occurrence of head in tail: 2
 ▲             Maximum: 2
→              Increment: 3

0

Japt , 31 byte

¡ãYÄÃrc k_ò< Åd_äa x}îbZvÃrÔ+2

Provalo online!

Hai salvato 10 byte prendendo ispirazione dalla risposta Husk di Zgarb. Penso ancora che questo possa essere migliorato, ma non l'ho ancora trovato.

Spiegazione:

¡ãYÄÃrc                            Get all segments
        k_           Ã             Remove ones where:
          ò<                        A non-increasing sub-segment
             Å                      Other than the first one
              d_äa x}               Has different heights
                      ®   Ã        For each remaining segment:
                       bZv          Get the second index of the first character
                           rÔ      Maximum
                             +2    Increase by 2
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.