Encontre dois números inteiros de uma lista não ordenada para somar à entrada


13

Esta é uma pergunta de entrevista do Google, veja aqui para obter um link do youtube.

A tarefa:

Encontre 2 números inteiros de uma lista não ordenada que soma um determinado número inteiro.

  1. Dada uma lista não ordenada de números inteiros, encontre 2 números inteiros que somam um determinado valor, imprima esses 2 números inteiros e indique sucesso (saída 0). Eles não precisam ser números específicos (ou seja, os 2 primeiros números inteiros somados ao número certo), qualquer par que somar o valor funcionará.
  2. um número inteiro é positivo e maior que zero.
  3. uma lista de números inteiros pode estar em qualquer estrutura de dados, incluindo um arquivo de números inteiros - um número inteiro por linha.
  4. se nenhum número inteiro puder ser encontrado, indique uma falha (saída 1).
  5. dois inteiros em posições diferentes na lista devem ser retornados. (ou seja, você não pode retornar o mesmo número da mesma posição duas vezes)

(Nota: no vídeo, esses não são exatamente os requisitos. O 'entrevistador' mudou várias vezes.)

por exemplo.

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

O status de impressões 3e 5saída é 0. Observe isso 1,7e 2,6também teria resultados permitidos.

sum2 8 <<EOF
1
2
3
4

Retorna o status de saída 1, pois não há combinação possível. 4,4não é permitido, de acordo com a regra 5.


15
Esta poderia ter sido uma ótima pergunta se tivesse tido a chance de sacudir algumas das pontas soltas da Sandbox primeiro. Por exemplo, para algo assim, eu esperaria escrever uma função que retornasse um valor falso ou um par de números.
Neil

2
No exemplo, por que o par retornado é (3,5) e não (1,7)?
Rod

4
Como pode haver um "primeiro" par em uma lista não ordenada? Isso é inerentemente auto-contraditório.
Peter Taylor

23
Realmente não acho que a saída 0 / exit 1 seja uma boa ideia. Muitas línguas não pode existir facilmente assim, e é geralmente permitido para sair com um erro (ou seja, ignorar STDERR) Muitas línguas golfe nem sequer têm uma maneira fácil de sair por código de saída eu acho
Rɪᴋᴇʀ

2
Pensando bem, algumas respostas já passaram por algum esforço para código de produto saída 1, por isso pode ser melhor não alterar os requisitos agora
Luis Mendo

Respostas:


5

Bash, 84 bytes

Minha implementação (aproximadamente) da solução de engenheiro do Google, mas usando o bash e um fluxo de entrada - não a minha solução, portanto isso não conta.

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

Método

enquanto podemos ler o número inteiro V do fluxo de entrada, se menos do que o destino $ 1, se já houver visto $ 1-V, imprima $ 1-V e V e a saída 0 (caso contrário) salve o candidato para a saída 1 de $ 1-V


4

Braquilog , 9 bytes

h⊇Ċ.+~t?∧

Experimente online!

Supondo que entendi o desafio corretamente ...

Explicação

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 bytes

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

Experimente
Experimente sem resultado possível

Expandido:

$_ = 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 bytes

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

Retorna um par de números na forma de uma matriz, se encontrado; caso contrário undefined, retorna um valor falso.

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


O exemplo foi 3, 5, mas este saídas 1, 7...
Neil

@ Neil, desculpe, eu alterei as regras porque eu errei. 1,7 está bem.
philcolbourn

1
Não vai funcionar f([2,2] 4)?
cliffroot

1
@cliffroot deve trabalhar para que caso agora
Tom

1
Bom includestruque.
Neil

4

JavaScript (ES6), 61 57 56 bytes

Pega a matriz de números inteiros ae a soma esperada sna sintaxe de currying (a)(s). Retorna um par de números inteiros correspondentes como uma matriz ou undefinedse esse par não existir.

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

Formatado e comentado

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

Teste


3

Gelatina , 14 bytes

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

Experimente online!

Esta é uma função (não um programa completo) que gera a saída padrão. (O link TIO possui um wrapper que executa uma função e desconsidera seu valor de retorno.)

Este programa pode ser 4 bytes mais curto se não for para o requisito do código de saída; retornar um código de saída 1 no Jelly é bastante difícil. (É possível que exista uma maneira mais tática de fazer isso que eu tenha perdido.)

Explicação

Œ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

Podemos reduzir pela metade todos os números inteiros de um par, portanto o⁶H, nada fará se encontrarmos um resultado, além de retornar um valor de retorno inútil que não seja relevante de qualquer maneira (ele serve como um método conveniente de byte único para determinar o retorno da função valor antecipado, de acordo com as regras do PPCG). No entanto, se não encontrarmos um resultado, acabamos tentando reduzir pela metade um caractere espacial, uma operação sem sentido que causa a falha do intérprete Jelly. Felizmente, esta falha produz um código de saída 1.


