Cocokkan hingga 10 dalam satu array

8

Tantangan

Diberikan array nomor digit tunggal, tentukan jika ada 2 dari mereka yang menambahkan hingga 10 dan cetaklah

Contoh

Memasukkan

(1,2,3,4,5,5,6,7)

Ini kembali ((4,6),(5,5),(3,7))

Memasukkan

(1,2,3,4,5)

Ini kembali (). karena hanya ada satu 5

Memasukkan

(5,5,5,5,5)

Ini kembali ((5,5),(5,5))karena ada jumlah ganjil dari 5s dan masing-masing 5 hanya dapat digunakan sekali

Aturan

Ini peraturannya!

  • Asumsikan input hanya akan berupa array bilangan bulat digit positif tunggal
  • Setiap angka hanya akan berpasangan satu kali, yang berarti jika ada tiga 5 itu hanya membentuk 1 pasangan (5,5). Jika ada (3,3,7) itu hanya akan membentuk 1 pasang (3,7)
  • Untuk input: Anda dapat menggunakan semua jenis tanda kurung (atau kurang dari) selama pembaca dapat mengetahui bahwa input adalah satu array angka.
  • Untuk hasilnya: Ini harus terlihat seperti array pasangan. Di mana array adalah bentuk yang sama dengan input Anda. (Jika Anda tidak menggunakan tanda kurung di input Anda, Anda harus menggunakan beberapa jenis simbol sehingga setiap pembaca dapat mengatakan mereka berpasangan dalam array)

Uji Kasus

(1,2,3,4,5,5,6,7) =((4,6),(5,5),(3,7))
(1,2,3,4,5) = ()
(5,5,5,5,5) = ((5,5),(5,5))
(1,2,3,3,4,5,6,7)=((3,7),(4,6))
(9,8,7,6,4,4,3,1)=((9,1),(7,3),(6,4))

Semoga berhasil!

The shorterjawaban, semakin baik!

Sunting 1: perbarui aturan dan Testcases dari komentar

Sunting 2: perbarui aturan untuk menentukan format input.

Sunting 3: perbarui aturan untuk menentukan format output. berusaha semaksimal mungkin.

pengguna1655072
sumber
2
Tidakkah seharusnya ada 10 kombinasi berbeda (5,5)untuk kasus ujian akhir?
Gareth
@ Gareth Sepertinya nilai-nilai terbiasa ketika mereka membuat pasangan
Matt
Bisakah Anda memposting beberapa test case lagi? Mungkin kira-kira seperti(1,2,3,3,4,5,6,7)
Matt
@Matt diedit. Terima kasih atas umpan baliknya
user1655072
Apakah input harus menyertakan tanda kurung, atau dapatkah dimasukkan sebagai 1,2,3,4,5,5,6,7?
jdstankosky

Jawaban:

7

GolfScript, 45 42 37 karakter

~{([.~11+.])@{1$=.{2$p!\}*!},\;\;.}do

Pendekatan baru juga mengambil array dengan satu item sebagai input. Selain itu, beberapa karakter lebih pendek.

Versi sebelumnya:

~{$(\)@.2$+10-.{0>{\}*;+}{;[\]p}if.,1>}do;

Algoritma yang digunakan dalam kode ini dijelaskan sebagai berikut:

  • Sortir susunannya.
  • Ambil jumlah item pertama dan terakhir.
    • Jika jumlahnya 10 cetak kedua angka dan hapus dari array.
    • Jika jumlahnya lebih besar dari 10, buang nomor yang lebih besar.
    • Jika jumlahnya kurang dari 10, buang nomor yang lebih kecil.
  • Loop sampai array hanya berisi satu digit atau bahkan kosong.

Kode mengharapkan array setidaknya dua digit pada STDIN.

Contoh (lihat online ):

>[9 8 7 6 4 4 3 1]
[1 9]
[3 7]
[4 6]

>[5 5 5 5 5]
[5 5]
[5 5]
Howard
sumber
9

