Какуро Комбінації


12

Какуро Комбінації

Оскільки я не можу займатися розумовою арифметикою, я часто борюся з головоломкою Какуро , яка вимагає від жертви багаторазово розробити, які чіткі числа в діапазоні від 1 до 9 (включно) складають до іншого числа в діапазоні від 1 до 45, коли ви знаєте, як багато номерів є. Наприклад, якщо ви, можливо, хочете знати, як отримати 23 з 3-х чисел, єдина відповідь - 6 + 8 + 9. (Це та сама ідея, що і Killer Sudoku, якщо ви знайомі з цим).

Іноді у вас буде інша інформація, наприклад, що число 1 не може бути присутнім, таким чином, щоб досягти 8 лише в 2 числах, ви можете використовувати лише 2 + 6 і 3 + 5 (ви не можете використовувати 4 + 4, оскільки вони є не виразно). Як варіант, можливо, ви вже знайшли 3 у рішенні, і тому щось на зразок 19 у 3 числах має бути 3 + 7 + 9.

Ваше завдання - написати програму, в якій перераховані всі можливі рішення даної проблеми, у чіткому порядку, із суворим макетом.

Вхідні дані

Ваше рішення може отримувати вхідні дані як окремий рядок ASCII через stdin, аргумент командного рядка, аргумент функції, значення, залишене у стеку, або будь-яке безумство вашої улюбленої езотеричної мови. Рядок у формі

number_to_achieve number_of_numbers_required list_of_rejected_numbers list_of_required_numbers

Перші два аргументи є типовими базовими-10 невід'ємними ненульовими цілими числами у межах від 1 до 45 та від 1 до 9 відповідно (з використанням десяткової крапки буде недійсним введенням); два списки - це просто цифри, накреслені разом із відмежуванням у немає жодного конкретного замовлення без повторення або "0", якщо вони порожні списки. Не може бути загальних цифр між списками (крім 0). Розмежувачі - це одинарні пробіли.

Вихідні дані

Ваш вихід повинен починатися з рядка, який містить кількість можливих рішень. Ваша програма повинна роздрукувати розмежовані рядки розв’язків, відсортовані за кожною все більш значущою цифрою, де кожна цифра розміщується на такому місці, як це було б, якби ви перерахували числа від 1 до 9. Наведені нижче приклади, сподіваємось, це зрозуміють.

Якщо надано недійсний вхід, мені байдуже, що робить ваша програма, хоч я вважаю за краще, щоб це не занурило мій завантажувальний сектор.

Приклади

Для цього прикладу введення

19 3 0 0

Очікуваний результат буде

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

Зверніть увагу на пробіли замість кожного "пропущеного" номера, вони потрібні; Мене не турбує пробіли, які не мають номера після них (наприклад, про відсутніх 9-ти вище). Ви можете припустити, що все, що ви друкуєте, буде використовувати шрифт монопробілу. Зверніть увагу також на впорядкування, в якому спочатку перераховуються рішення з меншою найменшою цифрою, а потім ті, що мають найменшу наступну найменшу цифру тощо.

Ще один приклад, виходячи з цього вище

19 3 57 9

Очікуваний результат буде

2
 2     89
   4 6  9

Зауважте, що кожен результат містить 9, а жоден результат не містить 5 або 7.

Якщо немає рішень, наприклад

20 2 0 0

Тоді вам слід просто вивести один рядок з 0 на ньому.

0

Я навмисно зробив розбір вхідної частини із задоволенням цього питання. Це код-гольф, можливо найкоротше рішення виграє.


2
+1 esp. для "... Я вважаю за краще, щоб це не знецінило мій завантажувальний сектор".
Михайло Пасха

Відповіді:


5

GolfScript, 88 символів

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

Безпосередня реалізація в GolfScript. Бере вхід зі STDIN або стека.

Код можна перевірити тут .

Код з коментарями:

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

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

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
}

Тест в консолі FireFox або 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'))

Тестовий вихід:

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

Безумовно

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

Математика, 239 байт

(Зізнаюся, я почав працювати над цим, поки він ще був у пісочниці.)

{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"]<>""

Безумовно

{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"] <> ""

Він очікує, що вхідний рядок буде збережено в i.

Це досить просто. По-перше, синтаксичний аналіз. Потім я використовую, IntegerPartitionsщоб зрозуміти, як я можу розділити перше число на дозволені числа. Потім я фільтрую всі розділи, які використовують дублікати або не містять необхідних номерів. А потім для кожного рішення я створюю список від 1до 9і перетворюю теперішні числа в їх рядкове представлення, а інші - в пробіли. А потім я все об'єдную.


1

Groovy - 494 символів

Велика, не натхненна відповідь, але вона використовує Google Guava для створення "набору потужності".

Гольф:

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

Проби:

$ 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

Безголівки:

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