Какуро Комбинации

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 через стандартный ввод данных, аргумент командной строки, аргумент функции, значение, оставленное в стеке, или любое другое безумие, которое использует ваш любимый эзотерический язык. Строка в форме

number_to_achieve number_of_numbers_required list_of_rejected_numbers list_of_required_numbers

Первые 2 аргумента являются типичными неотрицательными ненулевыми целыми числами из 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

Я специально сделал разбор входной части забавой этого вопроса. Это код-гольф, пусть победит самое короткое решение.

VisualMelon
источник
2
+1 особенно за "... я бы предпочел, чтобы это не обнуляло мой загрузочный сектор".
Майкл Пасха

Ответы:

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 строковым аргументом и возвращением запрошенного вывода. Чтобы иметь реальное выходное изменение, возвращайте с alert () с тем же количеством байтов, но будьте осторожны, шрифт оповещения не моноширинный.

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

Ungolfed

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
}
edc65
источник
4

Mathematica, 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"]<>""

Ungolfed

{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 для генерации "набора мощности".

Golfed:

@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

Ungolfed:

@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}
Майкл Пасха
источник