단일 숫자 올리기


25

소개

숫자 목록의 꼬리 최대 값, 즉 비어 있지 않은 각 접미어의 최대 값을 계산한다고 가정합니다. 이를 수행하는 한 가지 방법은 더 이상 가능하지 않을 때까지 하나의 숫자를 반복해서 선택하고 그 뒤에 나오는 더 높은 숫자로 바꾸는 것입니다. 이 도전에서, 당신의 임무는이 알고리즘의 한 단계를 수행하는 것입니다.

작업

입력 값은 정수 L 의 목록이며 비어있을 수 있습니다. 정확히 하나의 숫자 L i 가 다른 L j 로 대체 된 목록 L 이됩니다 . 여기서 L i <L ji <j 입니다.

다시 말해, 하나의 숫자를 그 뒤에 나오는 숫자로 교체해야합니다.

당신은 선택할 수 있습니다 IJ를 모든 유효한 쌍 중 자유롭게, 그리고 선택은 결정적이 될 수 있습니다.

이러한 경우 내가j는 (즉, 존재하지 않는 L은 비 증가)하여 출력한다 L 변경.

입력 L = [3, 1, 4, -1, 2]를 고려하십시오 . 가능한 작업은 34 로 바꾸 거나 , 14 로 바꾸 거나, 12 로 바꾸거나, -12로 바꾸는 것 입니다. 따라서 가능한 출력은 다음과 같습니다.

 [  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

자바 스크립트 (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)?
Neil

조건은 왼쪽에서 오른쪽으로 평가되므로 x=>x.map(c=>c<x[++i]>d?x[d=i]:c,d=i=0)(38 바이트)가 작동해야합니다.
user81655

@ user81655 대단합니다 :-)
ETHproductions

7

수학, 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의 정규 문자열 순서는 이상합니다.
Martin Ender

마틴 엔더?
Greg Martin

그냥 시도하십시오 Sort[FromCharacterCode /@ Range[32, 127]]. 여러 단어가 포함 된 문자열이 있으면 공백과 항목을 무시하기 때문에 이상해집니다.
Martin Ender

6

자바 스크립트 (ES6), 43 39 38 바이트

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

제자리에서 배열을 수정하여 출력합니다. 편집 : @ETHproductions 덕분에 4 바이트가 절약되었습니다. @ user81655 덕분에 1 바이트가 절약되었습니다.


나는 당신이 a=>a[i=0,a.findIndex(e=>e<a[++i])]=a[i]39 를 위해 할 수 있다고 생각합니다.
ETHproductions

40B를위한 또 다른 접근법 :a=>a.map((_,b)=>Math.max(...a.slice(b)))
Luke

@Luke 당신이 도전을 오해하고 있다고 생각합니다. 요점은 배열의 정수 중 하나만 더 크게 만드는 입니다.
ETHproductions

@ETHproductions 호의를 돌려 주셔서 감사합니다.
Neil

나는 당신이 대체 할 수 있다고 생각 findIndexsome: (38 바이트)a=>a[i=0,a.some(e=>e<a[++i])*i-1]=a[i]
user81655

5

하스켈 , 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)하고 2 바이트 더 짧습니다.
Ørjan Johansen

@ ØrjanJohansen 그것은 아름다운 방법입니다! 나는 당신이 그것을 자신의 답변으로 게시해야한다고 생각합니다. 처음에는 그것이 넥타이를 올바르게 처리 할 것이라고 확신하지 못했지만 이제는 작동하기 때문에 f r >= r.
xnor

감사합니다, 나는 한 이렇게 !
Ørjan Johansen 2012

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

파이썬 (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

엄청나게 길지만 첫 번째 시도입니다.


Value Ink 덕분에 TemporalWolf -41 (!!) 바이트 덕분에 -5 바이트


[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

하스켈 , 34 33 바이트

이것은 xnor의 답변을 기반으로 합니다. , 내가 직접 게시 할 것을 제안했습니다.

편집 : xnor는 저장할 바이트를 찾았습니다.

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

온라인으로 사용해보십시오!

기본적으로, 나는 xnor의 방법의 분기는 항상 분기 식 중 가장 큰 분기 식을 선택하게된다는 것을 알았습니다. 하스켈은 목록에 사전 식 순서를 사용하기 때문입니다. ( 유도에 의해 별도로 입증 될 수 a==b있기 때문에 작동 하는 경우 f r>=r.)

때마다 다르게 넣어 b:r > a:f r, 다음 b:r정답이고, 그렇지 않으면 우리는에 재귀 수 있습니다a:f r .

따라서 a<b미리 확인 하는 대신 두 표현식을 모두 계산하고 최대 값을 가져옵니다. 하스켈의 게으름이하지 않는 것을 피할 수 있지만 이것은 지수 파열을 줄 수 ab동일하다.


1
max(b:r)$a:f r바이트를 저장하는 것 같습니다 .
xnor

2

파이썬 3, 79 바이트

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

주어진 원래 배열 (목록)을 변경합니다. 나는 이것이 람다가 아니라서 더 나쁘고 더 나은 최적화가 있다고 확신한다. 나중에 그 문제를 다룰 것입니다.

간단한 설명

현재 요소를지나 배열의 최대 값을 취합니다 (0부터 시작). 그런 다음 이것을 요소 자체와 비교합니다. 최대 값이 더 큰 경우 현재 요소를 해당 요소로 바꾸고 중지하고, 그렇지 않으면 1 씩 증가시키고 계속 시도하십시오.



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"를 보여줍니다. 무엇이 잘못되었다고 생각하십니까?
hvd

나는 문제는 그 생각에 대해 매우 불분명하다, 참조
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

R, 71 바이트

a=scan()
l=length(a) 
lapply(1:l,function(x){
  a[x]=max(a[x:l])
  a
})

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

파이썬 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 만약 내가 작업 권리를 이해한다면, 그것은 유효합니다
Dead Possum

1
고려 r=[y for y in A[i+1:]if y>A[i]]\n if r:A[i]=r[0];break96에 점수를 드롭!
Value Ink

1
나는 다른 파이썬 답변 중 하나에 제안한 것을 제안 할 수 있습니다 : 당신이 가지고있는 것을 원래 배열을 변경하는 함수로 변환하여 인쇄를 피할 수 있습니다 input().
Cole

1

파이썬 2, 60 바이트

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

온라인으로 사용해보십시오!

설명 : 주어진 요소가 max목록의 나머지 요소 보다 작은 지 재귀 적으로 점검 합니다. 그렇다면 max첫 번째 요소 를 바꾸어 목록을 반환합니다 .


1

TI 기본, 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

sh, 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

하스켈, 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)

언 골프 드 :

(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 바이트 라이브

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

단일 단계, 78 바이트 라이브

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

Tail Maxima, 96 바이트 라이브

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.