提出一个数字


25

介绍

假设您要计算数字列表的尾部最大值,即每个非空后缀的最大值。一种方法是重复选择一个数字,然后用后面出现的更大的数字代替,直到不可能为止。在这一挑战中,您的任务是执行此算法的一个步骤。

任务

您的输入是一个整数列表L,它可以为空。您的输出应为列表L,其中一个数字L i正好被另一个L j代替,其中L i <L ji <j

换句话说,您应该用一个更大的数字代替一个数字。

您可以在所有有效对之间自由选择ij,并且选择可以是不确定的。

如果这样的ij不存在(即L不增加),则您的输出应保持L不变。

考虑输入L = [3,1,4,-1,2]。可能的操作是替换34,替换14,替换1通过2,或替换-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]

Answers:


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"}return上{"puzzles", "puzzles", "code", "golf"}


注意事项:Mathematica对字符串的规范排序是很奇怪的。
Martin Ender

马丁·恩德(Martin Ender)怎么样?
格雷格·马丁

试一试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
..

40B的另一种方法:a=>a.map((_,b)=>Math.max(...a.slice(b)))
路加福音

@Luke我认为您误会了挑战;点是只让一个在阵列更大的整数。
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)有效,并且短了两个字节。
与Orjan约翰森

@ØrjanJohansen这是一个很好的方法!我认为您应该将其发布为您自己的答案。我不确定一开始它是否可以正确处理领带,但我现在看到它可以正常工作,因为f r >= r
xnor

谢谢,我已经这样做了
与Orjan约翰森

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

MATL,15字节

tdt0>0whY>d*0h+

在线尝试!

我不是这个解决方案的忠实拥护者。对我来说,这似乎效率低下。特别是whY>d*0h+部分。


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()
珍惜墨水

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

Haskell34 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 rb:r便是正确答案,否则我们可以递归为a:f r

因此a<b,我无需预先检查,而只计算两个表达式并取最大值。尽管Haskell的懒惰会避免这种情况,除非ab相等,这可能会导致指数爆炸。


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

突变给它的原始数组(列表)。我对这不是lambda感到不满意,并且我确信还有更好的优化方法。我希望稍后再解决。

简要说明

它使数组的最大值超过当前元素(从第零个开始)。然后将其与元素本身进行比较:如果max较大,则用它替换当前元素并停止,否则,将其递增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,2017年

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

第一个子句用列表中其余部分的最大值替换列表中的第一个元素,但前提是此最大值更大。第二个子句递归地调用列表尾部的谓词。如果这些子句均不成功,则第三子句仅返回输入。

这只是可能的解决方案之一。用非常相似的代码查找所有这些对象很简单,但是如果无法更改,则需要处理更多的字节。

例:

?- 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个字节

在线尝试 -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];break将分数降至96!
价值墨水

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

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

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)

取消高尔夫:

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

尾巴千里马,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);}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.