Kết hợp Kakuro


12

Kết hợp Kakuro

Vì tôi không thể làm số học tinh thần, tôi thường phải vật lộn với Câu đố Kakuro , đòi hỏi nạn nhân phải liên tục tìm ra các số khác nhau trong phạm vi từ 1 đến 9 (bao gồm) tổng hợp với một số khác trong phạm vi từ 1 đến 45 khi bạn biết cách Có nhiều số. Ví dụ: nếu bạn có thể muốn biết cách lấy 23 từ 3 số, câu trả lời duy nhất là 6 + 8 + 9. (Đây là ý tưởng tương tự như Killer Sudoku nếu bạn quen với điều đó).

Đôi khi bạn sẽ có thông tin khác, chẳng hạn như số 1 không thể có mặt, do đó để đạt được 8 chỉ trong 2 số, bạn chỉ có thể sử dụng 2 + 6 và 3 + 5 (bạn không thể sử dụng 4 + 4, vì chúng là không phân biệt). Ngoài ra, có thể là bạn đã tìm thấy số 3 trong giải pháp, và do đó, một số như 19 trong 3 số phải là 3 + 7 + 9.

Nhiệm vụ của bạn là viết một chương trình liệt kê tất cả các giải pháp có thể cho một vấn đề nhất định, theo một trật tự nghiêm ngặt, trong một bố cục nghiêm ngặt.

Đầu vào

Giải pháp của bạn có thể nhận các đầu vào dưới dạng một chuỗi ASCII duy nhất thông qua stdin, đối số dòng lệnh, đối số cho hàm, giá trị còn lại trên ngăn xếp hoặc bất kỳ điều gì điên rồ mà ngôn ngữ bí truyền yêu thích của bạn sử dụng. Chuỗi có dạng

number_to_achieve number_of_numbers_required list_of_rejected_numbers list_of_required_numbers

Hai đối số đầu tiên là các số nguyên không âm 0 không âm cơ bản điển hình trong các phạm vi từ 1 đến 45 và 1 đến 9 tương ứng (sử dụng dấu thập phân sẽ là đầu vào không hợp lệ), hai danh sách chỉ là các chữ số được xâu chuỗi lại với nhau mà không phân định không có thứ tự cụ thể nào mà không lặp lại hoặc '0' nếu chúng là danh sách trống. Không thể có chữ số chung giữa các danh sách (ngoại trừ 0). Các dấu phân cách là không gian đơn.

Đầu ra

Đầu ra của bạn phải bắt đầu bằng một dòng chứa số lượng giải pháp có thể. Chương trình của bạn phải in ra các giải pháp phân cách ngắt dòng được sắp xếp theo từng chữ số ngày càng có ý nghĩa, trong đó mỗi chữ số được đặt ở vị trí sẽ là nếu bạn liệt kê các số từ 1 đến 9. Các ví dụ dưới đây hy vọng sẽ làm cho điều này rõ ràng hơn.

Nếu một đầu vào không hợp lệ được cung cấp, tôi không quan tâm chương trình của bạn làm gì, mặc dù tôi muốn nó không phải là khu vực khởi động của tôi.

Ví dụ

Đối với ví dụ này đầu vào

19 3 0 0

Sản lượng dự kiến ​​sẽ là

5
 2     89
  3   7 9
   4 6  9
   4  78 
    56 8 

Lưu ý các khoảng trắng thay cho mỗi số "thiếu", những số này là bắt buộc; Tôi không bận tâm về những không gian không có số sau chúng (chẳng hạn như số 9 bị thiếu ở trên). Bạn có thể giả định rằng bất cứ điều gì bạn đang in sẽ sử dụng phông chữ đơn không gian. Cũng lưu ý thứ tự, theo đó các giải pháp có chữ số nhỏ nhất nhỏ hơn được liệt kê trước, và sau đó là các giải pháp có chữ số nhỏ nhất tiếp theo, v.v.

Một ví dụ khác, dựa trên điều đó

19 3 57 9

Sản lượng dự kiến ​​sẽ là

2
 2     89
   4 6  9

Lưu ý rằng mọi kết quả đều chứa 9 và không có kết quả nào chứa 5 hoặc 7.

