从无序列表中找到两个整数以求和


13

这是Google的面试问题,请参阅此处的youtube链接。

任务:

从无序列表中找到2个整数,这些整数相加得出给定的整数。

  1. 给定一个无序的整数列表,找到2个总和为给定值的整数,打印这2个整数,并指示成功(退出0)。它们不需要是任何特定的数字(即,前2个整数加起来为正确的数字),任何与该值加起来的对都可以使用。
  2. 整数为正且大于零。
  3. 整数列表可以采用任何数据结构,包括整数文件-每行一个整数。
  4. 如果找不到整数,则指示失败(出口1)。
  5. 必须返回列表中不同位置的两个整数。(即,您不能从同一位置两次返回相同的数字)

(注意:在视频中,这些不完全是要求。“采访者”多次更改了他的位置。)

例如。

sum2 8 <<EOF
1
7
4
6
5
3
8
2
EOF

打印35退出状态为0。请注意,在此状态下1,72,6还将允许结果。

sum2 8 <<EOF
1
2
3
4

由于没有可能的组合,因此返回退出状态1。4,4根据规则5,不允许。


15
如果它有机会首先摆脱沙盒中的一些松散末端,这可能是一个很大的问题。例如,对于这样的事情,我希望编写一个返回假值或一对数字的函数。
尼尔

2
在示例中,为什么返回的对是(3,5)而不是(1,7)?
Rod

4
无序列表中如何有“第一”对?这本质上是自相矛盾的。
彼得·泰勒

23
我真的不认为0 / exit 1是个好主意。许多语言都不能像这样轻易存在,并且通常都允许退出时出错(即忽略STDERR)。许多高尔夫语言甚至都没有通过退出代码退出的简便方法
知道吗–Rɪ1717年

2
经过深思熟虑,已经做出了一些努力来产生退出代码1,因此最好不要现在更改要求
Luis Mendo

Answers:


5

Bash,84个字节

我对Google工程师的解决方案的大致实现,但使用了bash和输入流-不是我的解决方案,因此这不算什么。

while read V;do((V<$1))&&{ ((T=R[V]))&&echo $T $V&&exit;((R[$1-V]=V));};done;exit 1

方法

虽然我们可以从输入流中读取整数V,如果小于目标$ 1,则如果已经看到$ 1-V,则输出$ 1-V和V,然后退出0(否则),保存输入$ 1-V的候选对象,退出1


4

Brachylog,9个字节

h⊇Ċ.+~t?∧

在线尝试!

假设我正确理解了挑战...

说明

h⊇Ċ          Ċ ('couple') has two elements, and is a subset of the head of the input
  Ċ.         Output = Ċ
   .+~t?     The sum of the elements of the Output is the tail of the Input
        ∧    (disable implicit unification)

4

Perl 6、59字节

$_=get;put lines().combinations(2).first(*.sum==$_)//exit 1

试试吧,
尝试吧,没有可能的结果

展开:

$_ = get;            # get one line (the value to sum to)

put                  # print with trailing newline
    lines()          # get the rest of the lines of input
    .combinations(2) # get the possible combinations
    .first(          # find the first one
      *.sum == $_    # that sums to the input
    )
  //                 # if there is no value (「Nil」)
    exit 1           # exit with a non-zero value (「put」 is not executed)

4

JavaScript ES6,58 70 68 64字节

a=>b=>{for(i in a)if(a.includes(b-a[i],i+1))return[a[i],b-a[i]]}

如果找到,undefined则以数组形式返回一对数字,否则返回falsy值。

f=a=>b=>{for(i in a)if(a.includes(b-a[i],i+1))return[a[i],b-a[i]]}

console.log(f([1,7,4,6,5,3,8,2])(8));
console.log(f([1,2,3,4,5,6,7,8])(8));
console.log(f([1,2,3,4])(8));
console.log(f([2,2])(4));


例子是,3, 5但是输出1, 7...
Neil

@Neil,对不起,我已经修改了规则,因为我搞砸了。1,7还可以。
philcolbourn

