Ciągle rosnący wykres

23

Rozważ jednowymiarową sekwencję liczb w ustalonym zakresie, tj

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

Ciągle rosnący wykres * ** to linia, która łączy wszystkie punkty w tej sekwencji od lewej do prawej i zawsze idzie w górę lub utrzymuje poziom. W razie potrzeby linia owija się od góry do dołu i stamtąd idzie w górę, aby osiągnąć następny punkt.

Celem tego wyzwania jest podzielenie sekwencji na różne podsekwencje, z których wszystkie nie maleją, tak aby po wykreśleniu razem z ograniczoną osią pionową utworzyły one stale rosnący wykres. Odbywa się to poprzez dodanie punktu na końcu jednej podsekwencji i na początku następnej podsekwencji, tak aby kąt linii przecinającej górną granicę był wyrównany z linią przecinającą dolną granicę i dwoma punktami przecięcia mają tę samą współrzędną poziomą. Powyższy przykład dałby następujące dane wyjściowe:

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

Odpowiedni wykres będzie wyglądał następująco: Wykres stale rosnący, który powinien być nazywany wykresem nieustannym A z rozszerzoną osią dla lepszego widoku: Ciągle rosnący wykres, który w rzeczywistości powinien być nazywany ciągłym nieskalującym wykresem z rozszerzoną osią pionową. Wymaganym wynikiem jest lista podsekwencji, które tworzą części stale rosnącego wykresu. Robienie fabuły nie jest wymagane, ale zapewni ci punkty bonusowe;). Wynik musi w jakiś sposób wyraźnie oddzielić podsekwencje.

Notatki

  • Zakres będzie zawsze miał zero jako lewą (włącznie) granicę, a prawa granica będzie liczbą całkowitą N.
  • Sekwencja nigdy nie będzie zawierać wartości, które nie mieszczą się w zakresie.
  • Pierwsza podsekwencja nie ma na początku dodatkowego punktu.
  • Ostatni podsekwencja nie ma na końcu dodatkowego punktu.
  • Nie jest wymagane podawanie początkowych wskaźników, które byłyby wymagane do wykreślenia podsekwencji.

Przypadki testowe

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]

Punktacja

To jest code-golf, wygrywa najkrótszy kod w bajtach.

* Nie rzeczywisty żargon ** Tak naprawdę, jak wskazał @ngm, powinien się nazywać „Zawsze nie malejącym wykresem”, ale brzmi to mniej imponująco.

RvdV
źródło
7
Witamy w PPCG! Ładne pierwsze wyzwanie!
AdmBorkBork
1
Wygląda na to, że źle zrozumiałem część wyzwania. Myślę, że tak powinno być.
user202729
1
Czy możesz przedłużyć oś Y na przykładowym wykresie poniżej 0 i powyżej 10, aby łatwiej zrozumieć wyzwanie?
JayCe
@JayCe Tak, dobra sugestia.
RvdV,
2
Drugi przypadek testowy sugeruje, że zamierzasz nie zmniejszać sekwencji, a nie zwiększać? Innymi słowy, powtarzana wartość na wejściu nie zatrzymuje tej bieżącej podsekwencji, a jeśli dwie ostatnie wartości w podsekwencji są równe niż „kąt”, aby rozpocząć kolejną podsekwencję to 0 (więc zaczynałaby się od powtarzanej wartości także)?
ngm

Odpowiedzi:

8

R , 179 158 151 bajtów

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}}

Wypróbuj online!

Edycja: Kod jest teraz funkcją i wymaga danych wejściowych. (Podziękowania dla Giuseppe, user202729 i JayCe za spokojne wskazanie tego)
Edycja: -21 bajtów sugerowanych przez Giuseppe.
Edytuj: -7 bajtów przez usunięcie d=NULL;.

ROCZNIE
źródło
1
Witamy w PPCG! Ta odpowiedź jest obecnie nieprawidłowa, ponieważ musi w jakiś sposób pobierać dane wejściowe (obecnie są zakodowane na stałe w środowisku). Ponadto pomocne mogą być te wskazówki dotyczące gry w golfa w języku R. Zapraszam do pingowania mnie tutaj lub na czacie, gdy zdobędziesz wystarczającą reputację!
Giuseppe,
Aby wyjaśnić, co byłoby prawidłowym oświadczeniem: tak właśnie będzie . Witaj i baw się dobrze tutaj :)
JayCe
Myślę, że to s[p+1]-((m+s[p+1])-s[p])upraszcza s[p]-m, a ty masz d=c(c(...))tylko tam, gdzie d=c(...)jest to wymagane. Podejrzewam, że istnieje bardziej golfowy sposób, ale wciąż jest to dobra odpowiedź.
Giuseppe,
1
@ PA wymaga dnawet inicjalizacji?
JayCe
1
@ PA chętnie pomoże! Właśnie otworzyłem czat do gry w golfa w R, więc skontaktuj się ze mną i wszystkimi innymi golfistami z R w sprawie konkretnych pytań :-)
Giuseppe
6

Python 2 , 60 bajtów

Dane wejściowe to N, po których wszystkie punkty są pojedynczymi argumentami. Kolejności w danych wyjściowych są rozdzielane przez 0.5.

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

Wypróbuj online!


Python 2 , 92 77 68 bajtów

Kolejności są rozdzielone przez [...].

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

Wypróbuj online!

ovs
źródło
1
Niezła odpowiedź! Bardzo podoba mi się użycie zmiennej k do selektywnego dodawania elementów, tutaj dowiedziałem się czegoś nowego!
RvdV
4

Czysty , 279 269 258 bajtów

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..]]

Wypróbuj online!

Obrzydliwe
źródło
4

Haskell, 82 81 80 bajtów

To jest część mojej czystej odpowiedzi .

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

Wypróbuj online!

-1, -1 dzięki Laikoni


źródło
@Laikoni szkoda, że ​​nie możemy zdefiniować flokalnie bez nawiasów wokół :wzorca, jak w let x<r@(a:_):s|....
3

Czysty , 92 bajty

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)

Wypróbuj online!

Argumentem operatora foldrjest lambda z osłoną; jest analizowany jako:

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

Przeniesiłem to do Haskell .


źródło
2

Czysty , 110 109 104 100 97 bajtów

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]

Wypróbuj online!

-1 bajt dzięki Keelan

Laikoni
źródło
1

JavaScript (Node.js) , 98 bajtów

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)

Wypróbuj online! Jest to nieco dłużej niż w przypadku innej odpowiedzi JS, ale wykorzystuje inne podejście.

Nieskluczone i uproszczone wyjaśnienie

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
źródło