Le graphique toujours croissant

23

Considérons une séquence unidimensionnelle de nombres dans une plage fixe, c'est-à-dire

[1, 2, 4, 6, 8, 0, 2, 7, 3] in range [0, 10⟩

Le graphique toujours croissant * ** est une ligne qui relie tous les points de cette séquence de gauche à droite, et monte toujours ou reste au niveau. Si nécessaire, la ligne s'enroule de haut en bas et continue de monter à partir de là pour atteindre le point suivant.

Le but de ce défi est de diviser la séquence en différentes sous-séquences qui ne sont pas toutes décroissantes, de sorte que lorsqu'elles sont tracées avec un axe vertical limité, elles formeront un graphique toujours croissant. Cela se fait en ajoutant un point a à la fin d'une sous-séquence et au début de la sous-séquence suivante, de sorte que l'angle de la ligne qui traverse la limite supérieure s'aligne avec la ligne qui traverse la limite inférieure et les deux points de croisement ont la même coordonnée horizontale. L'exemple ci-dessus donnerait la sortie suivante:

[1, 2, 4, 6, 8, 10]
[-2, 0, 2, 7, 13]
[-3, 3]

Et le graphique correspondant se présente comme suit: Le graphique toujours croissant qui devrait en fait être appelé le graphique toujours croissant Et avec l'axe étendu pour une meilleure vue: Graphique toujours croissant qui devrait en fait être appelé graphique jamais décroissant avec un axe vertical étendu. La sortie requise est une liste de sous-séquences qui forment les parties du graphique toujours croissant. Faire un complot n'est pas obligatoire mais vous rapportera des points bonus;). La sortie doit clairement séparer les sous-séquences d'une manière ou d'une autre.

Remarques

  • La plage aura toujours zéro comme limite gauche (incluse) et la limite droite sera un entier N.
  • La séquence ne contiendra jamais de valeurs qui ne sont pas dans la plage.
  • La première sous-séquence n'a pas de point supplémentaire au début.
  • La dernière sous-séquence n'a pas de point supplémentaire à la fin.
  • Il n'est pas nécessaire de fournir les indices de départ qui seraient nécessaires pour tracer les sous-séquences.

Cas de test

Input: [0, 2, 4, 6, 1, 3, 5, 0], 7
Output: [0, 2, 4, 6, 8], [-1, 1, 3, 5, 7], [-2, 0]
Input: [1, 1, 2, 3, 5, 8, 3, 1], 10
Output: [1, 1, 2, 3, 5, 8, 13],[-2, 3, 11],[-7, 1]
Input: [5, 4, 3, 2, 1], 10
Output: [5, 14],[-5, 4, 13],[-6, 3, 12],[-7, 2, 11],[-8, 1]
Input: [0, 1, 4, 9, 16, 15, 0], 17
Output: [0, 1, 4, 9, 16, 32], [-1, 15, 17], [-2, 0]

Notation

C'est le code-golf, le code le plus court en octets gagne.

* Pas de jargon réel ** En fait, devrait être appelé Ever Non-Decraining Graph, comme l'a souligné @ngm, mais cela semble moins impressionnant.

RvdV
la source
7
Bienvenue chez PPCG! Joli premier défi!
AdmBorkBork
1
On dirait que j'ai mal compris une partie du défi. Je pense que cela devrait être ce que vous vouliez.
user202729
1
Pouvez-vous étendre l'axe y dans votre exemple de graphique en dessous de 0 et au-dessus de 10 pour rendre le défi plus facile à comprendre?
JayCe
@JayCe Oui, bonne suggestion.
RvdV
2
Le deuxième cas de test suggère que vous souhaitiez que les séquences ne diminuent pas, au lieu d'augmenter? En d'autres termes, une valeur répétée dans l'entrée n'arrête pas cette sous-séquence actuelle, et si les deux dernières valeurs dans une sous-séquence sont égales à l '"angle" pour démarrer la sous-séquence suivante est 0 (il commencerait donc par une valeur répétée ainsi que)?
ngm

Réponses:

8

R , 179 158 151 octets

function(s,m){p=1;t=c(which(diff(s)<0),length(s));for(i in t){d=c(s[p]-m,s[(p+1):i],s[i+1]+m);if(p==1)d[1]=s[1];if(p==t[-1])d=head(d,-1);print(d);p=i}}

Essayez-le en ligne!

