カクロの組み合わせ


12

カクロの組み合わせ

暗算はできないので、カクロパズルに苦労することがよくあります。カクロパズルでは、被害者が、1〜9の範囲内の異なる数字の合計を1〜45の範囲の別の数字と繰り返し計算する必要があります。多くの数字があります。たとえば、3つの数字から23を取得する方法を知りたい場合、答えは6 + 8 + 9だけです(これに精通している場合、これはKiller Sudokuと同じ考えです)。

場合によっては、数字1 存在できないなど、他の情報があるため、2つの数字だけで8を達成するには、2 + 6と3 + 5しか使用できません(4 + 4は使用できないため、4 + 4は使用できません)明確ではありません)。あるいは、ソリューションで既に3を見つけている可能性があるため、3の数字の19のようなものは3 + 7 + 9でなければなりません。

あなたの仕事は、与えられた問題に対するすべての可能な解決策を厳密な順序で、厳密なレイアウトでリストするプログラムを書くことです。

入力

ソリューションは、入力を単一のASCII文字列として、stdin、コマンドライン引数、関数の引数、スタックに残された値、またはお気に入りの難解な言語が採用している狂気のいずれかを介して受け取ることができます。文字列は次の形式です

number_to_achieve number_of_numbers_required list_of_rejected_numbers list_of_required_numbers

最初の2つの引数は、それぞれ1から45および1から9の範囲の典型的な10進数の非負の非ゼロ整数です(小数点を使用すると無効な入力になります)。2つのリストは、繰り返しのない特定の順序、または空のリストの場合は「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を1行だけ出力する必要があります。

0

この質問の楽しみの入力部分の解析を意図的に行いました。これはコードゴルフであり、最短のソリューションが勝つかもしれません。


2
+1特に 「...ブートセクタをゼロにしたくない」
マイケルイースター14

回答:


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

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

非ゴルフ

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

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

非ゴルフ

{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、最初の数字を許可された数字に分割する方法を見つけ出します。次に、重複を使用するか、必要な数が含まれていないすべてのパーティションを除外します。そして、ソリューションごとに1to からリストを作成し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}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.