1
它不会工作f([2,2] 4)吗?
悬崖根

1
@cliffroot现在应该为该案例工作
Tom

1
includes
尼尔

4

JavaScript(ES6),61 57 56字节

以currying语法获取整数数组a和期望的和。返回一对匹配的整数作为数组,或者如果不存在这样的对。s(a)(s)undefined

a=>s=>(r=a.find((b,i)=>a.some(c=>i--&&b+c==s)))&&[r,s-r]

格式化和评论

a =>                      // given an array of integers (a)
  s => (                  // and an expected sum (s)
    r = a.find((b, i) =>  // look for b at position i in a such that:
      a.some(c =>         //   there exists another c in a:
        i-- &&            //     - at a different position
        b + c == s        //     - satisfying b + c == s
      )                   //   end of some()
    )                     // end of find(): assign the result to r
  ) &&                    // if it's not falsy:
  [r, s - r]              // return the pair of integers

测试


3

果冻,14字节

ŒcS=⁹$$ÐfḢṄo⁶H

在线尝试!

这是一个输出到标准输出的功能(不是完整程序)。(TIO链接具有一个运行函数且不考虑其返回值的包装器。)

如果没有退出代码要求,该程序可能会短4个字节;在Jelly中返回退出代码1相当困难。(这可能是我错过的一种更简洁的方法。)

说明

ŒcS=⁹$$ÐfḢṄo⁶H
Œc                All pairs of values from {the first argument}
       Ðf         Take only those which
  S=⁹               sum to {the second argument}
     $$           Parse the preceding three builtins as a group
         Ḣ        Take the first result (0 if there are no results)

          Ṅ       Output this result (plus a newline) on standard output
           o⁶     If this value is falsey, replace it with a space character
             H    Halve every element of the value

我们可以将一对中的每个整数减半,因此,o⁶H如果找到结果,则将不执行任何操作,除了返回无意义的无用的返回值之外(这是一种方便的单字节方法,用于确定函数的返回值) (根据PPCG规则)提早估值)。但是,如果没有找到结果,我们最终会试图将空格字符减半,这种无意义的操作会导致Jelly解释器崩溃。幸运的是,此崩溃产生的退出代码为1。


3

Perl 5,51个字节

46个字节的代码+ 5个字节的-pli标志。

$\="$_ $v"if$h{$v=$^I-$_};$h{$_}=1}{$\||exit 1

在线尝试!

想法是在输入列表上进行迭代:在数字x$_)上,如果我们以前看到n-x$^I-$_),则找到了要查找的内容,并将其设置$\为这两个值("$_ $v")。最后,如果$\未设置,则为we exit 1,否则将隐式打印。


文字标签可以代替两个字符^I吗?

@ ais523看来我做不到。不过,也许在旧版本的Perl上是可能的。
达达

3

Röda60 56字节

f s,a{seq 1,s|{|x|[[x,s-x]]if[x in a,s-x in a-x]}_|pull}

在线尝试!

如果没有答案,此代码将引发错误。它生成所有可以形成和的对s,即。1, s-12, s-23, s-3,...然后,它会检查,如果这两个数字都在阵列中a,如果是这样,他们推到流。pull从流中读取一个值并将其返回。如果流中没有值,则将引发错误。a-x返回数组ax去除。


3

Python 2,60个字节

这很短,直到澄清了以代码1退出的规则。现在,如果未找到任何内容,则错误退出。

-5个字节,感谢@Peilonrayz

-4字节归功于@Rod

在线尝试

a,s=input()
while a:
 x=a.pop()
 if s-x in a:r=s-x,x
print r

@Peilonrayz没意识到,谢谢!
死负鼠

@Peilonrayz这将违反fith规则:必须返回列表中不同位置的两个整数。(即,您不能从同一位置两次返回相同的数字)
死负鼠

3
您可以将空格和制表符用于混合缩进以减少2个字节或切换input() 以减少4个字节
Rod

@Rod谢谢!输入似乎更好
Dead Possum

2
@Eric Duminil是的。相当于eval(raw_input())(我认为)。
Yytsi'3

