Постоянно увеличивающийся график

23

Рассмотрим одномерную последовательность чисел в фиксированном диапазоне, т.е.

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

Постоянно увеличивающийся график * ** - это линия, которая соединяет все точки в этой последовательности слева направо и всегда идет вверх или остается на одном уровне. Если необходимо, линия оборачивается сверху вниз и продолжает идти оттуда, чтобы встретить следующую точку.

Цель этой задачи состоит в том, чтобы разбить последовательность на разные подпоследовательности, которые все не уменьшаются, чтобы при построении графика вместе с ограниченной вертикальной осью они образовали постоянно увеличивающийся график. Это делается путем добавления точки в конец одной подпоследовательности и в начало следующей подпоследовательности, чтобы угол линии, пересекающей верхнюю границу, совпадал с линией, пересекающей нижнюю границу, и двумя точками пересечения имеют одинаковую горизонтальную координату. Приведенный выше пример даст следующий результат:

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

И соответствующий график будет выглядеть следующим образом: Вечно увеличивающийся граф, который на самом деле следует называть вечно неубывающим графом И с осью, расширенной для лучшего обзора: Постоянно увеличивающийся график, который на самом деле следует называть постоянно неубывающим графиком с расширенной вертикальной осью. Требуемый вывод - это список подпоследовательностей, которые образуют части постоянно увеличивающегося графика. Создание сюжета не обязательно, но вы заработаете бонусные баллы;). Выходные данные должны каким-то образом четко отделять подпоследовательности.

Заметки

  • Диапазон всегда будет иметь ноль в качестве левой (включительно) границы, а правой границей будет некоторое целое число N.
  • Последовательность никогда не будет содержать значений, которые не находятся в пределах диапазона.
  • Первая подпоследовательность не имеет дополнительной точки в начале.
  • Последняя подпоследовательность не имеет дополнительной точки в конце.
  • Не требуется указывать начальные индексы, которые потребуются для построения подпоследовательностей.

Контрольные примеры

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]

счет

Это код-гольф, выигрывает самый короткий код в байтах.

* Не фактический жаргон ** На самом деле должен называться Ever Non-Decreasing Graph, как указал @ngm, но это звучит менее впечатляюще.

RVDV
источник
7
Добро пожаловать в PPCG! Хороший первый вызов!
AdmBorkBork
1
Похоже, что я неправильно понял некоторую часть проблемы. Я думаю, что это должно быть то, что вы хотели.
user202729
1
Можете ли вы расширить ось Y на вашем образце графика ниже 0 и выше 10, чтобы облегчить понимание задачи?
JayCe
@JayCe Да, хорошее предложение.
RvdV
2
Второй тестовый пример предполагает, что вы хотите, чтобы последовательности были неубывающими, а не увеличивались? Другими словами, повторяющееся значение на входе не останавливает эту текущую подпоследовательность, и если два последних значения в подпоследовательности равны «углу», для начала следующая подпоследовательность равна 0 (поэтому оно будет начинаться с повторного значения также)?
НГМ

Ответы:

8

R , 179 158 151 байт

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

Попробуйте онлайн!

Редактировать: код теперь является функцией и принимает ввод. (Спасибо Giuseppe, user202729 и JayCe за спокойное указание на это)
Редактировать: -21 байт, предложенный Giuseppe.
Изменить: -7 байт, удалив d=NULL;.

Пенсильвания
источник
1
Добро пожаловать в PPCG! Этот ответ в настоящее время недействителен, поскольку он должен каким-либо образом принимать данные (в настоящее время они жестко закодированы в среде). Кроме того, вы можете найти эти советы для игры в гольф в R полезными. Не стесняйтесь пинговать меня здесь или в чате, как только вы получите достаточно репутации!
Джузеппе
Просто чтобы быть ясно, что будет правильным представлением: это будет . Добро пожаловать и приятного
времяпровождения
Я думаю, что s[p+1]-((m+s[p+1])-s[p])упрощает s[p]-m, и у вас, d=c(c(...))где только d=c(...)требуется. Я сильно подозреваю, что есть путь к игре в гольф, но это все еще хороший ответ.
Джузеппе
1
@PA dдаже нужно инициализировать?
JayCe
1
@PA рады помочь! Я только что вновь открыл чат для игры в гольф R, так что не стесняйтесь обращаться ко мне и всем другим игрокам в R по конкретным вопросам, которые у вас могут возникнуть :-)
Giuseppe
6

Python 2 , 60 байт

Ввод N, за которым следуют все точки в качестве отдельных аргументов. Подпоследовательности в выходных данных разделены 0.5.

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

Попробуйте онлайн!


Python 2 , 92 77 68 байт

Подпоследовательности разделены [...].

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

Попробуйте онлайн!

овс
источник
1
Хороший ответ! Мне очень нравится использование переменной k для выборочного добавления элементов, здесь я узнал что-то новое!
RvdV
4

Чистый , 279 269 258 байт

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

Попробуйте онлайн!

Οurous
источник
3

Чисто , 92 байта

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)

Попробуйте онлайн!

Аргументом оператора foldrявляется лямбда с защитой; он анализируется как:

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

Я перенес это на Хаскелл .


источник
1

JavaScript (Node.js) , 98 байт

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)

Попробуйте онлайн! Это немного длиннее, чем в другом ответе JS, но использует другой подход.

Неуправляемое и упрощенное объяснение

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
источник