Girdiyi toplamak için sırasız bir listeden iki tamsayı bulun


13

Bu bir Google röportaj sorusudur, youtube bağlantısı için buraya bakın.

Görev:

Sıralanmamış bir listeden belirli bir tam sayıya toplanan 2 tam sayı bulun.

  1. Sırasız bir tamsayı listesi verildiğinde, belirli bir değeri toplayan 2 tamsayı bulun, bu 2 tamsayıyı yazdırın ve başarıyı belirtin (çıkış 0). Belirli bir sayı olması gerekmez (yani doğru sayıya toplanan ilk 2 tam sayı), değeri toplayan herhangi bir çift çalışır.
  2. bir tamsayı pozitif ve sıfırdan büyük.
  3. bir tamsayı listesi, bir tamsayı dosyası da dahil olmak üzere herhangi bir veri yapısında olabilir - her satıra bir tam sayı.
  4. tamsayı bulunamazsa bir hata belirtin (çıkış 1).
  5. listedeki farklı konumlarda iki tamsayı döndürülmelidir. (yani, aynı numarayı aynı konumdan iki kez döndüremezsiniz)

(Not: videoda bunlar tam olarak şart değildir. 'Görüşmeci' birçok kez değişti.)

Örneğin.

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

Çıktı 3ve 5çıkış durumu 0'dır. Burada 1,7ve 2,6sonuçlara izin verileceğini unutmayın.

sum2 8 <<EOF
1
2
3
4

Olası birleşik giriş olmadığı için çıkış durumu 1'i döndürür. 4,4kural 5 uyarınca izin verilmez.


15
Öncelikle Sandbox'taki gevşek uçlardan bazılarını sallama şansı olsaydı bu harika bir soru olabilirdi . Örneğin, böyle bir şey için ya bir değer ya da bir çift sayı döndüren bir işlev yazmayı beklerdim.
Neil

2
Örnekte, döndürülen çift neden (1,7) değil (3,5) 'dir?
Rod

4
Sırasız bir listede "ilk" çift nasıl olabilir? Bu kendiliğinden çelişkili.
Peter Taylor

23
Gerçekten çıkış 0 / çıkış 1 şey iyi bir fikir olduğunu sanmıyorum. Birçok dil bu şekilde kolayca var olamaz ve genellikle bir hata ile çıkmasına izin verilir (yani STDERR'i yoksay) Birçok golf dilinin çıkış koduyla çıkmak için kolay bir yolu olmadığını düşünüyorum
Rɪᴋᴇʀ

2
İkinci düşüncede, bazı cevaplar çıkış kodu 1 üretmek için biraz çaba sarf etti, bu yüzden şimdi gereksinimleri değiştirmemek daha iyi olabilir
Luis Mendo

Yanıtlar:


5

Bash, 84 bayt

Benim uyguladığım (kabaca) Google'ın mühendisinin çözümünü bash ve bir girdi akışı kullanıyorum - benim çözümüm değil, dolayısıyla bu sayılmaz.

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

Yöntem

$ 1 hedefinden azsa giriş akışından tamsayı V okuyabilir, daha sonra $ 1-V görüyorsanız $ 1-V ve V yazdırabilir ve çıkış 0 (else) için $ 1-V çıkış 1 için aday kaydedebilirsiniz


4

Brachylog , 9 bayt

h⊇Ċ.+~t?∧

Çevrimiçi deneyin!

Meydan okumayı doğru anladığımı varsayarak…

açıklama

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 bayt

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

Deneyin
Olası bir sonuç olmadan deneyin

Expanded:

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

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

undefinedBulunursa dizi biçiminde bir çift sayı döndürür , aksi takdirde bir yanlış değeri döndürür .

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


Örnek 3, 5ancak bu çıktılar 1, 7...
Neil

@Neil, üzgünüm, kuralları değiştirdim çünkü dağıttım. 1,7 iyi.
philcolbourn

1
Bu işe yaramaz f([2,2] 4)mı?
cliffroot

1
@cliffroot şimdi bu dava için çalışmalı
Tom

1
Güzel includesnumara.
Neil

4

JavaScript (ES6), 61 57 56 bayt

Tamsayılar dizisini ave ssözdiziminde beklenen toplamı alır (a)(s). Dizi olarak bir çift eşleşen tamsayı veya undefinedböyle bir çift yoksa döndürür .

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

Biçimlendirilmiş ve yorumlanmış

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

Ölçek


3

Jöle , 14 bayt

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

Çevrimiçi deneyin!

Bu, standart çıktıya çıkan bir işlevdir (tam bir program değildir). (TIO bağlantısında bir işlevi çalıştıran ve dönüş değerini göz ardı eden bir sarıcı bulunur.)

Bu program, çıkış kodu gereksinimi için değilse 4 bayt daha kısa olabilir; Jelly'de 1 çıkış kodunu döndürmek oldukça zordur. (Bunu yapmanın, kaçırdığım ters bir yol olması mümkündür.)

açıklama

Œ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

Bir çiftte her tamsayıyı yarıya indirebiliriz, bu yüzden o⁶Hbir sonuç bulursak hiçbir şey yapmaz, yine de alakalı olmayan işe yaramaz bir dönüş değeri döndürmek dışında ( işlevin dönüşünü belirlemek için uygun bir tek bayt yöntemi olarak hizmet eder) PPCG kuralları uyarınca erken değer). Ancak, bir sonuç bulamazsak, boşluk karakterini yarıya indirmeye çalışırız, yani anlamsız bir işlem Jelly yorumlayıcısının çökmesine neden olur. Neyse ki, bu çökme 1 çıkış kodu üretir.