Nếu không có giải pháp, ví dụ

20 2 0 0

Sau đó, bạn chỉ nên xuất một dòng duy nhất có 0 trên đó.

0

Tôi đã cố tình phân tích phần đầu vào của niềm vui của câu hỏi này. Đây là mã golf, có thể là giải pháp ngắn nhất giành chiến thắng.


2
+1 đặc biệt. cho "... Tôi muốn nó không bằng khu vực khởi động của tôi."
Michael Easter

Câu trả lời:


5

GolfScript, 88 ký tự

~[[]]10,:T{{1$+}+%}/\{\0+`-!}+,\{0`+\`&!}+,\{\,=}+,\{\{+}*=}+,.,n@{1T>''*T@-{`/' '*}/n}/

Một triển khai đơn giản trong GolfScript. Lấy đầu vào từ STDIN hoặc ngăn xếp.

Mã có thể được kiểm tra ở đây .

Mã với một số ý kiến:

### evaluate the input string
~                     

### build all possible combinations of 0...9
[[]]              # start with set of empty combination
10,:T             #
{                 # for 0..9
  {1$+}+%         #   copy each item of set and append current digit to this copy
}/                # end for

### only keep combination which the digits given as last argument (minus 0)
\{                # start of filter block
  \0+`            #   add zero to combination and make string out of it
  -!              #   subtract from last argument -> check argument contains any
                  #     excess characters
}+,               # end of filter block


### remove any combination which contains either 0 or any digit from 2nd last argument
\{                # start of filter block
  0`+             #   take argument and append 0
  \`              #   stringify combination
  &!              #   check if no characters are common
}+,               # end of filter block

### filter for correct length
\{                # start of filter block
  \,              #   calc length of combination
  =               #   check if equal to second argument
}+,               # end of filter block

### filter for correct sum
\{                # start of filter block
  \{+}*           #   sum all digits of combination
  =               #   compare with first argument
}+,               # end of filter block

### output
.,                # determine size of set
n                 # append newline
@{                # for each combination in set
  1T>''*          #   generate "123456789"
  T@-             #   generate anti-set of current combination  
  {`/' '*}/       #   replace (in the string) each digit within the 
                  #   anti-combination with a space characters
  n               #   append newline
}/                # end for

5

JavaScript (E6) 172 180 275 296

Là một hàm (có thể kiểm tra) với 1 đối số chuỗi và trả về đầu ra được yêu cầu. Để có trả về thay đổi đầu ra thực sự với alert (), cùng số byte, nhưng hãy cẩn thận, phông chữ cảnh báo không phải là đơn cách.

F=i=>{
  [t,d,f,m]=i.split(' ');
  for(l=0,r='',k=512;--k;!z&!h&!o&&(++l,r+=n))
    for(z=n='\n',h=d,o=t,b=i=1;i<=9;b+=b)
      z-=~(b&k?(--h,o-=i,n+=i,f):(n+=' ',m)).search(i++);
  return l+r
}

Kiểm tra trong bảng điều khiển FireFox hoặc FireBug

console.log(['19 3 0 0','19 3 57 9','19 3 57 4','20 2 0 0'].map(x=>'\n'+x+'\n' +F(x)).join('\n'))

Đầu ra thử nghiệm:

19 3 0 0
5
 2     89
  3   7 9
   4 6  9
   4  78 
    56 8 

19 3 57 9
2
 2     89
   4 6  9

19 3 57 4
1
   4 6  9

20 2 0 0
0

Ung dung

F=i=>{
  [target, digits, forbidden, mandatory]=i.split(' ')

  result = '', nsol=0
  for (mask = 0b1000000000; --mask > 0;)
  {
    cdigits = digits
    ctarget = target
    bit = 1
    numbers = ''
    for (digit = 9; digit > 0; bit += bit, digit--)
    {

      if (bit & mask)
      {
        if (forbidden.search(digit)>=0) break;
        cdigits--;
        ctarget -= digit;
        numbers = digit + numbers;
      }
      else
      {
        if (mandatory.search(digit)>=0) break;
        numbers = ' '+numbers;
      }
    }
    if (ctarget==0 && cdigits == 0)
    {
        result += '\n'+numbers
        nsol++
    }
  }
  return nsol + result
}

