Знайдіть два цілих числа із не упорядкованого списку для підсумовування вхідних даних


13

Це питання інтерв'ю Google, дивіться тут посилання на youtube.

Завдання:

Знайдіть 2 цілих числа з не упорядкованого списку, які підсумовують задане ціле число.

  1. З огляду на не упорядкований список цілих чисел, знайдіть 2 цілих числа, які дорівнюють заданому значенню, надрукуйте ці 2 цілі числа та вкажіть успіх (вихід 0). Їм не потрібно бути певних чисел (тобто перші два цілих числа, що підсумовують правильне число), будь-яка пара, яка підсумовує значення, буде працювати.
  2. ціле число додатне і більше нуля.
  3. список цілих чисел може бути в будь-якій структурі даних, включаючи файл цілих чисел - одне ціле число на рядок.
  4. якщо цілих чисел не знайти, вкажіть на помилку (вихід 1).
  5. два цілих числа на різних позиціях у списку повинні бути повернені. (тобто ви не можете повернути одне і те ж число з тієї ж позиції двічі)

(Примітка. На відео це не зовсім відповідні вимоги. "Інтерв'юер" міняв кілька разів.)

напр.

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

Друк 3і 5вихід статусу 0. Зауважте, що в цьому 1,7і 2,6будуть дозволені результати.

sum2 8 <<EOF
1
2
3
4

Повертає статус виходу 1, оскільки немає можливого комбінації. 4,4заборонено, згідно правила 5.


15
Це могло бути великим питанням, якби він мав шанс спочатку витрусити частину пухких кінців у пісочниці . Наприклад, для чогось подібного я очікував би написати функцію, яка повертає або хибне значення, або пару чисел.
Ніл

2
У прикладі, чому повернута пара дорівнює (3,5), а не (1,7)?
Пруд

4
Як у списку не упорядкованих може бути пара "перша"? Це по суті суперечливо.
Пітер Тейлор

23
Я не думаю, що річ "вихід 0 / вихід 1" - це гарна ідея. Багато мов не може існувати так легко, і зазвичай це дозволяється виходити з помилкою (тобто ігнорувати STDERR) Багато мов для гольфу навіть не мають простого способу виходу за кодом виходу, я думаю
Rɪᴋᴇʀ

2
По-друге, деякі відповіді пройшли певні зусилля, щоб створити вихідний код 1, тому, можливо, краще не змінювати вимоги зараз
Луїс Мендо

Відповіді:


5

Баш, 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 дол.



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, хибне значення.

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, вибачте, я змінив правила, тому що я заплутався. 1,7 - це нормально.
philcolbourn

1
Це не працюватиме f([2,2] 4)?
Скеля

1
@cliffroot має працювати над цією справою зараз
Том,

1
Гарний includesтрюк.
Ніл

4

JavaScript (ES6), 61 57 56 байт

Бере масив цілих чисел aі очікувана сума sв синтаксисі currying (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 байти коротшою, якби не вимога коду виходу; повернути вихідний код 1 в Jelly досить важко. (Цілком можливо, що є більш стислий спосіб зробити це, що я пропустив.)

Пояснення

Œ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"). Зрештою, якщо $\це не встановлено, то ми exit 1, інакше це буде неявно надруковано.


Чи працює буквальна вкладка замість двох символів ^I?

@ ais523 Схоже, я не можу. Можливо, це було можливо і на старих версіях Perl.
Дада

3

Рода , 60 56 байт

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

Спробуйте в Інтернеті!

Цей код видає помилку, якщо немає відповіді. Він генерує всі можливі пари, які можуть утворювати суму s, тобто. 1, s-1, 2, s-2, 3, s-3, ... Тоді він перевіряє , якщо обидва числа в масиві , aі якщо так, підштовхує їх до потоку. pullзчитує одне значення з потоку і повертає його. Якщо в потоці немає значень, це видає помилку. a-xповертає масив aз xвидаленим.


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 Це порушило би правило: два цілі числа в різних позиціях у списку повинні бути повернуті. (тобто ви не можете повернути одне і те ж число двічі)
Dead Possum

3
Ви можете використовувати пробіли + вкладки для змішаного відступу, щоб зменшити 2 байти, або переключитисьinput() на зменшення 4 байтів
стрижень

@Rod Дякую! Введення здається приємнішим
Dead Possum

2
@Eric Duminil Так. Це рівнозначно eval(raw_input())(я думаю).
Yytsi

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);
Джеймс

@DJMcMayhem о, дякую Тож я повинен включати main ()?
em2er

@ em2er Ні, вам не потрібно включати main. Ми вважаємо (якщо в виклику не вказано інше), що функція є дійсною подачею. (Ласкаво просимо на сайт btw!)
Dada

Ні, подання функції нормально. (І набагато коротше, тому що ви можете сприймати дані як аргументи) Вам просто потрібно порахувати будь-які включення, необхідні для подання.
Джеймс

1
@DJMcMayhem @Dada велике спасибі! Я теж не впевнений у endтому, але він збирається на gcc без std::(і встановити, якщо звичайно, ні)
em2er

2

Хаскелл , 34 байти

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

Спробуйте в Інтернеті!

Для кожного елемента списку ця функція перевіряє, чи (sum-елемент) знаходиться у наступній частині списку. Повертає першу знайдену пару. Якщо функція доходить до кінця списку, вона видає помилку "не вичерпні шаблони" і виходить із кодом 1.


Я боюся, що такий підхід не працює для вхідних даних [2,2]#4.
Лайконі

@Laikoni Дякую, я недостатньо добре прочитав виклик. Ця нова версія повинна бути правильною (і коротше ^^)
Лев,

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

Взяв угоду на 12 байт, яку запропонував AdmBorkBork

Пояснення

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

Збережено 1 байт завдяки @Cyoce та ще 8 байт завдяки @ETHProductions

Це повертає кортеж з першою комбінацією елементів списку, які підсумовують даний вхід, або нічого за безвідповідність. Я видалив vars у функції; REPL.it завершує роботу без них, але консоль Chrome Dev справляється із цим просто ...

Спробуйте в Інтернеті!


Не виходить з коду 1, оскільки виклик спеціально вимагає недійсного введення. Наразі це невірна відповідь, але я запитав ОП про цю вимогу для мов, які не можуть зробити це так легко.
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

Хаскелл, 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, якщо немає рішення. Оскільки друк - це введення-виведення, я повинен підняти повернені значення в IO-Monad (через return), і фактичний тип функції є Num a => IO a.

Приклад використання (зі зворотним значенням, надрукованим відбитком):

*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].

Щойно я додаю функції Array.nova до push / pop та виправляю повернення, буде 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 байтах (69 за допомогою pop) теж є:

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/…
Jörg Hülsermann

0

Математика, 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); в іншому випадку він повертає перший запис у списку пар, який підсумовує правильну річ.

Якщо нам дозволено повернути значення фальси, замість того, щоб робити це дивне значення статусу виходу, наступний код має 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]. Залишає додатне число для truthy та порожній рядок або 0 для falsey.

Пояснення:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.