在序列中找出奇数


20

挑战:

考虑以下函数F(N) = 2^N + 1,其中N的正整数小于31。该函数定义的顺序是:

3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097, 8193, 16385, 32769, 65537, 131073, 262145, 524289, 1048577, 2097153, 4194305, 8388609, 16777217, 33554433, 67108865, 134217729, 268435457, 536870913, 1073741825

输入将生成如下:

  • 从上面的序列中获取5 个连续的整数。
  • 用不同的正整数替换它们之一(该整数可能会或可能不会成为上述序列的一部分)。
  • (可选)对5个结果数字重新排序。

给定这样一个由5个整数组成的列表,找到被交换的一个,因此不属于原始5个连续整数的一部分。

例:

  • 原始子列表:5, 9, 17, 33, 65
  • 替换为:5, 7, 17, 33, 65
  • 重新排序:33, 17, 5, 7, 65

预期的输出将是7

输入中的5个值将始终是不同的,并且将始终存在唯一的解决方案。(例如,你不会有应对输入等3, 9, 17, 33, 129,其中任何3129可能在已交换)。

测试用例:

5,9,17,33,829
o/p: 829

9,5,17,829,33
o/p: 829

33, 17, 5, 7, 65
o/p: 7

5,9,177,33,65
o/p: 177

65,129,259,513,1025
o/p: 259

129,259,513,1025,65
o/p: 259

63,129,257,513,1025
o/p: 63

65,129,257,513,4097
o/p: 4097

5, 9, 2, 17, 33
o/p: 2

536870913, 67108865, 1073741825, 1, 268435457
o/p: 1

4
为了将来参考,通常可以通过在沙箱中首先发布挑战想法来避免这种混乱和误解,人们可以开始解决挑战之前,您可以在其中获得社区的反馈。
马丁·恩德

@Ajay由于对规范还有一些困惑,我再次编辑了挑战,我认为您打算在此挑战中表达什么。我希望我不会误解它,但请告诉我是否有错。
马丁·恩德

@MartinEnder新的测试用例应该是536870913,67108865,134217729,1,268435457
约尔格Hülsermann

也可以随意添加@JörgHülsermann,但我的意图是添加一个涵盖N = 30作为输入值之一的测试用例。
马丁·恩德

1
一个有趣的挑战,因为很容易提出错误的算法。实际上,我从未见过这么多不正确的答案。如果允许重复,那就更糟了(许多基于集合的方法(包括我的方法)将失败)
Ton Hospel

Answers:


6

果冻,15个字节

⁹R2*‘ṡ5ḟ@€µEÐfQ

TryItOnline
所有测试用例也是在 TryItOnline

返回一个列表,其中包含一个包含奇数个的列表。

怎么样?

⁹R2*‘ṡ5ḟ@€µEÐfQ - Main link, a (list)
⁹               - literal 256 (saving a byte over literal 30)
 R              - range, [1,2,3,...]
  2*            - 2 ** x, [2,4,8,...]
    ‘           - increment, [3,5,9,...]
     ṡ5         - all contiguous slices of length 5
       ḟ@€      - filter with reversed arguments for each
          µ     - monadic chain separation
            Ðf  - filter on condition:
           E    - all equal (those previously filtered lists with only one value)
              Q - unique (there can be two, but both will have the same odd-one-out)

5

JavaScript(ES6),62个字节

a=>a.find(n=>--n&--n|!n)||a.sort((a,b)=>a-b)[a[0]*16>a[3]?4:0]

完全新的算法,因为正如@ edc65指出的那样,先前的算法已被破坏。说明:首先,我们通过寻找2或不大于2的幂的数字来处理这种简单情况。如果未找到,则有两种可能的情况,具体取决于额外值是小于还是大于该值。原来的五次运行,因此我们检查最小和第二最大值是否属于同一五次运行,如果是,则归咎于最大值,否则归咎于最小值。


几乎可以,但是请尝试n-1&n-2使用该值2
edc65 '16

@ edc65不适用于[3, 17, 33, 65, 257]
尼尔

@ edc65 --n&--n|!n适合这种2情况吗?
尼尔

看起来确实不错
edc65 '16

4

Python,84个字节

def f(a,i=0):s=set(a)-{2**j+1for j in range(i,i+5)};return len(s)<2and s or f(a,i+1)

所有测试用例都在ideone上

对于有效输入,返回仅包含奇数一出的集合。
对于无效输入,将达到递归限制,并且将引发错误。


4

Mathematica,65个字节