4

Toán học, 239 byte

(Tôi thừa nhận tôi đã bắt đầu làm việc này trong khi nó vẫn còn trong hộp cát.)

{t,n,a,b}=FromDigits/@StringSplit@i;Riffle[c=Cases[Union/@IntegerPartitions[t,n,Complement[r=Range@9,(d=IntegerDigits)@a]],k_/;(l=Length)@k==n&&(b==0||l[k⋂d@b]>0)];{(s=ToString)@l@c}~Join~((m=#;If[m~MemberQ~#,s@#," "]&/@r)&/@c),"\n"]<>""

Ung dung

{t, n, a, b} = FromDigits /@ StringSplit@i;
Riffle[
  c = Cases[
    Union /@ IntegerPartitions[
      t, n, Complement[r = Range@9, (d = IntegerDigits)@a
       ]
      ],
    k_ /; (l = Length)@k == 
       n && (b == 0 || l[k ⋂ d@b] > 0)
    ];
  {(s = ToString)@l@c}~
   Join~((m = #; If[m~MemberQ~#, s@#, " "] & /@ r) & /@ c),
  "\n"] <> ""

Nó hy vọng chuỗi đầu vào sẽ được lưu trữ trong i.

Nó khá đơn giản. Đầu tiên, phân tích cú pháp đầu vào. Sau đó, tôi sử dụng IntegerPartitionsđể tìm hiểu làm thế nào tôi có thể chia số đầu tiên thành các số được phép. Sau đó, tôi lọc ra tất cả các phân vùng sử dụng trùng lặp hoặc không chứa các số bắt buộc. Và sau đó với mỗi giải pháp, tôi tạo một danh sách từ 1đến 9và chuyển đổi các số hiện tại thành biểu diễn chuỗi của chúng và các số khác thành khoảng trắng. Và sau đó tôi nối tất cả mọi thứ.


1

Groovy - 494 ký tự

Câu trả lời lớn, không mệt mỏi, nhưng nó sử dụng Google Guava để tạo ra "bộ năng lượng".

Chơi gôn

@Grab(group='com.google.guava', module='guava', version='17.0')
m=(args.join(" ")=~/(\d+) (\d+) (\d+) (\d+)/)[0]
i={it as int}
n=i(m[1])
r=i(m[2])
j=[]
m[3].each{if(i(it))j<<i(it)}
q=[]
m[4].each{if(i(it))q<<i(it)}
d=1..9 as Set<Integer>
t=[]
com.google.common.collect.Sets.powerSet(d).each{x->
if(x.sum()==n&&x.size()==r&&x.disjoint(j)&&x.containsAll(q)) {
s="";for(i in 0..8){if(x.contains(i+1)){s+=(i+1) as String}else{s+=" "}};t<<s}
}
p={println it}
p t.size()
t.sort().reverse().each{p it}

Chạy mẫu:

$ groovy K.groovy 19 3 0 0 
5
 2     89
  3   7 9
   4 6  9
   4  78 
    56 8 
$ groovy K.groovy 19 3 5 0 
4
 2     89
  3   7 9
   4 6  9
   4  78 
$ groovy K.groovy 19 3 5 9
3
 2     89
  3   7 9
   4 6  9
$ groovy K.groovy 20 2 0 0 
0

Ung dung:

@Grab(group='com.google.guava', module='guava', version='17.0')

m=(args.join(" ")=~/(\d+) (\d+) (\d+) (\d+)/)[0]
i={it as int}
n=i(m[1])
r=i(m[2])

j=[]
m[3].each{if(i(it))j<<i(it)}
q=[]
m[4].each{if(i(it))q<<i(it)}

d=1..9 as Set<Integer>
t=[]

com.google.common.collect.Sets.powerSet(d).each{ x ->
    if(x.sum()==n && x.size()==r && x.disjoint(j) && x.containsAll(q)) {
        s=""
        for(i in 0..8) {
            if(x.contains(i+1)){s+=(i+1) as String}else{s+=" "}
        }
        t<<s
    }
}

p={println it}
p t.size()
t.sort().reverse().each{p it}
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.