3

Perl 5 , 51 bytes

46 bytes de código + para 5 bytes para -plisinalizadores.

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

Experimente online!

A idéia é iterar na lista de entrada: em um número x( $_), se vimos anteriormente n-x( $^I-$_), encontramos o que procurávamos e definimos $\esses dois valores ( "$_ $v"). No final, se $\não estiver definido, então nós exit 1, caso contrário, será impresso implicitamente.


Uma guia literal funciona no lugar dos dois caracteres ^I?

@ ais523 Parece que não posso. Talvez fosse possível em versões mais antigas do Perl.
Dada

3

Röda , 60 56 bytes

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

Experimente online!

Este código gera um erro se não houver resposta. Ele gera todos os pares possíveis que podem formar a soma s, ou seja. 1, s-1, 2, s-2, 3, s-3, ... Em seguida, ele verifica se os dois números estão na matriz ae em caso afirmativo, empurra-los para o fluxo. pulllê um valor do fluxo e o retorna. Se não houver valores no fluxo, gera um erro. a-xretorna a matriz acom xremovido.


3

Python 2, 60 bytes

Este resumo, até que as regras de saída do código 1 sejam esclarecidas. Agora sai com erro se nada for encontrado.

-5 bytes graças a @Peilonrayz

-4 bytes graças a @Rod

Experimente online

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

@Peilonrayz Não percebeu isso, obrigado!
Gambá morto

@Peilonrayz Isso violaria a regra 5: dois inteiros em posições diferentes da lista devem ser retornados. (ou seja, você não pode devolver o mesmo número a partir da mesma posição duas vezes)
Morto Possum

3
Pode utilizar espaços + guias para recuo misto para reduzir ou 2 bytes mudar parainput() reduzir 4 bytes
Rod

@ Rod Obrigado! A entrada parece melhor
Dead Possum

2
@ Eric Duminil Sim. É equivalente a eval(raw_input())(eu acho).
Yytsi 20/03/19

2

