Поднять одно число


25

Введение

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

Задание

Ваш ввод представляет собой список целых чисел L , который может быть пустым. Ваш вывод должен быть списком L, где ровно одно число L i было заменено другим L j , где L i <L j и i <j .

Другими словами, вы должны заменить одно число на большее число, которое стоит после него.

Вы можете свободно выбирать i и j среди всех допустимых пар, и выбор может быть недетерминированным.

Если такие i и j не существуют (т. Е. L не увеличивается), ваш вывод должен быть L без изменений.

пример

Рассмотрим вход L = [3, 1, 4, -1, 2] . Возможные операции: заменить 3 на 4 , заменить 1 на 4 , заменить 1 на 2 или заменить -1 на 2 . Таким образом, возможными выходами являются:

 [  3 ,   1 ,   4 ,  -1 ,   2 ]
 ------------------------------
 [( 4),   1 ,(  4),  -1 ,   2 ]
 [  3 ,(  4),(  4),  -1 ,   2 ]
 [  3 ,(  2),   4 ,  -1 ,(  2)]
 [  3 ,   1 ,   4 ,(  2),(  2)]

Если вы повторите операцию достаточно много раз, то конечный результат будет [4,4,4,2,2] , что именно список хвостовых максимумов L .

Правила и оценки

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

Побеждает самое низкое число байтов.

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

Все возможные выходы показаны.

[] -> []
[1] -> [1]
[1,2] -> [2,2]
[2,1] -> [2,1]
[4,4,4,4] -> [4,4,4,4]
[-1,-3,-10] -> [-1,-3,-10]
[1,3,10] -> [3,3,10] [10,3,10] [1,10,10]
[1,1,2,1] -> [2,1,2,1] [1,2,2,1]
[998,64,2,-94,-789] -> [998,64,2,-94,-789]
[998,2,64,-94,-789] -> [998,64,64,-94,-789]
[3,1,4,-1,2] -> [4,1,4,-1,2] [3,4,4,-1,2] [3,2,4,-1,2] [3,1,4,2,2]
[-1,4,0,4,7,2,3] -> [4,4,0,4,7,2,3] [0,4,0,4,7,2,3] [-1,4,4,4,7,2,3] [7,4,0,4,7,2,3] [-1,7,0,4,7,2,3] [-1,4,7,4,7,2,3] [-1,4,0,7,7,2,3] [2,4,0,4,7,2,3] [-1,4,2,4,7,2,3] [3,4,0,4,7,2,3] [-1,4,3,4,7,2,3] [-1,4,0,4,7,3,3]
[3542,-12311,7662,1672,6081] -> [7662,-12311,7662,1672,6081] [3542,7662,7662,1672,6081] [3542,1672,7662,1672,6081] [6081,-12311,7662,1672,6081] [3542,6081,7662,1672,6081] [3542,-12311,7662,6081,6081]

Ответы:


9

JavaScript (ES6), 41 40 39 38 байт

Сохраненный байт благодаря @Neil, еще одно спасибо @ user81655

x=>x.map(c=>c<x[++i]>d?x[d=i]:c,d=i=0)

Просто, когда кажется, reduceRightчто, наконец, есть шанс, .mapпоявляется снова ...


x=>x.map(c=>c<x[++i]&!d?x[d=i]:c,d=i=0)?
Нил

Условные выражения оцениваются слева направо, что означает x=>x.map(c=>c<x[++i]>d?x[d=i]:c,d=i=0)(38 байт) должно работать.
user81655

@ user81655 Это удивительно :-)
ETHproductions

7

Mathematica, 37 байт

#/.{a___,b_,c_,d___}/;b<c:>{a,c,c,d}&

Чистая функция, принимающая список действительных чисел и возвращающая список действительных чисел. Ищет первую пару последовательных записей в «неправильном» порядке и заменяет первую из этой пары второй. Хорошее поведение по умолчанию /.означает, что он возвращает входные данные без изменений, когда это необходимо.

Забавное примечание: если мы заменим b<cна !OrderedQ[{c,b}], то функция будет работать со строками (и действительно с любым типом данных после описания соответствующего порядка). Например, #/.{a___,b_,c_,d___}/;!OrderedQ[{c,b}]:>{a,c,c,d}&на входе {"programming", "puzzles", "code", "golf"}возвращается {"puzzles", "puzzles", "code", "golf"}.


Предостережение для примечания: каноническое упорядочение строк в Mathematica странно.
Мартин Эндер

Как так, Мартин Эндер?
Грег Мартин

Просто попробуй Sort[FromCharacterCode /@ Range[32, 127]]. Это становится странным, если у вас есть строки с несколькими словами, потому что тогда он игнорирует пробелы и прочее.
Мартин Эндер

6

JavaScript (ES6), 43 39 38 байт