f[a___,x_,b___]/;NestList[2#-1&,a~Min~b/. 2->0,4]~SubsetQ~{a,b}=x

这定义了一个f应使用5个参数调用的函数,例如

f[5, 9, 17, 33, 829]

原则上可以使用任意数量(非零)的参数来调用该函数,但是您可能会得到意想不到的结果...

我认为这是第一次,我设法将整个解决方案付诸于轻而易举的挑战=

说明

该解决方案确实使Mathematica的模式匹配功能对我们有用。我们使用的基本功能是Mathematica不仅可以定义简单的函数,f[x_] := (* some expression in x *)而且可以在左侧使用任意复杂的模式,例如,f[{a_, b_}, x_?OddQ] := ...将定义添加到f仅在用两个元素调用时使用列表和一个奇数整数。方便起见,我们已经可以在左侧表达式的任意下方给元素命名(例如,在最后一个示例中,我们可以立即将两个列表元素称为ab)。

我们在此挑战中使用的模式是f[a___,x_,b___]。这里a___b___是零个或多个参数的序列,并且x是一个参数。由于定义的右侧是simple x,我们想要的是某种魔术,可以确保将x其用于我们正在搜索的输入,a___并且b___仅仅是覆盖其余元素的通配符。

通过使用将条件附加到模式来完成此操作/;/;(返回的所有内容=)的右侧需要返回True以使此模式匹配。美妙之处在于Mathematica的模式匹配器会尝试的每一个任务axb要投入我们,所以正确的元素的搜索为我们所做的。这本质上是该问题的声明式解决方案。

至于条件本身:

NestList[2#-1&,a~Min~b/. 2->0,4]~SubsetQ~{a,b}

注意,这一点都不依赖x。相反,此条件仅取决于其余四个元素。这是模式匹配解决方案的另一个便利功能:由于序列模式,a并且b一起包含所有其他输入。

因此,此条件需要检查其余四个元素是否是我们序列中的相邻元素,且间隔最多为一个。检查此内容的基本思想是,我们从最小值(via )生成接下来的四个元素,并检查这四个元素是否是该元素的子集。唯一可能引起麻烦的输入是包含的输入,因为这也会生成有效的序列元素,因此我们需要单独处理。xi+1 = 2xi - 12

最后一部分:让我们看一下实际的表达,因为这里有一些更有趣的语法糖。

...a~Min~b...

该前缀符号是的缩写Min[a,b]。但是请记住,ab是序列,因此它实际上扩展为四个元素,Min[i1, i2, i3, i4]并为我们提供了输入中剩余的最小元素。

.../. 2->0

如果结果为2,则将其替换为0(这将生成不在序列中的值)。该空间是必需的,因为否则Mathematica会解析float文字.2

NestList[...&,...,4]

我们将左边的未命名函数应用于此值4次,并将结果收集在列表中。

2#-1&

这只是将其输入乘以2并减一。

...~SubsetQ~{a,b}

最后,我们检查包含所有元素的列表,a并且b是该列表的子集。


我不知道Mathematica可以做到这一点!
DanTheMan

4

球拍198字节

(λ(m)(let((l(for/list((i(range 1 31)))(+ 1(expt 2 i))))(r 1)(n(length m)))(for((i(-(length l)n)))(let
((o(for/list((j m)#:unless(member j(take(drop l i)n)))j)))(when(eq?(length o)1)(set! r o))))r))

非高尔夫版本:

(define f
  (λ(m)
    (let ((l (for/list ((i (range 1 31))) 
               (+ 1 (expt 2 i))))
          (res 1)
          (n (length m)))
      (for ((i (- (length l) n)))
        (let ((o (for/list ((j m) 
                             #:unless (member j 
                                             (take (drop l i) n))) 
                    j)))
          (when (eq? (length o) 1)
            (set! res o))))
      res)))

测试:

(f '(5 9 17 33 829))
(f '(9 5 17 829 33))
(f '(5 9 177 33 65))
(f '(65 129 259 513 1025))
(f '(129 259 513 1025 65))
(f '(63 129 257 513 1025))
(f '(65 129 257 513 4097))

输出:

'(829)
'(829)
'(177)
'(259)
'(259)
'(63)
'(4097)

2

05AB1E32 30 26 24 20字节

30Lo>Œ5ùv¹yvyK}Dgi`q

说明

30Lo>    # list containing the sequence [3 .. 1073741825]
Œ5ù      # all sequence sublists of length 5
v        # for each such list
 ¹yvyK}  # remove it's elements from input
 Dgi     # if the remaining list has length 1
    `q   # end the program and print the final list flattened

在线尝试!


2

R,97个字节

事实证明,这比我想象的要难。我相信这可以打很多。

m=match(x<-sort(scan()),2^(1:31)+1);l=diff(m);ifelse(NA%in%m,x[is.na(m)],x[ifelse(l[4]>1,5,l>1)])

脱节和解释

x<-sort(scan())                  # read input from stdin and sort, store as vector
m=match(x, 2^(1:31)+1)           # generate a vector of indices for which input matches the sequence
l=diff(m)                        # vector of the difference of indices (will only contain 4 elements)
ifelse(NA%in%m,                  # if m contains NA do:
       x[is.na(m)],              # return x where no match has been found, else:
       x[ifelse(l[4]>1,5,l>1)])  # return x by index where diff>1 unless it's the last object, then return x[5]

如果输入向量的任何元素不在序列中,则该match()函数将返回NA,因此,我们可以仅找到NA输入中存在的索引并返回此值:x[is.na(m)]

如果输入是序列的一部分但放错了位置,它将变得更加复杂。由于输入已排序,因此每对索引之间的距离 应为1。因此,我们可以通过调查1st匹配索引的差异l=diff(m)并找到的索引来 找到放错位置的元素l>1。如果不是因为l包含4元素而不是的事实,这就足够了5。如果排序后的输入中的最后一个元素是序列BUT的成员而不是子序列的一部分(如最终测试用例),这只是一个问题。因此,如果4th元素>1获取5th排序输入中的条目,则在4-length向量中查找索引:x[ifelse(l[4]>1,5,l>1)]


1
在R的最新版本中,有一个功能anyNA等效于any(is.na(x))
JDL

2

Haskell,66 64字节

g x=[s|n<-[1..],[s]<-[filter(`notElem`[2^m+1|m<-[n..n+4]])x]]!!0

用法示例:g [65,129,257,513,4097]-> 4097

循环浏览所有长度为5的连续子列表F(N),以保持不在输入列表中的元素x和模式匹配长度为1(-> [s])的元素。

编辑:@xnor通过删除外部循环的上限保存了两个字节。由于肯定存在解决方案,Haskell的懒惰会在找到的第一个数字处停止。


您实际上是否需要26的上限?
xnor

1

Perl,64个 59字节

包括+2 -an

在STDIN上提供输入列表:

perl -M5.010 oddout.pl <<< "5 9 2 17 33"

oddout.pl

#!/usr/bin/perl -an
@a=grep$_,@a{@F,map{2**$_+++1}($.++)x5}=@F while$#a;say@a

如果您不介意结果周围的可变空间量,那么这个58字节的版本将起作用:

#!/usr/bin/perl -ap
$_=join$",@a{@F,map{2**$_+++1}($.++)x5}=@F while/\b +\b/

如果输入没有解决方案,则这两个版本将永远循环。

这是非常恶心的代码,但我想不出任何优雅的方法...

%a据我所知,我滥用的方式是一种新的Perlgolf技巧。


1

Python 2,73个字节

s=set(input());i,=d={1}
while~-len(s-d):i*=2;d=d-{i/32+1}|{i+1}
print s-d

遍历d五个连续序列元素的集合,直到找到一个包含除一个输入元素之外的所有元素,然后打印差异,这是单例集合的输出。

d通过重复添加一个新元素i+1并删除i/32+1当前窗口5之前的任何旧元素,可以从零开始构建五个连续元素的集合。这就是它的进度。

{1}
{3}
{3, 5}
{3, 5, 9}
{3, 5, 9, 17}
{3, 5, 9, 17, 33}
{5, 9, 17, 33, 65}
{9, 17, 33, 65, 129}
{17, 33, 65, 129, 257}
{33, 65, 129, 257, 513}

初始化开始时会有一个杂散1,但这是无害的,因为它会立即被删除。较小的集合(最多可包含5个元素)也无害。


1

PHP,87 76 75字节

for(;count($b=array_diff($argv,$a?:[]))-2;)$a[$n%5]=1<<++$n|1;echo end($b);

php -r '<code>' <value1> <value2> <value3> <value4> <value5>


“A = []`时并不需要
约克Hülsermann

@JörgHülsermann:这是必需的array_diff。但是我可以在那里保存一个字节。
泰特斯(Titus)2016年

结果为警告array_diff():参数2不是数组。用mod 5填充数组的好方法。它将在我的建议中为我节省array_map和range
约尔格Hülsermann

1
end而不是,max您的笔记就不再重要了
约尔格·赫尔斯曼(JörgHülsermann)


0

Java 7,85字节

int f(int[]a,int l){int i=1;for(;i<l;)if(a[i++-1]*2-1!=a[i])return a[i];return a[0];}

不打高尔夫球

int f(int[]a,int l){
    int i=1;
    for(;i<l;)
    if(a[i++-1]*2-1!=a[i])
    return a[i];
   return a[0];

}

嗯,您确定这正常吗?因为我得到的测试用例1、5、6和7的输出不正确(仅第二,第三和第四输出是正确的)。另外,参数l31是吗?在这个问题中,我只看到一个int数组作为输入,而没有看到另一个int?:S
凯文·克鲁伊森

如果输出的奇数是第二个(在索引1处),这不会失败吗?
Ton Hospel's

抱歉,我误解了这个问题。.实际上我现在在医院..我会在很短的时间内更改它。
Numberknot

0

PHP,76字节

在mod 5中实现了Titus想法

<?for(;count($x=array_diff($_GET[a],$r))-1;$r[++$i%5]=2**$i+1);echo end($x);

126字节之前

<?for(;$x=array_diff($_GET[a],array_map(function($z){return 2**$z+1;},range(++$i,$i+4)));)if(count($x)<2){echo end($x);break;}

匿名功能:array_map(function($z){return 2**$z+1;},range($i,$i+4))$x[key($x)]->end($x)
泰特斯(Titus)

1-count($x=...)该条件将让你摆脱破发的:for(;1-count($x=...););echo end($x);(-13)
提图斯

0

Pyth,18个字节

hhlD-LQ.:mh^2dSCd5

形成序列,获取长度为5的子列表,从Q中删除每个子列表,获取最短的结果,输出其唯一元素。


不适用于[5, 9, 2, 17, 33]
Emigna

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.