Python 2.7 (70)

y=input()
while y:
 g=10-y.pop()
 if g in y:y.remove(g);print(g,10-g)

Testcases:

$ echo '[1, 2, 3, 4, 5, 5, 6, 7]' | python p.py
(3, 7)
(4, 6)
(5, 5)

$ echo '[1,2,3,4,5]' | python p.py

$ echo '[5,5,5,5,5]' | python p.py
(5, 5)
(5, 5)

$ echo '[1,2,3,3,4,5,6,7]' | python p.py
(3, 7)
(4, 6)

$ echo '[9,8,7,6,4,4,3,1]' | python p.py
(9, 1)
(7, 3)
(6, 4)

Satu byte tambahan untuk tanda kurung yang bagus.

Daniel
sumber
Saya pikir saya meniru metode ini dalam PHP, tetapi hanya berfungsi sesekali dan tidak dengan semua pasangan. Ada yang tahu kenapa? <?$a=fgetcsv(STDIN);while($a){$b=10-array_pop($a);if($a[$b]){unset($a[$b]);echo"($b,",10-$b,")";}}
jdstankosky
5

Javascript, 188 183 181 153 141 121 123 112 105 98 karakter

Golf di JS agak sulit, tapi saya hanya ingin memiliki masalah pada masalah ini, jadi inilah kodenya:

for(a=eval(prompt(i=o=[]));k=a[j=++i];)for(;p=a[--j];)k+p-10||(k=a[i]=a[j]=-o.push([p,k]));console.log(o)

Input: mis [1,2,3,3,4,5,6,7]. Keluaran misalnya [[4,6],[3,7]]ke konsol.

105-> 98: Menggunakan algoritma hebat Daniel untuk menulis ulang kode sepenuhnya! Lihat jawabannya untuk algoritma yang dapat dibaca. Barang-barang benar-benar kacau sehingga dikembalikan ke 105 karakter.

112-> 105: Diinisialisasi ike nol, menggunakan output o.pushuntuk set k( k=a[i]=a[j]=-o.push...) dan output log ke konsol bukannya memperingatkan untuk menghilangkan "["+dan +"]"karena konsol sudah output dengan baik.

123-> 112: Sekarang dihapus tanda kurung luar dalam output, karena golfscript mungkin :) Juga akhirnya diterapkan saran untuk menghapus |=0.