a=>a[a.some(e=>e<a[++i],i=0)*i-1]=a[i]

Выводы путем изменения массива на месте. Редактировать: 4 байта сохранены благодаря @ETHproductions. Сохранено 1 байт благодаря @ user81655.


Я думаю, что вы можете сделать с a=>a[i=0,a.findIndex(e=>e<a[++i])]=a[i]39.
ETHproductions

Еще один подход для 40B:a=>a.map((_,b)=>Math.max(...a.slice(b)))
Лука

@ Люк, я думаю, ты неправильно понимаешь вызов; дело только в том, чтобы увеличить одно из целых чисел в массиве.
ETHproductions

@ETHproductions Спасибо за возвращаемую услугу, теперь почести даже!
Нил

Я думаю , что вы могли бы быть в состоянии заменить findIndexс some(38 байт):a=>a[i=0,a.some(e=>e<a[++i])*i-1]=a[i]
user81655

5

Haskell , 36 байт

f(a:r@(b:_))|a<b=b:r|1>0=a:f r
f e=e

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

Просмотрите список для последовательных элементов a,bс a<bи изменяет их b,b.

Улучшено с 37 байтов:

f(a:b:t)|a<b=b:b:t
f(a:t)=a:f t
f e=e

Я думаю, что f(a:r@(b:_))=max(b:r)(a:f r)работает и на два байта короче.
Орджан Йохансен

@ ØrjanJohansen Это прекрасный метод! Я думаю, что вы должны опубликовать это как свой собственный ответ. Сначала я не был уверен, что он будет правильно обрабатывать связи, но теперь я вижу, что это работает, потому что f r >= r.
xnor

Спасибо, я так и сделал !
Орджан Йохансен,

4

Желе , 13 11 байт

ṫJṀ€ż¹ŒpQ-ị

Заменяет самый правый из всех возможных номеров.

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

Как это работает

ṫJṀ€ż¹ŒpQ-ị  Main link. Argument: A (array)

 J           Yield all indices of A, i.e., the array [1, ..., len(A)].
ṫ            Dyadic tail; for index k, take all elements starting with the k-th.
             This constructs the array of suffixes.
  Ṁ€         Maximum each; map the monadic maximum atom over the suffixes.
     ¹       Identity; yield A.
    ż        Zip; construct all pairs of elements of the result to the left and the
             corresponding elements of the result to the right.
      Œp     Cartesian product. Construct all arrays that, for each index, take
             either the left or the right element.
        Q    Unique; deduplicate the resulting arrays.
         -ị  At-index -1; select the second to last result.
             The last result is A itself, the first maxima of suffixes.


3

Python 2, 139, 134, 93 байта

a=input()
for i in range(len(a)):
 for j in a[i+1:]:
    if a[i]<j:a[i]=j;print a;exit()
print a

Ужасно долго, но это первая попытка.

-5 байт благодаря TemporalWolf
-41 (!!) байт благодаря Value Ink


[1,2]дает [2,1]вместо[2,2]
TemporalWolf

1
@TemporalWolf Да, я неправильно понял вызов. Нет байтов, сохраненных или потерянных, исправит.
HyperNeutrino

Вы можете удалить возврат перед своим внутренним элементом printи использовать \tвкладку вместо дополнительного пространства для внутреннего цикла. Кроме того, вы можете оставить 0 exit()для дополнительного. Должны привести вас к 132.
TemporalWolf

@TemporalWolf Хорошо, спасибо!
HyperNeutrino

1
if a[i]<a[j]:a[i]=a[j];print a;exit()еще короче. Черт возьми, это лучше делатьfor j in a[i+1:]:\n\tif a[i]<j:a[i]=j;print a;exit()
Value Ink

3

MATL , 13 байт

ttd0>fX>Q)2M(

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

объяснение

Следующие два условия эквивалентны:

  1. Существует число, которое имеет большее число справа от него
  2. Существует номер, который имеет большее число сразу справа от него

Код использует условие 2, которое проще. Он вычисляет последовательные приращения и находит последний положительный, если он есть. Для двух задействованных записей записывается значение второй записи в первую.

Этот трюк используется для обработки случая, когда замена не может быть выполнена. Также обратите внимание, что индексирование MATL основано 1на.

Давайте использовать вход [3,1,4,-1,2]в качестве примера.

tt    % Get input implicitly and duplicate it twice
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], [3,1,4,-1,2]
d     % Consecutive differences
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], [-2  3 -5  3]
0>    % Are they positive?
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], [0 1 0 1]
f     % Find indices of all positive differences. Result may be empty
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], [2 4]
X>    % Maximum index with a positive difference. Empty input remains as empty
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], 4
Q     % Add 1. Since the addition is elementwise, empty input remains as empty
      % STACK: [3,1,4,-1,2], [3,1,4,-1,2], 5
)     % Get the entry of the input at that position
      % STACK: [3,1,4,-1,2], 2