Edit: Le code est maintenant une fonction et prend une entrée. (Merci à Giuseppe, user202729 et JayCe pour l'avoir signalé calmement)
Edit: -21 octets suggérés par Giuseppe.
Modifier: -7 octets en supprimant d=NULL;.

Pennsylvanie
la source
1
bienvenue chez PPCG! Cette réponse n'est actuellement pas valide car elle doit prendre des données d'une certaine manière (elles sont actuellement codées en dur dans l'environnement). De plus, vous pouvez trouver ces conseils pour jouer au golf dans R utiles. N'hésitez pas à me cingler ici ou dans le chat une fois que vous aurez assez de réputation!
Giuseppe
Juste pour être clair sur ce qui serait une soumission valable: ce serait . Bienvenue et profitez de votre temps ici :)
JayCe
Je pense que s[p+1]-((m+s[p+1])-s[p])simplifie s[p]-m, et vous avez d=c(c(...))où seulement d=c(...)est nécessaire. Je soupçonne fortement qu'il y a une façon golfique mais c'est toujours une bonne réponse.
Giuseppe
1
@PA doit-il dmême être initialisé?
JayCe
1
@PA heureux de vous aider! Je viens de rouvrir un salon de golf R alors n'hésitez pas à me contacter et à tous les autres golfeurs R pour des questions spécifiques que vous pourriez avoir :-)
Giuseppe
6

Python 2 , 60 octets

L'entrée est N, suivie de tous les points comme arguments individuels. Les séquences de sortie sont séparées par 0.5.

f=lambda N,k,*l:(k,)+(l and(l[0]+N,.5,k-N)*(l[0]<k)+f(N,*l))

Essayez-le en ligne!


Python 2 , 92 77 68 octets

Les suites sont séparées par [...].

l,N=input();r=[];k=0
for a in l:r+=[a+N,r,k-N]*(a<k)+[a];k=a
print r

Essayez-le en ligne!

ovs
la source
1
Bonne réponse! J'aime vraiment l'utilisation de la variable k pour ajouter des éléments de manière sélective, j'ai appris quelque chose de nouveau ici!
RvdV
4

Propre , 279 269 258 octets

import StdEnv
s=snd o unzip
$[]=[]
$l#(a,b)=span(uncurry(<))(zip2[-1:l]l)
=[s a: $(s b)]
?l n#[h:t]= $l
=[h:if(t>[])(?(map((+)n)(flatten t))n)t]
@l n#l= ?l n
=[[e-i*n\\e<-k]\\k<-[a++b++c\\a<-[[]:map(\u=[last u])l]&b<-l&c<-tl(map(\u=[hd u])l)++[[]]]&i<-[0..]]

Essayez-le en ligne!

Οurous
la source
4

Haskell, 82 81 80 octets

Ceci est un portage de ma réponse Clean .

r!n|let f x(r@(a:_):s)|x>a=[x,n+a]:(x-n:r):s|y<-x:r=y:s=foldr f[[last r]]$init r

Essayez-le en ligne!

-1, -1 grâce à Laikoni


la source
@Laikoni c'est dommage que nous ne puissions pas définir flocalement sans parenthèses autour du :motif, comme dans let x<r@(a:_):s|....
3

Nettoyer , 92 octets

import StdEnv
@r n=foldr(\x[r=:[a:_]:s]|x>a=[[x,n+a]:[x-n:r]:s]=[[x:r]:s])[[last r]](init r)

Essayez-le en ligne!

L'argument opérateur de foldrest un lambda avec garde; il est analysé comme:

\x [r=:[a:_]:s]
    | x > a     = [[x,n+a]:[x-n:r]:s]
    | otherwise = [[x:run]:s]

J'ai porté cela à Haskell .


la source
2

Clean , 110 109 104 100 97 bytes

import StdEnv
@[x:r]n=let$s=:[x:r]a|x<last a=[a++[n+x]: $s[last a-n]]= $r(a++[x]);$_ a=[a]in$r[x]

Essayez-le en ligne!

-1 octet grâce à Keelan

Laikoni
la source
1

JavaScript (Node.js) , 98 octets

a=>m=>(r=[],b=[],a.map((e,i)=>e<a[--i]?(b[p](m+e),r[p](b),b=[a[i]-m,e]):b[p='push'](e)),r[p](b),r)

Essayez-le en ligne!C'est un peu plus long que l'autre réponse JS, mais il utilise une approche différente.

Explication non golfée et simplifiée

g=(a,m)=>{
    // r is the final array of arrays to return.
    // b is the current subset of only ascending numbers.
    r=[],b=[];

    a.map((e,i)=>{
        if(e<a[i-1]){
            // if the current value is less than the previous one,
            // then we're descending, so start a new array b.
            // add the proper value to b to match slopes with the next
            b.push(m+e);
            // add r to b, and restart b with the starter value and the current value in a
            r.push(b);
            b=[a[i-1]-m,e];
        } else{
            // otherwise, we're ascending, so just addd to to b.
            b.push(e);
        }
    });
    r.push(b); // add the final b to r, and return r
    return r;
}
NinjaBearMonkey
la source