2

C ++ 133字节(与clang 4和gcc 5.3 -std = c ++ 14编译)

#include <set>
auto f=[](auto s,int v,int&a,int&b){std::set<int>p;for(auto i:s)if(p.find(i)==end(p))p.insert(v-i);else{a=v-i;b=i;}};

C 108字节

void f(int*s,int*e,int v,int*a,int*b){do{int*n=s+1;do if(v-*s==*n){*a=*s;*b=*n;}while(++n<e);}while(++s<e);}

1
欢迎光临本站!不幸的是,我认为您需要为添加15个字节,#include <set>并为添加更多的字节std::set。尽管如果删除括号也可以节省一些字节p.insert(v-i);
James

@DJMcMayhem哦,谢谢。那我应该包括main()吗?
em2er

@ em2er不,您不需要包含main。我们认为(除非在挑战中另有说明)函数是有效的提交。(欢迎访问网站!)
Dada

不可以,可以提交功能。(而且更简短,因为您可以将输入作为参数)。您只需要计算提交内容中需要包含的所有内容。
詹姆斯

1
@DJMcMayhem @Dada非常感谢!我也不确定end,但是它可以在gcc上编译std::(如果没有当然可以设置)
em2er

2

Haskell,34个字节

(n:v)#s|elem(s-n)v=(n,s-n)|1<2=v#s

在线尝试!

对于列表的每个元素,此函数都会检查(sum-element)是否在列表的以下部分中。返回找到的第一对。如果函数到达列表的末尾,则会引发“非穷举模式”错误,并以代码1退出。


恐怕这种方法不适用于的输入[2,2]#4
Laikoni '17

@Laikoni谢谢,我对挑战的理解还不够。这个新版本应该是正确的(并且更短^^)
Leo

2

PowerShell,109 97字节

param($i,$a)($c=0..($a.count-1))|%{$c-ne($f=$_)|%{if($a[$f]+$a[$_]-eq$i){$a[$f,$_];exit}}};exit 1

接受了AdmBorkBork提供的12字节交易

说明

# Get the parameter passed where $i is the addition target from the array of numbers in $a
param($i,$a)

($c=0..($a.count-1))|%{
    # We are going to have two loops to process the array elements.
    # The first loop element will be held by $f
    $f=$_
    # Create a second loop that will be the same as the first except for the position of $f to
    # prevent counting the same number twice. 
    $c|?{$_-ne$f}|%{
        # Check if the number at the current array indexes add to the target value. If so print and exit.
        if($a[$f]+$a[$_]-eq$i){$a[$f],$a[$_];exit}        
    }

}
# If nothing was found in the loop then we just exit with error.
exit 1

当前规则会寻找退出代码。那些可以被删除,只需要检查返回的数字和伪造的数字即可。

样品用量

如果以上代码另存为函数 s

s 8 @(1,2,3,4)
s 8 @(1,7,4,6,5,3,8,2) 