2M    % Push maximum index with a positive difference, again
      % STACK: [3,1,4,-1,2], 2, 4
(     % Assign to that position. Implicitly display
      % STACK: [3,1,4,2,2]

3

Haskell , 34 33 байта

Это основано на ответе xnor , который предложил мне опубликовать его самостоятельно.

РЕДАКТИРОВАТЬ: xnor нашел байт для сохранения.

f(a:r@(b:_))=max(b:r)$a:f r
f e=e

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

По сути, я заметил, что ветвление метода xnor всегда заканчивается выбором того, какое из выражений ветвления является наибольшим, поскольку Haskell использует лексикографическое упорядочение для списков. (Случай, когда a==bтакже работает потому f r>=r, что может быть доказано отдельно по индукции.)

Иные слова, всякий раз , когда b:r > a:f r, то b:rесть правильный ответ, а в противном случае мы можем рекурсию a:f r.

Поэтому вместо a<bпредварительной проверки я просто вычисляю оба выражения и беру максимум. Это может привести к экспоненциальному росту, хотя лень Хаскелла избегает этого, если только aи bне равны.


1
Похоже, max(b:r)$a:f rсохраняет байт.
xnor

2

Python 3, 79 байт

def f(x):
 for i,a in enumerate(x):
  m=max(x[i+1:])
  if m>a:x[i]=m;break

Изменяет исходный массив (список), данный ему. Я недоволен, что это не лямбда, и я уверен, что есть лучшие оптимизации; Надеюсь, я расскажу об этом позже.

Краткое объяснение

Он принимает максимум массива после текущего элемента (начиная с нуля). Затем он сравнивает это с самим элементом: если max больше, замените текущий элемент на него и остановите, в противном случае, увеличьте на единицу и продолжайте пробовать это.



2

C, 47 байтов

f(p,n)int*p;{n>1?*p<p[1]?*p=p[1]:f(p+1,n-1):0;}

Рекурсивная реализация, принимающая в качестве входных данных указатель на первый элемент массива и длину массива. Изменяет массив на месте.


Ваш код возврата кажется недействительным ideone.com/83HJqN
Khaled.K

@ Khaled.K Показывает вывод «3 4 4 -1 2», который является одним из разрешенных выходов, приведенных в вопросе. Что вы думаете не так с этим?
17

Я вижу, вопрос совершенно неясен об этом, хотя
Khaled.K

2

SWI-Пролог, 70 байт

f([H|T],[S|T]):-max_list(T,S),S>H,!.
f([H|T],[H|R]):-f(T,R),!.
f(I,I).

Первое предложение заменяет первый элемент списка максимальным значением остальной части списка, но только если этот максимум больше. Второе предложение рекурсивно вызывает предикат для конца списка. Если ни одно из этих предложений не выполняется, третье предложение просто возвращает входные данные.

Это возвращение только одно из возможных решений. Найти их все с очень похожим кодом тривиально, но тогда случай, когда никакие изменения невозможны, требует намного больше байтов для обработки.

Пример:

?- f([-1,4,0,4,7,2,3], O).
O = [7, 4, 0, 4, 7, 2, 3]


1

C, 80 байтов

i,j;f(l,n)int*l;{for(i=0;i<n;++i)for(j=i;++j<n;)if(l[i]<l[j]){l[i]=l[j];j=i=n;}}

Звоните с:

int main()
{
    int a[5]={3,1,4,-1,2};
    f(a,5);
    for(int k=0;k<5;++k)
        printf("%d ", a[k]);
}

1

Python 2, 89 байт

Попробуйте онлайн -1 байт благодаря @TemporalWolf
-25 байт благодаря @ValueInk
-7 байт благодаря @Cole

Функция, которая изменяет входной массив

def F(A):
 for i in range(len(A)):
    r=[y for y in A[i+1:]if y>A[i]]
    if r:A[i]=r[0];break

Если бы не было необходимости останавливаться после первой итерации, это было бы немного красивее


Это, кажется, не работает. Попробуй [1, 3, 5, 7]; это возвращается [3, 3, 5, 7].
HyperNeutrino

1
A[i]<y and=> y>A[i]andсохраняет 1
TemporalWolf

@HyperNeutrino Если я правильно понимаю задачу, то это действительно выход
Мертвый Опоссум

1
Подумайте о том, r=[y for y in A[i+1:]if y>A[i]]\n if r:A[i]=r[0];breakчтобы снизить ваш счет до 96!
Value Ink

1
Могу ли я предложить то, что я предложил для одного из других ответов Python: преобразовать то, что у вас есть, в функцию, которая изменяет исходный массив, чтобы вы могли избежать печати и input().
Коул

1

Python 2, 60 байт

f=lambda x:x and[x[:1]+f(x[1:]),[max(x)]+x[1:]][x[0]<max(x)]

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

Объяснение: Рекурсивно проверяет, меньше ли заданный элемент, чем maxэлемент в остальной части списка. Если это так, возвращает список с maxзаменой первого элемента.


1

TI-Basic, 72 байта

Prompt L1
If 2≤dim(L1
Then
For(A,1,dim(L1)-1
For(B,A,dim(L1
If L1(A)<L1(B
Then
L1(B→L1(A
Goto E
End
End
End
End
Lbl E
L1

Объяснение:

Prompt L1          # 4 bytes, input list
If 2≤dim(L1        # 7 bytes, if the list has 2 or 1 element(s), skip this part and return it
Then               # 2 bytes
For(A,1,dim(L1)-1  # 12 bytes, for each element in the list other than the last
For(B,A,dim(L1     # 9 bytes, for each element after that one
If L1(A)<L1(B      # 12 bytes, if the second is larger than the first
Then               # 2 bytes
L1(B→L1(A          # 10 bytes, replace the first with the second
Goto E             # 3 bytes, and exit
End                # 2 bytes
End                # 2 bytes
End                # 2 bytes
End                # 2 bytes
Lbl E              # 3 bytes
L1                 # 2 bytes, implicitly return L1

1

ш, 118 байт

Входные целые числа передаются в качестве аргументов скрипту.

l=("$@");for i in "$@";{ for j in "$@";{(($i<$j))&&{ l[$x]=$j;echo ${l[@]};exit;};};shift;x=`expr $x+1`;};echo ${l[@]}

Сломать:

l=("$@");                      #copy original list
for i in "$@";{ for j in "$@"; #check all elements j that follow element i in list
{(($i<$j))&&{ l[$x]=$j;echo ${l[@]};exit;};};   #if i<j, make i=j; print list, done
shift;                         #makes sure that i is compared only to j that occur after it
x=`expr $x+1`;};               #keeps track of i'th position in the list
echo ${l[@]}                   #prints list if it was unchanged

0

PHP, 88 байт

<?for(;$i+1<$c=count($a=$_GET)&&$a[+$i]>=$a[++$i];);$i>=$c?:$a[$i-1]=$a[$i];print_r($a);

Сломать

for(;
$i+1<($c=count($a=$_GET))  # first condition end loop if the item before the last is reach 
&&$a[+$i]>=$a[++$i] # second condition end loop if item is greater then before 
;);
$i>=$c?:$a[$i-1]=$a[$i]; # replace if a greater item is found
print_r($a); #Output

0

Haskell, 48 байтов

f(b:l)|l>[],m<-maximum l,b<m=m:l|1<2=b:f l
f x=x

Пример использования: f [1,1,2,1]-> [2,1,2,1]. Попробуйте онлайн! ,

Если во входном списке есть хотя бы один элемент, свяжите bего с первым элементом и lс остальной частью списка. Если значение lне пустое и bменьше максимального l, возвращает максимум с последующим l, в противном случае возвращает с bпоследующим рекурсивным вызовом f l. Если список ввода пуст, верните его.


0

Ракетка 202 байта

(let((g(λ(L i n)(for/list((c(in-naturals))(l L))(if(= c i)n l))))(ol'()))
(for((c(in-naturals))(i L))(for((d(in-range c(length L)))#:when(>(list-ref L d)i))
(set! ol(cons(g L c(list-ref L d))ol))))ol)

Ungolfed:

(define (f L)
  (let ((replace (λ (L i n)   ; sub-function to replace i-th item in list L with n;
                   (for/list ((c (in-naturals))
                              (l L))
                     (if (= c i) n l))))
        (ol '()))             ; outlist initially empty; 
    (for ((c (in-naturals))               ; for each item in list
          (i L))
      (for ((d (in-range c (length L)))   ; check each subsequent item in list
            #:when (> (list-ref L d) i))  ; if greater, replace it in list
        (set! ol (cons (replace L c (list-ref L d)) ol)))) ; and add to outlist.
    ol))          ; return outlist.

Тестирование:

(f '(3 1 4 -1 2))

Выход:

'((3 1 4 2 2) (3 2 4 -1 2) (3 4 4 -1 2) (4 1 4 -1 2))

0

C 67 байт

Одиночный прогон, 67 байтов Live

j;f(l,i)int*l;{j=i-1;while(i-->0)while(j-->0)l[j]=fmax(l[i],l[j]);}

Один шаг, 78 байт Live

j;f(l,i)int*l;{j=i-1;while(i-->0)while(j-->0)if(l[j]<l[i]){l[j]=l[i];return;}}

Хвост Максима, 96 байт Live

x;i;j;f(l,n)int*l;{do{x=0;for(i=0;i<n;i++)for(j=0;j<i;j++)if(l[j]<l[i])l[j]=l[i],x=1;}while(x);}

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.