Trova due numeri interi da un elenco non ordinato da sommare all'input


13

Questa è una domanda di intervista di Google, vedi qui per un link di YouTube.

L'obiettivo:

Trova 2 numeri interi da un elenco non ordinato che si sommano a un dato numero intero.

  1. Dato un elenco non ordinato di numeri interi, trova 2 numeri interi che si sommano a un determinato valore, stampa questi 2 numeri interi e indica il successo (uscita 0). Non hanno bisogno di essere numeri particolari (cioè i primi 2 numeri interi che si sommano al numero giusto), qualsiasi coppia che sommi al valore funzionerà.
  2. un numero intero è positivo e maggiore di zero.
  3. un elenco di numeri interi può essere in qualsiasi struttura di dati incluso un file di numeri interi - un numero intero per riga.
  4. se non è possibile trovare numeri interi, indicare un errore (uscita 1).
  5. devono essere restituiti due numeri interi in posizioni diverse nell'elenco. (cioè non puoi restituire lo stesso numero dalla stessa posizione due volte)

(Nota: nel video, questi non sono esattamente i requisiti. L'intervistatore ha cambiato più volte.)

per esempio.

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

Stampa 3e lo 5stato di uscita è 0. Notare che in questo 1,7e 2,6sarebbero anche consentiti risultati.

sum2 8 <<EOF
1
2
3
4

Restituisce lo stato di uscita 1 poiché non è possibile alcuna combinazione. 4,4non è consentito, come da regola 5.


15
Questa sarebbe stata una grande domanda se avesse avuto la possibilità di scuotere prima alcune delle estremità libere nella Sandbox . Ad esempio, per qualcosa del genere mi aspetterei di scrivere una funzione che abbia restituito un valore errato o una coppia di numeri.
Neil,

2
Nell'esempio, perché la coppia restituita è (3,5) e non (1,7)?
Rod,

4
Come può esserci una "prima" coppia in un elenco non ordinato? Questo è intrinsecamente contraddittorio.
Peter Taylor,

23
Non credo proprio che l'uscita 0 / uscita 1 sia una buona idea. Molte lingue non possono esistere facilmente in quel modo, ed è generalmente permesso uscire con un errore (cioè ignorare STDERR) Molte lingue del golf non hanno nemmeno un modo semplice per uscire dal codice di uscita credo
Rɪᴋᴇʀ

2
A pensarci bene, alcune risposte hanno fatto qualche sforzo per produrre il codice di uscita 1, quindi potrebbe essere meglio non cambiare i requisiti ora
Luis Mendo

Risposte:


5

Bash, 84 byte

La mia implementazione della (approssimativamente) soluzione dell'ingegnere di Google ma usando bash e un flusso di input - non la mia soluzione, quindi questo non conta.

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

Metodo

mentre possiamo leggere il numero intero V dal flusso di input se inferiore al target $ 1, quindi se già visto $ 1-V quindi stampare $ 1-V e V e uscire da 0 (altrimenti) salvare il candidato per l'ingresso $ 1-V uscita 1


4

Brachylog , 9 byte

h⊇Ċ.+~t?∧

Provalo online!

Supponendo di aver compreso correttamente la sfida ...

Spiegazione

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 byte

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

Provalo
Provalo senza nessun risultato possibile

Allargato:

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

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

Restituisce una coppia di numeri sotto forma di un array se trovato, altrimenti restituisce undefinedun valore errato.

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


L'esempio è stato, 3, 5ma questo produce 1, 7...
Neil

@Neil, scusa, ho modificato le regole perché ho sbagliato. 1,7 è ok.
philcolbourn,

1
Non funzionerà per f([2,2] 4)?
cliffroot,

1
@cliffroot dovrebbe funzionare per quel caso ora
Tom

1
Bel includestrucco.
Neil,

4

JavaScript (ES6), 61 57 56 byte

Prende l'array di numeri interi ae la somma prevista snella sintassi del curry (a)(s). Restituisce una coppia di numeri interi corrispondenti come un array o undefinedse non esiste una coppia del genere.

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

Formattato e commentato

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

Test


3

Gelatina , 14 byte

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

Provalo online!

Questa è una funzione (non un programma completo) che genera l'output standard. (Il collegamento TIO ha un wrapper che esegue una funzione e ignora il suo valore restituito.)

Questo programma potrebbe essere più corto di 4 byte se non per il requisito del codice di uscita; restituire un codice di uscita 1 in Jelly è abbastanza difficile. (È possibile che ci sia un modo più difficile per farlo che mi sono perso.)

Spiegazione

Œ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

Possiamo dimezzare ogni numero intero in una coppia, quindi o⁶Hnon faremo nulla se trovassimo un risultato, a parte restituire un valore di ritorno inutile che non è comunque rilevante ( serve come un metodo a byte singolo conveniente per determinare il ritorno della funzione valore in anticipo, secondo le regole PPCG). Tuttavia, se non abbiamo trovato un risultato, finiamo per provare a dimezzare un personaggio spaziale, un'operazione così insignificante da provocare il crash dell'interprete Jelly. Fortunatamente, questo arresto anomalo produce un codice di uscita pari a 1.


3

Perl 5 , 51 byte

46 byte di codice + per 5 byte per -pli flag.

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

Provalo online!

L'idea è quella di iterare nell'elenco di input: su un numero x( $_), se in precedenza abbiamo visto n-x( $^I-$_), abbiamo trovato quello che stavamo cercando e impostato $\su questi due valori ( "$_ $v"). Alla fine, se $\non impostato, allora noi exit 1, altrimenti verrà stampato implicitamente.


Una scheda letterale funziona al posto dei due personaggi ^I?

@ ais523 Sembra che non ci riesca. Forse era possibile nelle versioni precedenti di Perl.
Dada,

3

Röda , 60 56 byte

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

Provalo online!

Questo codice genera un errore se non c'è risposta. Genera tutte le possibili coppie che possono formare la somma s, cioè. 1, s-1, 2, s-2, 3, s-3, ... Poi controlla se entrambi i numeri sono nella matrice ae, in caso affermativo, li spinge al torrente. pulllegge un valore dallo stream e lo restituisce. Se non ci sono valori nello stream, viene generato un errore. a-xrestituisce l'array acon xrimosso.


3

Python 2, 60 byte

Questo breve, fino a quando le regole con uscita con il codice 1 vengono chiarite. Ora esce con errore se non viene trovato nulla.

-5 byte grazie a @Peilonrayz

-4 byte grazie a @Rod

Provalo online

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

@Peilonrayz Non me ne sono reso conto, grazie!
Dead Possum,

@Peilonrayz Questo violerebbe la regola fith: devono essere restituiti due numeri interi in posizioni diverse nell'elenco. (cioè non puoi restituire lo stesso numero dalla stessa posizione due volte)
Dead Possum

3
Puoi usare spazi + tab per rientro misto per ridurre 2 byte o passareinput() a ridurre 4 byte
Rod

@Rod Grazie! L'ingresso sembra più bello
Dead Possum,

2
@Eric Duminil Sì. È equivalente a eval(raw_input())(penso).
Yytsi,

2

C ++ 133 byte (compilato con 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 byte

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
Benvenuti nel sito! Sfortunatamente, penso che devi aggiungere 15 byte per #include <set>e qualche altro per std::set. Anche se puoi anche salvare alcuni byte se rimuovi le parentesi graffep.insert(v-i);
James

@DJMcMayhem oh, grazie. Quindi dovrei includere main ()?
em2er,

@ em2er No, non è necessario includerlo main. Consideriamo (se non diversamente indicato nella sfida) che una funzione è una presentazione valida. (benvenuto sul sito tra l'altro!)
Dada,

No, l'invio di una funzione va bene. (E molto più breve perché puoi prendere l'input come argomento) Devi solo contare qualsiasi inclusione richiesta dalla tua richiesta.
James,

1
@DJMcMayhem @Dada grazie mille! non ne sono sicuro end, ma si compila su gcc senza std::(e impostato se ovviamente no)
em2er

2

Haskell , 34 byte

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

Provalo online!

Per ogni elemento dell'elenco, questa funzione controlla se (sum-element) è nella parte seguente dell'elenco. Restituisce la prima coppia che trova. Se la funzione raggiunge la fine dell'elenco genera un errore "schemi non esaustivi" ed esce con il codice 1.


Temo che questo approccio non funzioni per input come [2,2]#4.
Laikoni,

@Laikoni Grazie, non avevo letto abbastanza bene la sfida. Questa nuova versione dovrebbe essere corretta (e più breve ^^)
Leo

2

PowerShell, 109 97 byte

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

Ha preso un affare di 12 byte offerto da AdmBorkBork

Spiegazione

# 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

Le regole attuali cercano il codice di uscita che fa questo. Quelli potrebbero essere rimossi e controllare solo la restituzione dei numeri e una falsità.

Esempio di utilizzo

Se il codice sopra è stato salvato come funzione s

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

È possibile salvare qualche byte in più eliminando $ce ($a.count-1)..1|%{$f=$_;--$_..0|%{if...
ripetendo il

2

R, 49 byte

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

Questo trova tutte le 2 combinazioni di xe restituisce una matrice. Quindi, somma per colonna e trova tutte le somme uguali y(quindi senza la [,1]parte alla fine stamperà tutte le combinazioni a cui corrispondono le loro somme y)


2

Japt , 9 byte

Salvati molti byte grazie a @ETHproductions

à2 æ_x ¥V

Provalo online!

Spiegazione

à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   

Esempio

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 byte

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

Salvato 1 byte grazie a @Cyoce e altri 8 byte grazie a @ETHProductions

Ciò restituisce una tupla con la prima combinazione di elementi di elenco che si sommano all'input dato o nulla per nessuna corrispondenza. Ho rimosso la vars nella funzione; REPL.it si blocca senza di loro, ma la Chrome Dev Console gestisce questo bene ...

Provalo online!


Non esce dal codice 1, poiché la sfida richiede specificamente input non validi. Per ora è una risposta non valida, ma ho chiesto a OP di questo requisito per le lingue che non possono farlo facilmente.
Rɪᴋᴇʀ

@Matt Sì, questa regola è rispettata: se y=x+1ne occupa.
Steenbergh,

1
È possibile utilizzare a=>b=>...per salvare un byte
Cyoce

1
È possibile salvare altri tre byte con for(y=x;++y<b.length;){. Inoltre, puoi rimuovere tutti i set di parentesi graffe tranne quello più esterno e puoi rimuovere lo spazio doporeturn
ETHproductions

1

Clojure, 77 byte

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

Restituisce la prima di queste coppie o nil .


1

Haskell, 62 byte

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

Non so ancora cosa sia permesso dalla sfida e cosa no. Vado per una funzione che stampa una coppia di numeri e restituisce 0 se c'è una soluzione e non stampa nulla e restituisce 1 se non c'è soluzione. Poiché la stampa è I / O, devo elevare i valori di ritorno in IO-Monad (via return) e il tipo effettivo della funzione èNum a => IO a .

Esempio di utilizzo (con valore di ritorno stampato dal sostituto):

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

Provalo online!.

Se è consentita la raccolta di eccezioni, failverranno salvati alcuni byte (totale 51):

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

1

Gelatina , 9 byte

ŒcS=¥ÐfḢZ

Jelly non ha modo di impostare il codice di uscita su valori arbitrari, quindi questo produce un TypeError per l'input senza una soluzione valida che provocherà l'uscita dell'interprete principale con il codice di uscita 1 .

Provalo online!

Come funziona

Œ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 byte

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

Una cosa bella del code golf è che mi aiuta a trovare bug nella mia lingua. ad es. lo spazio richiesto tra returne [y,x-y].

Una volta aggiunto le funzioni push / pop ad Array.nova e risolto il ritorno, sarebbe 96 byte:

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

Modifica: Inoltre, c'è anche questo modo a 73 byte (69 usando pop):

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

firstOrThrow genererà un'eccezione, che non sarà rilevata e quindi alla fine uscirà dal programma con il codice di uscita 1.;)

In questo modo sembra anche più leggibile.


0

Pyth, 12 byte

hfqsThQ.ceQ2

Spiegazione

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

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

accetta input dagli argomenti della riga di comando, sommando prima. Corri con -nr.

Fortunatamente, die/ exitesce con 0quando gli dai una stringa come parametro.

Ho provato a unire i loop a uno; ma richiede un'inizializzazione più lunga e test questa volta.


Brutta giornata? for($i=1;$a=$argv[$k=++$i];)for(;$b=$argv[++$k];)$a+$b!=$argv[1]?:die(!0);e dovresti dare un'occhiata a questo codegolf.stackexchange.com/questions/120803/…
Jörg Hülsermann

0

Mathematica, 76 byte

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

Abbastanza semplice: #~Subsets~{2}ottiene tutti i sottoinsiemi a 2 elementi dell'elenco, quindi Cases[...,x_/;Tr@x==#2]seleziona solo quelli la cui somma è il numero che vogliamo. Se non ce ne sono, If[l=={}, Message@f::e,First@l]stampa il messaggio di erroref::e : 1 che abbiamo definito in precedenza (poiché non ho idea di cos'altro potrebbe significare "exit status 1" per Mathematica); in caso contrario, restituisce la prima voce nell'elenco di coppie che si somma alla cosa corretta.

Se ci è permesso di restituire un valore di falso invece di fare quella strana cosa dello stato di uscita, il seguente codice ha 58 byte:

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

0

Scala, 55 41 byte

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

Restituisce un elenco dei due numeri se esistono e genera un errore in caso contrario. Non rilevato, questo errore comporterà uno stato di uscita pari a 1.


0

Rubino, 53 48 byte

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

Input: a è l'elenco, s è la somma prevista.

Se vengono trovati i 2 numeri, stampali e restituisci 0, altrimenti restituisci 1, come da specifica.


0

TI-Basic, 59 byte

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

Spiegazione:

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 il programma non è stato chiuso correttamente, causerà un errore quando non ci sono abbastanza elementi nell'elenco per continuare.


0

CJam, 23 byte

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

L'input è sum numbers. Ad esempio: 6 [3 2 3]. Lascia un numero positivo per verità e una stringa vuota o 0 per falsità.

Spiegazione:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.