Kết hợp tối đa 10 trong một mảng


8

Thử thách

Đưa ra một mảng gồm một số có một chữ số, hãy tìm ra nếu bất kỳ 2 trong số chúng thêm tối đa 10 và in chúng ra

Thí dụ

Đầu vào

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

Điều này trở lại ((4,6),(5,5),(3,7))

Đầu vào

(1,2,3,4,5)

Điều này trở lại (). vì chỉ có một 5

Đầu vào

(5,5,5,5,5)

Điều này trả về ((5,5),(5,5))vì có số lẻ là 5s và mỗi 5 chỉ có thể được sử dụng một lần

Quy tắc

Đây là các quy tắc!

  • Giả sử đầu vào sẽ chỉ là một mảng chưa được sắp xếp của các số nguyên một chữ số dương
  • Mỗi số sẽ được ghép nối chỉ một lần, có nghĩa là nếu có ba 5s thì nó chỉ tạo thành 1 cặp (5,5). Nếu có (3,3,7), nó sẽ chỉ tạo thành 1 cặp (3,7)
  • Đối với đầu vào: Bạn có thể sử dụng bất kỳ loại dấu ngoặc đơn (hoặc thiếu) miễn là người đọc có thể nói rằng đầu vào là một mảng số duy nhất.
  • Đối với đầu ra: Nó phải trông giống như một mảng các cặp. Trường hợp mảng có dạng giống như đầu vào của bạn (Nếu bạn không sử dụng bất kỳ parenhes nào trong đầu vào của mình, bạn phải sử dụng một số loại ký hiệu để bất kỳ độc giả nào cũng có thể biết chúng là một cặp trong một mảng)

Các trường hợp thử nghiệm

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

Chúc may mắn!

Các shortercâu trả lời là, thì càng tốt!

Chỉnh sửa 1: cập nhật các quy tắc và Testcase từ các bình luận

Chỉnh sửa 2: cập nhật quy tắc để xác định định dạng của đầu vào.

Chỉnh sửa 3: cập nhật quy tắc để xác định định dạng đầu ra. cố gắng để có sức chứa càng tốt.


2
Không nên có 10 kết hợp khác nhau (5,5)cho trường hợp thử nghiệm cuối cùng?
Gareth

@Gareth Có vẻ như các giá trị được sử dụng hết khi chúng tạo thành cặp
Matt

Bạn có thể gửi thêm một vài trường hợp thử nghiệm? Có lẽ một cái gì đó như(1,2,3,3,4,5,6,7)
Matt

@Matt chỉnh sửa. Cảm ơn phản hồi
user1655072

Là đầu vào phải bao gồm các dấu ngoặc đơn, hoặc nó có thể được nhập vào như 1,2,3,4,5,5,6,7?
jdstankosky

Câu trả lời:


7

GolfScript, 45 42 37 ký tự

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

Cách tiếp cận mới cũng lấy mảng với một mục duy nhất làm đầu vào. Hơn nữa, nó là một số ký tự ngắn hơn.

Phiên bản trước:

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

Thuật toán được sử dụng trong mã này được mô tả như sau:

  • Sắp xếp mảng.
  • Lấy tổng của mục đầu tiên và mục cuối cùng.
    • Nếu tổng bằng 10, hãy in cả hai số và xóa chúng khỏi mảng.
    • Nếu tổng lớn hơn 10, loại bỏ số lớn hơn.
    • Nếu tổng nhỏ hơn 10, loại bỏ số nhỏ hơn.
  • Lặp lại cho đến khi mảng chỉ chứa một chữ số hoặc thậm chí trống.

Mã này mong đợi một mảng có ít nhất hai chữ số trên STDIN.

Ví dụ (xem trực tuyến ):

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

>[5 5 5 5 5]
[5 5]
[5 5]

9

Con trăn 2.7 (70)

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

Testcase:

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

Thêm một byte cho dấu ngoặc đơn đẹp.


Tôi nghĩ rằng tôi đã sao chép phương thức này trong PHP, nhưng nó chỉ hoạt động đôi khi và không hoạt động với tất cả các cặp. Bất cứ ý tưởng tại sao? <?$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 ký tự

