Determinar el valle más ancho

12

Imagine que obtenemos una porción de una región montañosa, esto daría como resultado una forma similar a esta:

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

Como podemos ver, podemos representar esto (hasta cierto punto) con una secuencia de enteros.

Para el propósito de este desafío, definimos un valle como una subsecuencia contigua donde los valores inicialmente están disminuyendo y desde algún punto están aumentando. Más formalmente para una secuencia un valle será índices para los cuales se cumple lo siguiente:(ai)i=1n1s<r<tn

  • El inicio y el punto final del valle son los mismos:as=at
  • el valle comienza y termina una vez que la región baja:as>as+1at1<at
  • el valle no es plano:asararat
  • el valle inicialmente disminuye:i[s,r):aiai+1
  • el valle aumentará en algún momento:j[r,t):ajaj+1

Ahora definimos el ancho de dicho valle como el tamaño de los índices , es decir. .[s,t]ts+1

Desafío

Dado un perfil de altura (secuencia de enteros no negativos), su tarea es determinar el ancho del valle más ancho.

Ejemplo

Dado el perfil de altura [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], podemos visualizarlo como antes:

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

Observe cómo el segundo valle [3,2,1,0,0,1,2,2,3]no se extiende más hacia la derecha porque el punto más a la izquierda es y no . Además, no agregamos los dos s restantes porque requerimos que el punto final esté más arriba que el segundo y último punto.343

Por lo tanto, el ancho del valle más ancho es .9

Reglas

  • La entrada será una secuencia de enteros no negativos (lo siento, holandeses)
    • puedes asumir que siempre hay al menos un valle
  • La salida será el tamaño del valle más ancho como se definió anteriormente

Casos de prueba

[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
ბიმო
fuente
2
Caso de prueba: [3,2,0,1,0,0,1,3]. Todas las respuestas actuales devuelven 8, según su definición, creo que debería ser 4.
Zgarb
¿La pendiente de la montaña será más pronunciada que 1? (p [3,1,2,3]. ej. )
Pomo de la puerta
@ Zgarb: Eso es correcto, sí. Lo agregué a los casos de prueba.
ბიმო
@Doorknob: No hay nada que lo impida, sí. Por ejemplo, [4,0,4]sería un caso así.
ბიმო
1
"La entrada será una secuencia de enteros no negativos (lo siento, holandeses) " Lol, como holandés me reí cuando leí esto. ;)
Kevin Cruijssen

Respuestas:

3

Jalea , 15 bytes

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

Pruébalo en línea!

O vea un conjunto de pruebas (agregué dos casos de prueba más que anteriormente no pude cumplir).

¿Cómo?

Ẇµ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
Jonathan Allan
fuente
3

JavaScript (ES6), 111 108 99 97 bytes

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

Pruébalo en línea!

Comentado

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
Arnauld
fuente
3

Python 2 , 120 115 89 87 86 152 149 bytes

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

Pruébalo en línea!

TFeld
fuente
1

Retina 0.8.2 , 77 bytes

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

O^`
\G,|$

Pruébalo en línea! El enlace incluye casos de prueba. Explicación:

\d+
$*

Convierte a unario.

M&!`

Lista, en lugar de contar, coincidencias superpuestas.

\b(1+),

El comienzo del valle está capturado en \1. Esto no debe volver a coincidir hasta el final. Como no capturamos la coma, esto también evita que los valores más altos coincidan.

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

Empareja los valores decrecientes. Esto (?!1+\2)evita que cualquier paso por el bucle sea mayor que el anterior. (La primera vez \2no está configurada, por lo que no coincide trivialmente). La captura incluye la coma final, ya que es más golfista.

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

Une los valores crecientes. Este tiempo ((?3)\3|\2)significa que cada coincidencia debe ser al menos tan larga como el valor anterior, o la última captura decreciente la primera vez a través del ciclo.

\1\b

Finalmente, el final del valle debe tener la misma altura que el inicio.

1

Eliminar las alturas, dejando las comas. (Esto es un poco más fácil que contar las alturas ya que algunas de ellas podrían ser cero).

O^`

Ordenar en orden inverso, es decir, la mayoría de las comas primero.

\G,|$

Cuente la cantidad de comas en la primera línea, más una.

Neil
fuente
1

Casco , 13 bytes

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

Pruébalo en línea!

Explicación

Yo uso un algoritmo similar al de 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
Zgarb
fuente
0

Japt , 31 bytes

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

Pruébalo en línea!

Ahorré 10 bytes inspirándome en la respuesta Husk de Zgarb. Todavía creo que esto se puede mejorar, pero aún no lo he encontrado.

Explicación:

¡ã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
Kamil Drakari
fuente