Déterminer la vallée la plus large


12

Imaginez que nous obtenions une tranche d'une région montagneuse, cela donnerait une forme similaire à ceci:

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

Comme nous pouvons le voir, nous pouvons représenter cela (dans une certaine mesure) avec une séquence d'entiers.

Aux fins de ce défi, nous définissons une vallée comme une sous-séquence contiguë où les valeurs diminuent initialement et à partir d'un certain point elles augmentent. Plus formellement pour une séquence (ai)i=1n une vallée sera des indices 1s<r<tn pour lesquels:

  • le début et la fin de la vallée sont les mêmes: as=at
  • la vallée commence et se termine une fois la région plus basse: as>as+1at1<at
  • la vallée n'est pas plate: asararat
  • la vallée décroît initialement: i[s,r):aiai+1
  • la vallée augmentera à un moment donné: j[r,t):ajaj+1

Maintenant, nous définissons la largeur d'une telle vallée comme la taille des indices [s,t] , ie. ts+1 .

Défi

Étant donné un profil de hauteur (séquence d'entiers non négatifs), votre tâche consiste à déterminer la largeur de la vallée la plus large.

Exemple

Compte tenu du profil de hauteur [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], nous pouvons le visualiser comme précédemment:

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

Notez que la deuxième vallée [3,2,1,0,0,1,2,2,3]ne s'étend pas plus à droite car le point le plus à gauche est 3 et non 4 . De plus, nous n'ajoutons pas les deux 3 s restants car nous exigeons que le point final soit plus haut que l'avant-dernier point.

Par conséquent, la largeur de la vallée la plus large est de 9 .

Règles

  • L'entrée sera une séquence d'entiers non négatifs (désolé pour les Néerlandais)
    • vous pouvez supposer qu'il y a toujours au moins une vallée
  • La sortie sera la taille de la vallée la plus large définie ci-dessus

Cas de 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
Cas de test: [3,2,0,1,0,0,1,3]. Toutes les réponses actuelles renvoient 8, selon votre définition, je pense que cela devrait être 4.
Zgarb

La pente de la montagne sera-t-elle jamais plus raide que 1? (ex. [3,1,2,3])
Poignée de porte

@Zgarb: C'est exact, oui. Je l'ai ajouté aux testcases.
ბიმო

@ Doorknob: Rien n'empêche cela, oui. Par exemple [4,0,4]serait un tel cas.
ბიმო

1
"L' entrée sera une séquence d'entiers non négatifs (désolés, les Néerlandais) " Lol, en tant que Néerlandais, j'ai gloussé en lisant ceci. ;)
Kevin Cruijssen

Réponses:


3

Gelée , 15 octets

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

Essayez-le en ligne!

Ou voir une suite de tests (ajout de deux cas de test supplémentaires que je n'ai pas réussi à remplir auparavant).

Comment?

Ẇµ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 octets

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

Essayez-le en ligne!

Commenté

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 octets

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

Essayez-le en ligne!


1

Retina 0.8.2 , 77 octets

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

O^`
\G,|$

Essayez-le en ligne! Le lien inclut des cas de test. Explication:

\d+
$*

Convertissez en unaire.

M&!`

Liste, plutôt que de compter, les correspondances qui se chevauchent.

\b(1+),

Le début de la vallée est capturé \1. Cela ne doit alors plus correspondre jusqu'à la fin. Comme nous ne capturons pas la virgule, cela empêche également les valeurs plus élevées de correspondre.

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

Faites correspondre les valeurs décroissantes. Le (?!1+\2)empêche tout passage à travers la boucle d'être supérieur au précédent. (La première fois \2que le processus n'est pas défini, il ne correspond pas de manière triviale.) La capture inclut la virgule de fin car c'est golfier.

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

Faites correspondre les valeurs croissantes. Ce temps ((?3)\3|\2)signifie que chaque correspondance doit être au moins aussi longue que la valeur précédente, ou la dernière capture décroissante la première fois dans la boucle.

\1\b

Enfin, la fin de la vallée doit être à la même hauteur que le début.

1

Supprimez les hauteurs en laissant les virgules. (C'est un peu plus facile que de compter les hauteurs car certaines peuvent être nulles.)

O^`

Trier dans l'ordre inverse, c'est-à-dire la plupart des virgules en premier.

\G,|$

Comptez le nombre de virgules sur la première ligne, plus un.


1

Husk , 13 octets

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

Essayez-le en ligne!

Explication

J'utilise un algorithme similaire à 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 octets

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

Essayez-le en ligne!

Enregistré 10 octets en s'inspirant de la réponse Husk de Zgarb. Je pense toujours que cela peut être amélioré, mais je ne l'ai pas encore trouvé.

Explication:

¡ã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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.