121-> 123: Diubah o+="("+p+","+k+"),"menjadi o.push("("+[p,k]+")")(menambahkan 2 karakter :() dan membuat oarray bukan string ( o=""-> o=[]). Sekarang output tidak salah lagi (seperti ((5,5),(5,5),)).

141-> 121: Mulai sekarang diasumsikan bahwa pertanyaan itu berarti bahwa kita bisa mendapatkan input dalam format array bahasa, yang dalam kasus JS [a,b,c,...]dibuat dan dibuat o, output "akumulator" string bukan array ( o.push(...),-> o+=...,).

153-> 141: Setel ulang entri array alih-alih menghapusnya setelah digunakan.

181-> 153: Perubahan yang diterapkan u=[], loop yang diatur ulang, a[i]& a[j]-> temp vars, dikonversi jika logika dan dikonversi ke logika int a[i]|=0.

183-> 181: Diganti i<=0dengan i+1dan sama untuk j.

188-> 183: Ditempatkan o=[]di dalam prompt()( ;) dan diganti for(j=i;dengan for(j=i-1;( i==j&&).

(Terima kasih mellamokb, Paul Walls dan ryan!)

tommeding
sumber
1
Anda dapat mengganti i>=0dengan i+1dan j>=0dengan j+1untuk menyimpan 2 karakter.
mellamokb
1
Saya menerapkan perubahan ke array bidang bit ( u=[]bukan x), menata ulang loop untuk pergi dari 0 ke atas, ditugaskan a[i]dan a[j]untuk variabel temporer untuk menyimpan referensi berulang, memindahkan beberapa inisialisasi variabel ke dalam pernyataan lain, mengubah iflogika menjadi ||logika rantai , dan mengkonversi int parsing ke yang lebih ringkas a[i]|=0, untuk mendapatkan total penghematan 30 karakter :). Inilah harness pengujian saya yang menunjukkan keakuratan solusi: jsfiddle.net/GKUDb/8 , dan solusi kerja golf 151 karakter: jsfiddle.net/DVtW2 .
mellamokb
1
Array.toString () juga akan menyelamatkan Anda beberapa karakter (yaitu o+="("+[p,k]+")").
Paul Walls
1
Jika Anda baik-baik saja dengan output seperti yang ada pada skrip golf, maka Anda dapat melakukan ini:, for(a=eval(prompt(o=[])),i=-1;k=a[j=++i]|=0;)for(;p=a[--j];)k+p-10||(o.push("["+[p,k]+"]"),k=a[i]=a[j]=-1);alert(o)membawanya ke 115
Ryan
1
Anda lupa saran saya untuk menginisialisasi saya ke 0. Anda dapat melipat a=eval(prompt(o=[])),i=-1ke dalam a=eval(prompt(i=o=[]))tanpa kehilangan kesetiaan, untuk 3 tabungan karakter lebih lanjut.
mellamokb
3

J, 54 53 50 46 45 44 karakter

(>:,.9&-)I.<.4({.,-:@{::)(<.|.)+/|:(1+i.9)=/

Pemakaian:

   (>:,.9&-)I.<.4({.,-:@{::)(<.|.)+/|:(1+i.9)=/5 5 5 5 5
5 5
5 5
   (>:,.9&-)I.<.4({.,-:@{::)(<.|.)+/|:(1+i.9)=/9 8 7 6 4 4 3 1
1 9
3 7
4 6

Algoritma pada dasarnya adalah:

  • hitung instance dari setiap nomor +/|:(1+i.9)=/
  • pasangkan jumlah masing-masing pasangan yang akan menambah 10 (<.|.)(jadi 1 dan 9, 2 dan 8 dll)
  • ambil jumlah minimum dari jumlah tersebut (jadi jika Anda memiliki tiga angka 9 tetapi hanya satu 1 9angka 1, Anda hanya akan memiliki satu pasangan) dan lepaskan semuanya setelah lima pasangan pertama
  • 5s adalah kasus khusus jadi bagilah dengan 2 ( <.4({.,-:@{::)mengimplementasikan kedua langkah sebelumnya)
  • ambil lima item pertama dari daftar dan hasilkan angkanya dan 10 -angkanya(>:,.9&-)I.
Gareth
sumber
3

Python (142)

Masukan harus diberikan dengan tanda kurung siku alih-alih tanda kurung bulat. http://ideone.com/p2QR11

from itertools import*
a=input()
c=lambda:[i for i in product(a,a[1:])if sum(i)==10]
d=c()
while d:print d[0];[a.remove(j)for j in d[0]];d=c()

Algoritma:

1. Get input
2. Generate all pairs of input where the sum is 10
3. If there are no pairs, then END PROGRAM
4. Take the first pair's items and remove them from the input
5. Go back to step 2

Jika output dengan kelainan serius diizinkan (90) : http://ideone.com/GR762f

a=input()
c=a.count
for i in range(6):print(`i`+`10-i`+' ')*(min(c(i),c(10-i))/(1+(i==5)))
beary605
sumber
3

C, 142.138 , 124

char*p,*q;
main(int a,char**s){
    for(p=s[1];*p;p++)
        if(q=strchr(p+1,106-*p))a=*q=printf("%c(%c,%c)",38+a,*p,*q);
    puts("()"+a/6);
}

Pengujian:

./a.out "(1,2,3,4,5,5,6,7)"
((3,7),(4,6),(5,5))

./a.out "(1,2,3,4,5)"
()

./a.out "(5,5,5,5,5)"
((5,5),(5,5))

./a.out "(1,2,3,3,4,5,6,7)"
((3,7),(4,6))

./a.out "(9,8,7,6,4,4,3,1)"
((9,1),(7,3),(6,4))

Catatan implementasi:

  • awalnya a = 2 (program memiliki dua argumen), diatur ke 6 (printf mencetak 6 karakter) setelah kecocokan terjadi
  • 106 = '0' + '0' + 10, yaitu menggunakan jumlah kode ascii
  • 38 + a, adalah 44/40, yaitu '(' atau ','
  • Dengan mengatur karakter string ke 6 itu memastikan mereka tidak akan menambah 106 pada lintasan lainnya
  • "()" + a / 6, apakah "()" atau ")"
bayi-kelinci
sumber
3

Perl 52

perl -ne '$a{$y=9-$_}&&0*$a{$y++}--*print"$y,$_"or$a{$_-1}++'

Bukti:

> cat test
1
2
3
4
5
5
6
7
> perl -ne '$a{$y=9-$_}&&0*$a{$y++}--*print"$y,$_"or$a{$_-1}++' < test
5,5
4,6
3,7

Dan ada kode komentar ungolfed:

while(<>) {     # made by the -n option

    # We are looking for (P,Q) pairs where P+Q=10
    # Each P entry will come in $_="P\n" (because $_ will not be chopped)
    # We choose to store the number of occurence of P in $a{P-1}
    # (For instance, if there have been five '3's in the input, then $a{2}=5)

    $y=9-$_;        # if Q=P-10, then $y=Q-1
    if ($a{$y}) {   # check if there was a Q (so $a{Q-1} != 0)
        $a{$y++}--;   # If so 'consume' this Q, and let $y=Q
        print"$y,$_"; # ... and output "Q,P\n"
    } else {
        $a{$_-1}++;   # P is not forming a new pair, so 'count it'.
                    # $a{$_} would not work because of the un-chopped \n, thus the '-1'
    }

}

Mungkin penjelasannya seperti pidgin Prancis (saya bukan penulis bahasa Inggris asli), jadi jika seseorang ingin mengeditnya dan membuatnya lebih dimengerti, silakan lakukan.

Orabîg
sumber
Serius, bahkan tidak satu poin untuk ini, dengan penjelasan dan semuanya? ... :(
Orabîg
3

Javascript - 131 129 125 karakter

for(i=eval(prompt(r=[])),k=j=i.length;j--;)for(m=k;m--;)if(m!=j&&i[j]+i[m]==10)r.push([i[j],i[m]]),i[j]=i[m]=0;console.log(r)

Saya berasumsi, urutan dan dalam array hasil bersarang tidak wajib :)

Kasus uji yang dievaluasi:

[1,2,3,4,5,5,6,7] returns [[7,3],[6,4],[5,5]]
[1,2,3,4,5]       returns []
[5,5,5,5,5]       returns [[5,5],[5,5]]
[1,2,3,3,4,5,6,7] returns [[7,3],[6,4]]
[9,8,7,6,4,4,3,1] returns [[1,9],[3,7],[4,6]]

Sunting : Seperti uraian masalah yang tertulis 'Array', kita berbicara tentang notasi khusus bahasa array, kan?

codeporn
sumber
2

Mathematica 70

Cases[#//.{x___,n_,y___,d_,z___}/;n+d==10:>{x,y,z,n~f~d},a_~f~b_:>{a,b}]&

Pemakaian

Cases[# //. {x___, n_, y___, d_, z___} /; n + d == 10 :> {x, y, z, n~f~d}, 
a_~f~b_ :> {a,b}] &[{1, 2, 3, 4, 5, 5, 6, 7}]

{{3, 7}, {4, 6}, {5, 5}}

DavidC
sumber
2

PostScript (46)

Ini menggunakan token biner berkode tangan, oleh karena itu, inilah hexdump:

00000000  7b 7b 92 1a 92 3f 7b 32  92 19 92 01 31 30 92 3d  |{{...?{2....10.=|
00000010  7b 32 92 09 92 0b 3d 3d  5b 92 40 7d 69 66 92 1a  |{2....==[.@}if..|
00000020  31 92 87 7d 92 83 92 75  7d 92 65 7d 92 a3        |1..}...u}.e}..|
0000002e

Saya mengunggah file biner jika Anda ingin mencobanya.

Ini mengharapkan nomor berada di tumpukan. Mereka dapat didahului dengan kode atau disediakan pada baris perintah, misalnya ketika menggunakan Ghostscript seperti:

gsnd -c 2 8 5 5 @ 10_golfed.ps

Jika Anda bersikeras pada sintaks array untuk input, maka ini membutuhkan dua token ( aload pop) yang tepat di awal. Dalam token biner, ini adalah empat byte lagi.

Berhenti bermain golf dan berkomentar:

{ % stopped                   % we use stopped because we want to catch a
                              % stackunderflow when all numbers have been used up
  { % loop                    % repeat until all numbers have been popped off the stack
    % Test for all numbers on the stack whether they add up to 10 with the topmost number
    count{                    % ... nextNumber number currentTestNumber
      exch                    % ... nextNumber currentTestNumber number 
      2 copy add 10 eq{       % ... nextNumber currentTestNumber number
        2 array astore ==     % ... nextNumber
        % We push "[" on the stack because we want to pop the topmost object after each iteration.
        % As [ is a one byte self delimiting token, this is nice for golfing.
        [ exit                % ... nextNumber [
      }if                     % ... nextNumber currentTestNumber number
      count 1 roll            % number ... nextNumber currentTestNumber 
    }repeat                   % number ... nextNumber currentTestNumber
    pop                       % number ... nextNumber
  }loop                       
}stopped
Thomas W.
sumber
2

Python 84

Membutuhkan input dalam tanda kurung bukan tanda kurung.

a=input();r=[]
while a:
 n=a.pop(0);m=10-n
 if m in a:a.remove(m);r+=[(n,m)]
print r

Untuk jawaban yang kira-kira sama dengan golf, lebih baik lihat jawaban Daniel .

Steven Rumbalski
sumber
2

PHP 150 149 148 146 142 -> 140

Gunakan dengan PHP CLI.

<?$a=fgetcsv(STDIN);for($i=0;$i<$c=count($a);$i++){for($j=$i+1;$j<$c;$j++)if($a[$i]+$a[$j]==10){echo"({$a[$i]},{$a[$j]})";$a[$i]=$a[$j]=0;}}

Memasukkan: 1,2,3,4,5,5,6,7

Keluaran: (3,7)(4,6)(5,5)

Tidak golf:

<?php

$a = fgetcsv(STDIN);
$c = count($a);
for ($i = 0; $i < $c; $i++) {
    for ($j = ($i + 1); $j < $c; $j++) {
        if ($a[$i] + $a[$j] == 10) {
            echo "({$a[$i]},{$a[$j]})";
            $a[$i] = 0;
            $a[$j] = 0;
        }
    }
}

?>
jdstankosky
sumber
1

SED, 112 karakter

Mungkin agak lebih sederhana daripada solusi lainnya

s/.*/@&;12345678987654321/
:
s/\(@.*\)\(.\)\(.*\)\(.\)\(.*;.*\2.\{7\}\4\)/(\2,\4),\1\3\5/
t
s/^\(.*\),@.*/(\1)/
Hasturkun
sumber
1

Perl, 72 dengan -pbendera

perl -p -e 's/^/@/;1while s/(@.*)(.)(.*)((??{10-$2}))/($2,$4)$1$3/;s/(.*)@.*/($1)/'
Hasturkun
sumber
Saya pikir -pharus dihitung karena yang setara akan menambahLINE: while (<ARGV>){...}continue{die "-p destination: $!\n" unless print $_}
Brad Gilbert b2gills
Pada setiap server golf otomatis, ini akan dihitung sebagai 80 byte, karena memerlukan shebang #!perl -pplus baris baru.
primo