C ++ 133 bytes (compilado com clang 4 e 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 bytes

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
Bem vindo ao site! Infelizmente, acho que você precisa adicionar 15 bytes #include <set>e mais alguns std::set. Embora você também possa salvar alguns bytes se remover os chavetas ao redorp.insert(v-i);
James

@DJMcMayhem oh, obrigado. Então, devo incluir main ()?
em2er

@ em2er Não, você não precisa incluir main. Consideramos (salvo indicação em contrário no desafio) que uma função é um envio válido. (bem-vindo no site btw!)
Dada

Não, o envio de uma função é bom. (E muito mais curto, porque você pode usar a entrada como argumento) Você só precisa contar todas as inclusões exigidas pelo seu envio.
James

1
@DJMcMayhem @Dada, muito obrigado! não estou certo com endmuito, mas ele compila em gcc sem std::(e definido se claro que não)
em2er

2

Haskell , 34 bytes

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

Experimente online!

Para cada elemento da lista, essa função verifica se (soma-elemento) está na parte a seguir da lista. Retorna o primeiro par encontrado. Se a função chegar ao final da lista, gera um erro "padrões não exaustivos" e sai com o código 1.


Receio que essa abordagem não funcione para entradas como [2,2]#4.
Laikoni

@Laikoni Obrigado, eu não tinha lido o desafio o suficiente. Esta nova versão deve ser correto (e mais curto ^^)
Leo

2

PowerShell, 109 97 bytes

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

Fez um acordo de 12 bytes que a AdmBorkBork ofereceu

Explicação

# 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

As regras atuais procuram o código de saída que isso faz. Eles podem ser removidos e basta verificar se há números retornados e um falso.

Uso da amostra

Se o código acima foi salvo como função s

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

Você pode salvar mais alguns bytes, eliminando $ce fazendo um loop para baixo - #($a.count-1)..1|%{$f=$_;--$_..0|%{if...
AdmBorkBork 21/17 /

2

R, 49 bytes

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

Ele encontra todas as 2 combinações de xe retorna uma matriz. Em seguida, soma por coluna e encontra todas as somas iguais a y(portanto, sem a [,1]parte no final, ela imprimirá todas as combinações às quais suas somas são iguais y)


2

Japonês , 9 bytes

Economizou muitos bytes graças a @ETHproductions

à2 æ_x ¥V

Experimente online!

Explicação

à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   

Exemplo

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 bytes

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

Guardou 1 byte graças a @Cyoce e outros 8 bytes graças a @ETHProductions

Isso retorna uma tupla com a primeira combinação de elementos da lista que somam a entrada fornecida ou nada para nenhuma correspondência. Eu removi os vars na função; O REPL.it falha sem eles, mas o Chrome Dev Console lida com isso muito bem ...

Experimente online!


Não sai do código 1, pois o desafio solicita especificamente entrada inválida. É uma resposta inválida no momento, mas perguntei à OP sobre esse requisito para idiomas que não podem fazer isso facilmente.
Rɪᴋᴇʀ

@ Matt Sim, essa regra é observada: y=x+1cuida disso.
precisa

1
Você pode usar a=>b=>...para salvar um byte
Cyoce 20/17

1
Você pode salvar outros três bytes com for(y=x;++y<b.length;){. Além disso, você pode remover todos os conjuntos de chaves, exceto o mais externo, e você pode remover o espaço depoisreturn
ETHproductions

1

Clojure, 77 bytes

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

Retorna o primeiro par desse tipo ou nil.


1

Haskell, 62 bytes

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

Ainda não sei o que é permitido pelo desafio e o que não é. Eu estou indo para uma função que imprime um par de números e retorna 0 se houver uma solução e imprime nada e retorna 1 se não houver solução. Como a impressão é de E / S, preciso elevar os valores de retorno para a IO-Mônada (via return) e o tipo real da função é Num a => IO a.

Exemplo de uso (com valor de retorno impresso pela réplica):

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

Experimente online! .

Se o aumento de exceções for permitido, failserão salvos alguns bytes (total de 51):

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

1

Geléia , 9 bytes

ŒcS=¥ÐfḢZ

O Jelly não tem como definir o código de saída para valores arbitrários, portanto, isso gera um TypeError para entrada sem uma solução válida que fará com que o intérprete pai saia com o código de saída 1 .

Experimente online!

Como funciona

Œ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

Nova , 101 bytes

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

Uma coisa interessante sobre o código de golfe é que ele me ajuda a encontrar erros no meu idioma. por exemplo, o espaço necessário entre returne [y,x-y].

Depois de adicionar funções push / pop ao Array.nova e corrigir o retorno, seriam 96 bytes:

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

Uso:

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

Edit: Além disso, há desta maneira em 73 bytes (69 usando pop) também:

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

firstOrThrow lançará uma exceção, que não será capturada e, portanto, sairá do programa com o código de saída 1.;)

Desta forma, parece mais legível também.


0

Pitão, 12 bytes

hfqsThQ.ceQ2

Explicação

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

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

recebe entrada dos argumentos da linha de comando, soma primeiro. Corra com -nr.

Felizmente, die/ exitsai 0quando você fornece uma string como parâmetro.

Eu tentei mesclar os loops a um; mas requer uma inicialização mais longa e teste dessa vez.


Dia ruim? for($i=1;$a=$argv[$k=++$i];)for(;$b=$argv[++$k];)$a+$b!=$argv[1]?:die(!0);e você deve dar uma olhada neste codegolf.stackexchange.com/questions/120803/…
Jörg Hülsermann 16/17

0

Mathematica, 76 bytes

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

Bastante simples: #~Subsets~{2}obtém todos os subconjuntos de 2 elementos da lista e, em seguida,Cases[...,x_/;Tr@x==#2] escolhe apenas aqueles cuja soma é o número que queremos. Se não houver, If[l=={}, Message@f::e,First@l]imprime a mensagem de erro f::e : 1que definimos anteriormente (já que não tenho idéia do que mais "status de saída 1" possa significar para o Mathematica); caso contrário, ele retornará a primeira entrada na lista de pares que somam a coisa correta.

Se for permitido retornar um valor falsey em vez de fazer a coisa estranha de status de saída, o código a seguir tem 58 bytes:

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

0

Scala, 55 41 bytes

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

Retorna uma lista dos dois números, se eles existirem, e gera um erro caso contrário. Não detectado, esse erro resultará no status de saída 1.


0

Ruby, 53 48 bytes

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

Entrada: a é a lista, s é a soma esperada.

Se os 2 números forem encontrados, imprima-os e retorne 0, caso contrário, retorne 1, como na especificação.


0

TI-Basic, 59 bytes

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

Explicação:

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

Se o programa não for encerrado normalmente, ocorrerá um erro quando não houver elementos suficientes na lista para continuar.


0

CJam, 23 bytes

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

Entrada é sum numbers. Por exemplo:6 [3 2 3] . Deixa um número positivo para truthy e uma sequência vazia ou 0 para falsey.

Explicação:

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.