Chơi golf trong JS có phần khó khăn, nhưng tôi chỉ muốn có một cú đánh về vấn đề này, vì vậy đây là mã:

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)

Đầu vào: vd [1,2,3,3,4,5,6,7]. Đầu ra, ví dụ như [[4,6],[3,7]]bàn điều khiển.

105-> 98: Sử dụng thuật toán tuyệt vời của Daniel để viết lại hoàn toàn mã! Xem câu trả lời của anh ấy cho một thuật toán có thể đọc được. Hoàn toàn làm rối tung mọi thứ để trở lại 105 ký tự.

112-> 105: Đã khởi tạo ivề 0, đầu ra được sử dụng của o.pushset k( k=a[i]=a[j]=-o.push...) và đầu ra được ghi vào bảng điều khiển thay vì cảnh báo để loại bỏ "["++"]"vì giao diện điều khiển đã xuất hiện độc đáo.

123-> 112: Bây giờ đã loại bỏ dấu ngoặc ngoài trong đầu ra, vì golfscript có thể :) Cuối cùng cũng áp dụng đề xuất loại bỏ |=0.

121-> 123: Đã thay đổi o+="("+p+","+k+"),"thành o.push("("+[p,k]+")")(thêm 2 ký tự :() và tạo omột mảng thay vì một chuỗi ( o=""-> o=[]). Bây giờ đầu ra không còn sai nữa (như ((5,5),(5,5),)).

141-> 121: Từ giờ trở đi, giả sử rằng câu hỏi có nghĩa là chúng ta có thể nhận đầu vào ở định dạng mảng của ngôn ngữ, trong trường hợp của JS là [a,b,c,...]và được tạo o, đầu ra "tích lũy" một chuỗi thay vì một mảng ( o.push(...),-> o+=...,).

153-> 141: Đặt lại các mục mảng thay vì xóa chúng sau khi sử dụng.

181-> 153: Các thay đổi được áp dụng cho u=[], các vòng lặp được sắp xếp lại, a[i]& a[j]-> các lọ tạm thời, được chuyển đổi nếu logic và chuyển đổi logic int thành a[i]|=0.

183-> 181: Thay thế i<=0bằng i+1và tương tự cho j.

188-> 183: Đặt o=[]bên trong prompt()( ;) và thay thế for(j=i;bằng for(j=i-1;( i==j&&).

(Cảm ơn mellamokb, Paul Walls và ryan!)


1
Bạn có thể thay thế i>=0với i+1j>=0với j+1tiết kiệm 2 chars.
mellamokb

1
Tôi đã áp dụng thay đổi cho một mảng trường bit ( u=[]thay vì x), sắp xếp lại các vòng lặp để đi từ 0 trở lên, được gán a[i]a[j]biến tạm thời để lưu các tham chiếu lặp lại, chuyển một số khởi tạo biến thành các câu lệnh khác, chuyển đổi iflogic thành logic chuỗi ||và chuyển đổi phân tích cú pháp int để gọn gàng hơn a[i]|=0, để có được tổng số tiền tiết kiệm là 30 ký tự :). Đây là khai thác thử nghiệm của tôi chứng minh tính chính xác của giải pháp: jsfiddle.net/GKUDb/8 và giải pháp làm việc golf 151 ký tự: jsfiddle.net/DVtW2 .
mellamokb

1
Array.toString () cũng sẽ giúp bạn tiết kiệm một vài ký tự (nghĩa là o+="("+[p,k]+")").
Paul Walls

1
Nếu bạn ổn với đầu ra như của golfscript, thì bạn có thể làm điều này : 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), đưa nó xuống 115
Ryan

1
Bạn đã quên đề xuất của tôi để khởi tạo i thành 0. Bạn có thể gấp a=eval(prompt(o=[])),i=-1lại a=eval(prompt(i=o=[]))mà không mất độ trung thực, để tiết kiệm thêm 3 ký tự.
mellamokb

3

J, 54 53 50 46 45 44 ký tự

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

Sử dụng:

   (>:,.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

Thuật toán về cơ bản là:

  • đếm số thể hiện của mỗi số +/|:(1+i.9)=/
  • ghép số đếm của mỗi cặp sẽ cộng thành 10 (<.|.)(vì vậy 1 và 9, 2 và 8, v.v.)
  • lấy tối thiểu số đếm đó (vì vậy nếu bạn có ba số 9 nhưng chỉ có 1, bạn sẽ chỉ có một 1 9cặp) và bỏ mọi thứ sau năm cặp đầu tiên
  • 5s là trường hợp đặc biệt nên chia cho 2 ( <.4({.,-:@{::)thực hiện cả hai bước trước)
  • lấy năm mục đầu tiên của danh sách và xuất số và 10 -số(>:,.9&-)I.

3

Con trăn (142)

Đầu vào phải được đưa ra với dấu ngoặc vuông thay vì dấu ngoặc tròn. 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()

Thuật toán:

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

Nếu đầu ra không đúng định dạng nghiêm trọng được cho phép (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)))

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

Kiểm tra:

./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))