3

Perl 5 , 51 bayt

46 bayt kod + -plibayraklar için 5 bayt .

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

Çevrimiçi deneyin!

Fikir, giriş listesinde tekrarlamaktır: bir sayı x( $_) üzerinde, daha önce n-x( $^I-$_) gördüğümüzde, aradığımızı bulduk ve $\bu iki değere ( "$_ $v") ayarladık . Sonunda, $\ayarlanmadıysa, biz exit 1, aksi takdirde örtük olarak yazdırılacaktır.


Değişmez sekme iki karakterin yerine çalışır ^Imı?

@ ais523 Yapamam gibi görünüyor. Belki de Perl'in eski sürümlerinde mümkün oldu.
Dada

3

Röda , 60 56 bayt

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

Çevrimiçi deneyin!

Yanıt yoksa bu kod bir hata atar. Toplamı oluşturabilecek tüm olası çiftleri oluşturur s, yani. 1, s-1, 2, s-2, 3, s-3, ... Sonra her iki sayılar dizisinde ise denetler ave eğer öyleyse, akışa onları iter. pullakıştan bir değer okur ve döndürür. Akışta hiç değer yoksa bir hata atar. a-xdizi döner aile xuzaklaştırıldı.


3

Python 2, 60 bayt

Bu kısa, kod 1 ile çıkış kuralları açıklığa kavuşana kadar. Hiçbir şey bulunmazsa şimdi hata ile çıkar.

@Peilonrayz sayesinde -5 bayt

@Rod sayesinde -4 bayt

Çevrimiçi deneyin

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

@Peilonrayz Farkında değildim, teşekkürler!
Dead Possum

@Peilonrayz Bu kuralın ihlali anlamına gelir: listedeki farklı konumlarda iki tamsayı döndürülmelidir. (örneğin, aynı numarayı aynı konumdan iki kez döndüremezsiniz)
Dead Possum

3
Şunları yapabilirsiniz karışık girinti için boşluk + sekmeleri kullanın 2 bayt azaltmak veya geçmekinput() 4 bayt azaltmak için
Çubuk

@Rod Teşekkürler! Girdi daha güzel görünüyor
Dead Possum

2
@Eric Duminil Evet. Eşdeğerdir eval(raw_input())(sanırım).
Yytsi

2

