単一の数字を上げる


25

前書き

数値のリストの末尾の最大値、つまり空でない各サフィックスの最大値を計算するとします。それを行う1つの方法は、1つの番号を繰り返し選択し、それが不可能になるまで、その番号の後に発生するより大きな番号に置き換えることです。この課題では、タスクはこのアルゴリズムの1つのステップを実行することです。

タスク

入力は整数Lのリストで、空の場合があります。出力はリストLになります。リストLでは、正確に1つの数値L iが別のL jに置き換えられています。ここで、L i <L jおよびi <jです。

言い換えると、1つの数値を、その後に発生するより大きな数値に置き換える必要があります。

あなたは選ぶことができますIおよびjは、有効なすべてのペアの間で自由に、そして選択は非決定的ことができます。

そのようなijが存在しない場合(つまり、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

JavaScript(ES6)、41 40 39 38バイト

@Neilに1バイト、@ user81655にもう1つ感謝

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

実数のリストを偶数で取り、実数のリストを返す純粋な関数。「間違った」順序で連続するエントリの最初のペアを探し、そのペアの最初のペアを2番目のペアに置き換えます。の素晴らしいデフォルトの動作は/.、適切な場合に入力を変更せずに返すことを意味します。

面白いサイドノート:私達は交換した場合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]

インプレースで配列を変更して出力します。編集:@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)))
ルーク

@ルーク私はあなたが挑戦を誤解していると思います。ポイントは、配列内の整数の1つだけを大きくすることです。
ETHproductions

@ETHproductions好意を返してくれてありがとう、今では栄誉は平等です!
ニール

私はあなたが交換することができるかもしれないと思うfindIndexsome(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)働くと思い、2バイト短くなっています。
Ørjanヨハンセン

@ØrjanJohansenそれは美しい方法です!自分の答えとして投稿するべきだと思います。最初はそれがタイを正しく処理するかどうかはわかりませんでしたが、今は動作するように見えf r >= rます
-xnor

ありがとう、私はそうしました
Ørjanヨハンセン

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

ひどく長いですが、それは最初の試みです。

TemporalWolfのおかげで-5バイト
Value Value Inkのおかげで-41(!!)バイト


[1,2]与え[2,1]代わりに[2,2]
TemporalWolf

1
@TemporalWolfええ、私は挑戦を読み間違えました。保存または失われたバイトは修正されません。
ハイパーニュートリノ

内部の前の戻り値を削除し、内部ループに余分なスペースの代わりにタブprintを使用でき\tます。また、exit()追加の1に0をドロップできます。132にあなたをダウンさせる必要があります。
TemporalWolf17年

@TemporalWolfわかりました、ありがとう!
ハイパーニュートリノ

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()
バリューインク

3

MATL、13バイト

ttd0>fX>Q)2M(

オンラインでお試しください!

説明

次の2つの条件は同等です。

  1. 右側に大きい数字がある数字があります
  2. すぐ右に大きい数字がある数字があります

コードは条件2を使用しますが、これはより単純です。連続した増分を計算し、もしあれば最後の正の増分を見つけます。関連する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

Haskell34 33バイト

これは、自分で投稿することを提案したxnorの回答に基づいています

編集:xnorは保存するバイトを見つけました。

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

オンラインでお試しください!

基本的に、Haskellはリストに辞書式順序を使用しているため、xnorのメソッドの分岐は常に最大の分岐式を選択することに気付きました。(の場合a==bも動作するのはf r>=r、帰納法によって個別に証明できるためです。)

言い換えると、いつでもb:r > a:f r、その後、b:r正解で、それ以外の場合我々が再帰することができますa:f r

したがってa<b、事前にチェックする代わりに、両方の式を計算して最大値を取得します。Haskellの怠さは、等しくない限り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

指定された元の配列(リスト)を変更します。私はこれがラムダではないことに不満を感じており、より良い最適化があると確信しています。うまくいけば後でそれらに対処します。

簡単な説明

現在の要素(0番目から開始)を超える配列の最大値を取ります。次に、これを要素自体と比較します。最大値が大きい場合は、現在の要素をそれに置き換えて停止します。



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」を表示します。これは、質問で与えられた出力の1つです。何が悪いと思いますか?
hvd

なるほど、質問はそれについては非常に不明瞭です
-Khaled.K

2

SWI-Prolog、70バイト

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

最初の節は、リストの最初の要素をリストの残りの最大値で置き換えますが、この最大値が大きい場合のみです。2番目の句は、リストの末尾の述語を再帰的に呼び出します。これらの句のいずれも成功しない場合、3番目の句は単に入力を返します。

これにより、可能な解決策の1つが返されます。非常に類似したコードでそれらすべてを見つけるのは簡単ですが、変更が不可能な場合は、処理するのにさらに多くのバイトが必要です。

例:

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

Python 2、89バイト

オンラインで試してください @TemporalWolfのおかげで-1バイト@ValueInkの
おかげで-25バイト@Coleの
おかげで-7バイト

入力配列を変更する関数

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

最初の反復後に停止する必要がない場合、少しきれいになります


This appears not to work. Try [1, 3, 5, 7]; it returns [3, 3, 5, 7].
HyperNeutrino

1
A[i]<y and => y>A[i]and saves 1
TemporalWolf

@HyperNeutrino If I inderstand task right, that is valid outut
Dead Possum

1
Consider r=[y for y in A[i+1:]if y>A[i]]\n if r:A[i]=r[0];break to drop your score to 96!
Value Ink

1
Might I suggest what I suggested for one of the other Python answers: convert what you have to a function which mutates the original array so that you can avoid printing and input().
cole

1

Python 2, 60 bytes

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

Try it Online!

Explanation: Recursively checks if a given element is less than the max element in the rest of the list. If so, returns the list with max replacing the first element.


1

TI-Basic, 72 bytes

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

Explanation:

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 bytes

Input integers are passed as arguments to the script.

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

Breakdown:

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 Bytes

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

Breakdown

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 bytes

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

Usage example: f [1,1,2,1] -> [2,1,2,1]. Try it online!.

If the input list has at least one element, bind b to the first element and l to the rest of the list. If l is not empty and b less than the maximum of l, return the maximum followed by l, else return b followed by a recursive call of f l. If the input list is empty, return it.


0

Racket 202 bytes

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

Testing:

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

Output:

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

0

C, 67 bytes

Single Run, 67 bytes Live

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

Single Step, 78 bytes 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;}}

Tail Maxima, 96 bytes 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);}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.