Ghi chú thực hiện:

  • ban đầu a = 2 (chương trình có hai đối số), được đặt thành 6 (printf in 6 ký tự) sau khi trận đấu xảy ra
  • 106 = '0' + '0' + 10, tức là sử dụng tổng số mã ascii
  • 38 + a, là 44/40, nghĩa là '(' hoặc ','
  • Bằng cách đặt các ký tự chuỗi thành 6, nó đảm bảo chúng sẽ không thêm vào 106 trên các đường chuyền khác
  • "()" + a / 6, là "()" hoặc ")"

3

Perl 52

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

Bằng chứng :

> 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

Và có một mã nhận xét vô căn cứ:

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

}

Có thể các giải thích trông giống như tiếng Pháp pidgin (Tôi không phải là một nhà văn tiếng Anh bản địa), vì vậy nếu ai đó muốn chỉnh sửa nó và làm cho nó dễ hiểu hơn, xin vui lòng làm như vậy.


Nghiêm túc mà nói, thậm chí không có một điểm nào cho điều này, với những lời giải thích và tất cả? ... :(
Orabîg

3

Javascript - 131 129 125 ký tự

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)

Tôi giả sử, thứ tự và trong các mảng kết quả lồng nhau là không bắt buộc :)

Các trường hợp kiểm tra đánh giá:

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

Chỉnh sửa : Như mô tả vấn đề nói 'Mảng', chúng ta đang nói về ký hiệu cụ thể ngôn ngữ của một mảng, phải không?


2

Toán học 70

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

Sử dụng

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


2

PostScript (46)

Điều này sử dụng mã thông báo nhị phân được mã hóa bằng tay, do đó, đây là một 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

Tôi đã tải lên tệp nhị phân nếu bạn muốn dùng thử.

Điều này hy vọng các con số sẽ được xếp chồng lên nhau. Chúng có thể được thêm vào mã hoặc được cung cấp trên dòng lệnh, ví dụ như khi sử dụng Ghostscript như vậy:

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

Nếu bạn nhấn mạnh vào cú pháp mảng cho đầu vào, thì điều này đòi hỏi thêm hai mã thông báo ( aload pop) ngay từ đầu. Trong mã thông báo nhị phân, đây là bốn byte nữa.

Un-golfed và nhận xét:

{ % 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

2

Con trăn 84

Yêu cầu đầu vào trong ngoặc thay vì dấu ngoặc đơn.

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

Đối với câu trả lời đại khái giống như chơi golf tốt hơn xem câu trả lời của Daniel .


2

PHP 150 149 148 146 142 -> 140

Sử dụng với 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;}}

Đầu vào: 1,2,3,4,5,5,6,7

Đầu ra: (3,7)(4,6)(5,5)

Chưa chơi gôn:

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

?>

1

SED, 112 ký tự

Có lẽ đơn giản hơn các giải pháp khác

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

1

Perl, 72 với -pcờ

perl -p -e 's/^/@/;1while s/(@.*)(.)(.*)((??{10-$2}))/($2,$4)$1$3/;s/(.*)@.*/($1)/'

Tôi nghĩ rằng -pnên được tính vì tương đương sẽ thêmLINE: while (<ARGV>){...}continue{die "-p destination: $!\n" unless print $_}
Brad Gilbert b2gills

Trên mỗi máy chủ golf tự động, điều này sẽ được tính là 80 byte, vì nó yêu cầu shebang #!perl -pcộng với dòng mới.
Primo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.