C ++ 133 bayt (clang 4 ve gcc 5.3 ile derlenmiştir -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 bayt

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
Siteye Hoşgeldiniz! Ne yazık ki, 15 bayt #include <set>ve birkaç tane daha eklemeniz gerektiğini düşünüyorum std::set. Parantezleri kaldırırsanız da bazı baytlar kaydedebilirsinizp.insert(v-i);
James

@DJMcMayhem oh, teşekkür ederim. Yani main () içermeli mi?
em2er

@ em2er Hayır, dahil etmeniz gerekmez main. (Meydan okumada aksi belirtilmedikçe) bir işlevin geçerli bir gönderim olduğunu düşünüyoruz. (btw sitesinde hoş geldiniz!)
Dada

Hayır, bir işlev gönderimi iyidir. (Ve çok daha kısadır, çünkü girdiyi bağımsız değişken olarak alabilirsin) Yalnızca gönderiminizin gerektirdiği tüm öğeleri saymanız yeterlidir.
James

1
@DJMcMayhem @Dada çok teşekkürler! ben de emin değilim end, ama olmadan gcc üzerinde derler std::(ve ders değilse ayarlayın)
em2er

2

Haskell , 34 bayt

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

Çevrimiçi deneyin!

Listenin her öğesi için, bu işlev (sum-element) öğesinin aşağıdaki bölümde olup olmadığını kontrol eder. Bulduğu ilk çifti döndürür. İşlev listenin sonuna ulaşırsa, "kapsamlı olmayan desenler" hatası atar ve kod 1 ile çıkar.


Korkarım bu yaklaşım gibi girdiler için işe yaramıyor [2,2]#4.
17'de Laikoni

@Laikoni Teşekkürler, bu meydan okumayı yeterince iyi okumamıştım. Bu yeni sürüm doğru olmalı (ve daha kısa ^^)
Leo

2

PowerShell, 109 97 bayt

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

AdmBorkBork'un sunduğu 12 baytlık bir anlaşma aldı

açıklama

# 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

Geçerli kurallar, bunun yaptığı çıkış kodunu arar. Bunlar kaldırılabilir ve sadece döndürülen sayıları ve bir sahneyi kontrol edebilir.

Örnek Kullanımı

Yukarıdaki kod işlev olarak kaydedildiyse 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...
Kaldırıp

2

R, 49 bayt

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

Bu, tüm 2 kombinasyonlarını bulur xve bir matris döndürür. Daha sonra, sütuna göre toplamlar ve eşit olan tüm toplamları bulur y(böylece [,1]sonunda bölüm olmadan toplamlarının eşit olduğu tüm kombinasyonları yazdırır y)


2

Japt , 9 bayt

@ETHproductions sayesinde çok bayt tasarrufu

à2 æ_x ¥V

Çevrimiçi deneyin!

açıklama

à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   

Misal

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 bayt

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 sayesinde 1 bayt ve @ETHProductions sayesinde 8 bayt tasarruf etti

Bu, verilen girdiyi toplayan liste öğelerinin ilk birleşimiyle bir eşleşme döndürür veya eşleşme için hiçbir şey döndürmez. Ben varişlev s kaldı; REPL.it onlarsız çöküyor, ancak Chrome Dev Konsolu bu iyi durumda ...

Çevrimiçi deneyin!


Meydan okuma özellikle geçersiz giriş istediği için kod 1'den çıkmaz. Şimdilik geçersiz bir yanıt, ancak OP'ye bunu kolayca yapamayan diller için bu gereksinimi sordum.
Rɪᴋᴇʀ

@Matt Evet, bu kurala uyulur: y=x+1bununla ilgilenir.
steenbergh

1
a=>b=>...Bir bayt kaydetmek için kullanabilirsiniz
Cyoce

1
İle üç bayt daha kaydedebilirsiniz for(y=x;++y<b.length;){. Ayrıca, en dıştaki hariç tüm parantez setlerini kaldırabilir ve daha sonra alanı kaldırabilirsinizreturn
ETHproductions

1

Clojure, 77 bayt

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

Bu gibi ilk çifti veya döndürür nil.


1

Haskell, 62 bayt

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

Hala meydan okumaya neyin izin verdiğini ve neye izin vermediğini bilmiyorum. Bir çözüm varsa bir çift sayı basan ve 0 döndüren bir işlev için gidiyorum ve hiçbir şey yazdırmaz ve çözüm yoksa 1 döndürür. Yazdırma G / Ç olduğu için, dönüş değerlerini IO-Monad'a (üzerinden return) kaldırmam gerekir ve işlevin gerçek türü Num a => IO a.

Kullanım örneği (dönüş değeri repl tarafından yazdırılmış olarak):

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

Çevrimiçi deneyin! .

İstisnaların yükseltilmesine izin veriliyorsa, failbazı bayt tasarrufu sağlar (toplam 51):

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

1

Jöle , 9 bayt

ŒcS=¥ÐfḢZ

Jelly'in çıkış kodunu rastgele değerlere ayarlamanın bir yolu yoktur, bu nedenle bu , üst yorumlayıcının çıkış kodu 1 ile çıkmasına neden olacak geçerli bir çözümü olmayan giriş için bir TypeError üretir .

Çevrimiçi deneyin!

Nasıl çalışır

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

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

Kod golf hakkında güzel bir şey, benim dilimde hataları bulmak bana yardımcı olmasıdır. örneğin uzay arasında gerekli returnve [y,x-y].

Array.nova'ya push / pop fonksiyonları ekleyip dönüşü düzelttikten sonra 96 ​​bayt olur:

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

Kullanımı:

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

Düzenleme: Ayrıca, 73 bayt (69 pop kullanarak) de bu şekilde:

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

firstOrThrow yakalanmamış bir istisna atar ve bu nedenle sonuçta çıkış kodu 1 ile programdan çıkar.;)

Bu şekilde daha okunabilir görünüyor.


0

Pyth, 12 bayt

hfqsThQ.ceQ2

açıklama

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

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

Komut satırı bağımsız değişkenlerinden girdi alır, önce toplamı. İle çalıştırın -nr.

Neyse ki, die/ parametresi olarak bir dize verdiğinizde / ile exitçıkar 0.

Döngülerle birleştirmeyi denedim; ancak bu sefer daha uzun bir başlatma ve test gerektirir.


Kötü bir gün mü? for($i=1;$a=$argv[$k=++$i];)for(;$b=$argv[++$k];)$a+$b!=$argv[1]?:die(!0);ve bu koda
Jörg Hülsermann

0

Mathematica, 76 bayt

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

Oldukça basit: #~Subsets~{2}listenin tüm 2 elemanlı alt kümelerini Cases[...,x_/;Tr@x==#2]alır , sonra sadece toplamı istediğimiz sayı olanları alır. Bunlardan hiçbiri yoksa, daha önce tanımladığımız If[l=={}, Message@f::e,First@l]hata mesajını yazdırır f::e : 1(Mathematica için başka bir "çıkış durumu 1" ne anlama gelebileceğine dair hiçbir fikrim olmadığından); aksi takdirde, çiftler listesindeki doğru girdiyi toplayan ilk girdiyi döndürür.

Bu garip çıkış durumu işlemini yapmak yerine bir falsey değeri döndürmemize izin verilirse, aşağıdaki kod 58 bayt içerir:

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

0

Scala, 55 41 bayt

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

Varsa, iki sayının listesini döndürür ve aksi halde hata atar. Yakalanmadığında, bu hata 1 çıkış durumuna neden olur.


0

Yakut, 53 48 bayt

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

Girdi: a liste, s beklenen toplam.

2 sayı bulunursa, bunları yazdırın ve 0 döndürün, aksi takdirde belirtimdeki gibi 1 döndürün.


0

TI-Basic, 59 bayt

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

Açıklama:

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

Program zarif bir şekilde çıkmadıysa, listede devam etmek için yeterli öğe olmadığında hataya neden olur.


0

CJam, 23 bayt

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

Girdi sum numbers. Örneğin: 6 [3 2 3]. Doğruluk için pozitif bir sayı ve falsey için boş bir dize veya 0 bırakır.

Açıklama:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.