您可以通过消除$c向下循环来节省更多字节–($a.count-1)..1|%{$f=$_;--$_..0|%{if...
AdmBorkBork

2

R,49个字节

function(x,y){r=combn(x,2);r[,colSums(r)==y][,1]}

找出的所有2个组合x并返回一个矩阵。然后,按列求和并找到所有等于的总和y(因此,如果没有[,1]结尾部分,它将打印出总和等于的所有组合y


2

Japt,9字节

@ETHproductions节省了很多字节

à2 æ_x ¥V

在线尝试!

说明

à2 æ_x ¥V
à2         // Creates all combinations of the input, length 2
   æ       // Returns the first item where:
    _x     //     The sum of the two items in each set
       ¥V  //     == Second input   

Input:        [1,2,3], 4
à2         // [[1,2],[1,3],[2,3]]
   æ_x     // [3,    4,    5    ]
       ¥V  //  3!=4, 4==4 ✓
Output:    //  1,3

2

Javascript,114 96 86 84字节

a=>b=>{c=b.length;for(x=0;x<c;x++)for( y=x;++y<c;)if(b[x]+b[y]==a)return[b[x],b[y]]}

@Cyoce节省了1个字节,@ ETHProductions节省了8个字节

这将返回具有列表元素的第一组合的元组,这些组合的总和等于给定的输入,否则不返回任何内容。我已经删除var了函数中的;REPL.it在没有它们的情况下崩溃,但是Chrome Dev Console可以很好地解决此问题...

在线尝试!


不退出代码1,因为质询特别要求输入无效。目前,这是一个无效的答案,但是我已经向OP询问了对那些不那么容易做到的语言的要求。
Rɪᴋᴇʀ

@Matt是的,遵守该规则:y=x+1会注意这一点。
steenbergh

1
您可以a=>b=>...用来保存字节
-Cyoce

1
您可以使用保存另外三个字节for(y=x;++y<b.length;){。另外,您可以删除除最外的一组大括号,并且可以删除之后的空格return
ETHproductions

1

Clojure,77个字节

#(first(mapcat(fn[i a](for[b(drop(inc i)%):when(=(+ a b)%2)][a b]))(range)%))

返回第一个这样的对或nil


1

Haskell,62个字节

r=return;s#[]=r 1;s#(a:b)|elem(s-a)b=print(a,s-a)>>r 0|1<2=s#b

我仍然不知道挑战允许什么,不允许什么。我正在寻找一个打印一对数字并在有解决方案的情况下返回0的函数,什么也不打印,在没有解决方案的情况下返回1的函数。由于打印是I / O,因此我必须将返回值提升到IO-Monad(通过return),并且该函数的实际类型是Num a => IO a

使用示例(由repl打印返回值):

*Main> 4 # [2,2]
(2,2)
0

在线尝试!

如果允许引发异常,fail将保存一些字节(共51个字节):

s#[]=fail"";s#(a:b)|elem(s-a)b=print(a,s-a)|1<2=s#b

1

果冻,9字节

ŒcS=¥ÐfḢZ

Jelly无法将退出代码设置为任意值,因此在没有有效解决方案的情况下,输入会产生TypeError,这将导致父解释器以退出代码1退出。

在线尝试!

怎么运行的

ŒcS=¥ÐfḢZ  Main link. Argument: A (array of integers), n (integer)

Œc         Yield all 2-combinations of different elements of A.
     Ðf    Filter by the link to the left.
    ¥        Combine the two links to the left into a dyadic chain.
  S            Take the sum of the pair.
   =           Compare the result with n.
       Ḣ   Head; extract the first pair of the resulting array.
           This yields 0 if the array is empty.
        Z  Zip/transpose the result.
           This doesn't (visibly) alter pairs, but it raise a TypeError for 0.

1

新星,101字节

q(Int[] a,Int x)=>a{if(Int y=a.firstWhere({a.contains(x-a.remove(0))}))return [y,x-y];System.exit(1)}

关于代码高尔夫的一件好事是,它可以帮助我查找语言中的错误。例如return和之间的空格[y,x-y]

一旦将push / pop函数添加到Array.nova并修复return,将是96个字节:

q(Int[] a,Int x)=>a{if(Int y=a.firstWhere({a.contains(x-a.pop())}))return[y,x-y];System.exit(1)}

用法:

class Test {
    static q(Int[] a,Int x)=>a{if(Int y=a.firstWhere({a.contains(x-a.remove(0))}))return [y,x-y];System.exit(1)}

    public static main(String[] args) {
        Console.log(q([1, 2, 3, 4, 5], 8)) // [5, 3]
        Console.log(q([1, 2, 3, 4, 5], 5)) // [1, 4]
        Console.log(q([1, 2, 3, 4], 8)) // exit code 1
    }
}

编辑:此外,也有这种方式在73个字节(使用pop时为69个字节):

q(Int[] a,Int x)=>[Int y=a.firstOrThrow({a.contains(x-a.remove(0))}),x-y]

firstOrThrow将引发一个异常,该异常未被捕获,因此最终以退出代码1退出程序。

这种方式似乎也更具可读性。


0

Pyth,12个字节

hfqsThQ.ceQ2

说明

       .ceQ2   Get all pairs from the second input
 fqsThQ        Find the ones whose sum is the first input
h              Take the first (exits with error code 1 if there aren't any)

0

PHP,88字节

for($i=1;$a=$argv[$k=++$i];)for(;$b=$argv[++$k];)if($a+$b==$argv[1])die("$a $b");die(1);

从命令行参数获取输入,首先求和。用运行-nr

幸运的是,当给它一个字符串作为参数时,die/ exit退出0

我试图将循环合并为一个。但这需要更长的初始化时间并进行测试。


糟糕的一天?for($i=1;$a=$argv[$k=++$i];)for(;$b=$argv[++$k];)$a+$b!=$argv[1]?:die(!0);你应该对这个看看codegolf.stackexchange.com/questions/120803/...
约尔格Hülsermann

0

Mathematica,76个字节

f::e="1";If[(l=Cases[#~Subsets~{2},x_/;Tr@x==#2])=={},Message@f::e,First@l]&

相当简单:#~Subsets~{2}获取列表的所有2元素子集,然后Cases[...,x_/;Tr@x==#2]仅选择总和为我们想要的数字的那些。如果没有这些,则If[l=={}, Message@f::e,First@l]输出f::e : 1我们先前定义的错误消息(因为我不知道“退出状态1”对Mathematica意味着什么);否则,它将返回总和为正确事物的对列表中的第一个条目。

如果允许我们返回一个false值而不是执行奇怪的退出状态操作,则以下代码具有58个字节:

If[(l=Cases[#~Subsets~{2},x_/;Tr@x==#2])=={},1<0,First@l]&

0

Scala,55 41字节

(l,n)=>l combinations 2 find(_.sum==n)get

返回两个数字的列表(如果存在),否则抛出错误。未被发现,此错误将导致退出状态为1。


0

Ruby,53个48字节

->a,s{p(a.combination(2).find{|x,y|x+y==s})?0:1}

输入:a是列表,s是期望的总和。

如果找到2个数字,则打印它们并返回0,否则返回1,如规格所示。


0

TI-Basic,59个字节

Prompt L1
Prompt X
While 1
L1(1→B
seq(L1(C),C,2,dim(L1→L1
If sum(not(X-L1-B
Then
Disp B,X-B
Return
End
End

说明:

Prompt L1               # 4 bytes, input array like "{1, 2, 3}"
Prompt X                # 3 bytes, Input target sum
While 1                 # 3 bytes, until the list is empty
L1(1→B                  # 7 bytes, try the first element (now B)
seq(L1(C),C,2,dim(L1→L1  # 18 bytes, remove first element from list
If sum(not(X-L1-B       # 10 bytes, if any element in the list plus B is the target
Then                    # 2 bytes, then...
Disp B,X-B              # 7 bytes, print it and it's "complement"
Return                  # 2 bytes, and exit gracefully
End                     # 2 bytes
End                     # 1 byte

如果程序没有正常退出,则列表中没有足够的元素继续执行时,它将导致错误。


0

CJam,23个字节

l~_,1>{e!2f<::+#)}{;;}?

输入为sum numbers。例如:6 [3 2 3]。留下正数表示真值,留空字符串或0代表假值。

说明:

l~    e# Read input and evaluate:  | 7 [3 2 3]
_     e# Duplicate:                | 7 [3 2 3] [3 2 3]
,     e# Take the length:          | 7 [3 2 3] 3
1>{   e# If more than 1:           | 7 [3 2 3]
  e!  e#   Unique permutations:    | 7 [[2 3 3] [3 2 3] [3 3 2]]
  2f< e#   Slice each to length 2: | 7 [[2 3] [3 2] [3 3]]
  ::+ e#   Some each:              | 7 [5 5 6]
  #   e#   Index:                  | -1
  )   e#   Increment:              | 0
}{    e# Else:                     | 7 [3 2 3]
  ;   e#   Pop                     | 7
  ;   e#   pop                     |
}?    e# Endif
e# Implicit output: 0
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.