チェーン上の数字


15

いくつかの正の整数は、チェーン分割可能性と呼ばれるプロパティを持つことが示されます数値をnでチェーン分割できるよう  にするには、次の3つの要件を満たす必要があります。

  1. 各桁は、  それに続くn桁で形成される数値を分割します。

    例えば、番号7143が2~7ため分割14と1除算43によってチェーン割り切れるそれはない 7 143を分割しないので鎖割り切れる3による。

  2. 可分性のために考慮される各サブシーケンスには、先行ゼロがあってはなりません。

    たとえば、08には先行ゼロがあるため、14208の数値は2でチェーン分割できません。ただし、208には先行ゼロがないため、3でチェーン分割できます。

  3. 番号のすべての数字は一意である必要があります。

たとえば、番号14280は2、3、4でチェーン分割可能です。チェーンの分割可能性に関する私の説明が不明な場合は、コメントで質問してください。

入力

プログラムへの入力は、単一の整数n、スペース、アンダースコアで置き換えられた特定の数字を持つ数字で構成されます。たとえば、次の入力が可能です。

3 6__2__4508

nは1より大きくなります。数値が完全にアンダースコアになることはありません。最初の数字がアンダースコアでないことは保証されません。最初の桁は0になることはありませんNより大きい又は番号の桁数に等しくなることはありません。

出力

結果の数値がnでチェーンで割り切れるように、数字を整数に置き換えて数値を出力します。チェーン分割可能な数を完成する複数の方法が存在する場合、どれでも出力として使用できます。それを完成できる数字がない場合は、を出力しますno answer。たとえば、入力例の出力は次のようになります。

6132794508

これはコードゴルフなので、最短のコードが勝ちます。


私はそのn数の桁数以上である場合、数は割り切れると仮定しますか?
ジョンドヴォルザーク14

@Jan Dvorak nが入力の桁数以上になることはありません。常に小さくなります。それを反映するように編集します。
アブサン14

完全なプログラムを書く必要がありますか、それとも機能で十分ですか?
ジョン・ドヴォルザーク

@Martinはい。文字制限パディング。
アブサン14

@Jan Dvorak完全なプログラム。
アブサン14

回答:


5

Bash + coreutils、197バイト

for i in $(eval printf '%s\\n' ${2//_/{0..9\}}|grep -vP '(\d).*\1');{
for((f=d=0;d<${#i}-$1;d++));{
((${i:d+1:1}==0||10#${i:d+1:$1}%${i:d:1}))&&f=
}
[ $f ]&&echo $i&&((c++))
}
((c))||echo no answer

出力:

$ ./chain.sh 3 714_
7140
$ ./chain.sh 2 7141
no answer
$ ./chain.sh 2 14208
no answer
$ ./chain.sh 3 14208
14208
$ ./chain.sh 2 1_208
no answer
$ ./chain.sh 3 1_208
14208
$ ./chain.sh 2 6__2__4508
no answer
$ ./chain.sh 3 6__2__4508
6132794508
$

説明

  • パラメーターの展開により${2//_/{0..9\}}、すべての下線がに置き換えられ{0..9}ます。
  • 結果の文字列はeval、これらすべてのブレース式を展開するために編集されます。
  • grep任意の繰り返しの数字があるすべての可能性を雑草。
  • 次に、残りの各番号が、条件1と2の桁ごとにチェックされます。

2

パイソン-239 267

from itertools import*
T=raw_input()
n=int(T[0])
N=len(T)-2
J=''.join
for i in permutations('0123456789',N):
 if all([S in[I,'_']for S,I in zip(T[2:],i)])*all([i[j]>'0'<i[j+1]and int(J(i[j+1:j+n+1]))%int(i[j])<1for j in range(N-n)]):print J(i);exit()
print'no answer'

遅いが、短い。考えられるすべてのN桁の順列を指定されたパターンと単純に比較し、すべての要件を確認します。7桁または8桁でのみテストしました。9または10でも機能するはずですが、かなり時間がかかります。

編集:欠落しているデフォルト出力「no answer」を追加しました。


2

Mathematica Ruby、349 224 229バイト

n=$*[0].to_i
r='no answer'
(?0..?9).to_a.permutation($*[1].count'_'){|q|s=$*[1]
q.map{|d|s=s.sub'_',d}
c=s.chars
(t=1
c.each_cons(n+1){|c|e=c.shift.to_i
(t=!t
break)if e<1||c[0]==?0||c.join.to_i%e>0}
(r=s)if t)if c==c.uniq}
$><<r

これは非常に単純な実装です。アンダースコアの数をカウントし、その長さのすべての数字順列のリストを作成して、可能なすべての組み合わせをブルートフォースします。これは、多数のアンダースコアに対して恐ろしく機能しますが、これはコードゴルフであり、最速のコードではありません。:)

編集:これをMathematicaから移植しました。元のバージョンの編集履歴を参照してください。

編集:主要なアンダースコアのケースを修正しました。


タプルの代わりに順列を使用するべきではありませんか(文字カウントを見落とす)?
DavidC 14

@DavidCarraherなぜですか?そこには多くの組み合わせがありませんよね?
マーティンエンダー

番号の各桁は一意である必要があります。 Tuplesその制約を課しません。 Permutations入力セットに繰り返される数字がない場合。また、まだ使用されていない数字のみを置換できます。(ただし、これでもコードが長くなる可能性があります。)
DavidC 14

@DavidCarraherああ、私は一意性の要件を見落としていました。その場合、それを内側のループに追加する必要があります。その場合は、Tuples短いため、そのまま使用することもできます。
マーティンエンダー14

@DavidCarraherが修正されました。
マーティンエンダー14

1

Java、421

class C{static int n;public static void main(String[]a){n=new Short(a[0]);f(a[1]);System.out.print("no answer");}static void f(String s){if(s.contains("_"))for(int i=0;i<=9;i++)f(s.replaceFirst("_",i+""));else{for(int i=1;i<s.length()-n+1;){String t=s.substring(i,i+n);if(t.charAt(0)<49||new Long(t)%new Long(s.substring(i-1,i++))>0||s.chars().distinct().count()<s.length())return;}System.out.print(s);System.exit(0);}}}

説明の少ないゴルフ:

class C {

    static int n;

    public static void main(String[] a) {
        n = new Short(a[0]);
        f(a[1]);
        System.out.print("no answer");
    }

    /**
     * This method is called recursively, each time with
     * another underscore replaced by a digit, for all possible digits.
     * If there is a solution, the method prints it and exits the program.
     * Otherwise, it returns.
     */
    static void f(String s) {
        if (s.contains("_")) {
            for (int i = 0; i <= 9; i++) {
                f(s.replaceFirst("_", i + ""));
            }
        } else {
            for (int i = 1; i < s.length() - n + 1;) {
                String t = s.substring(i, i + n);       // on each substring...
                if (                                    // test for the three rules
                    t.charAt(0) < 49 ||
                    new Long(t) % new Long(s.substring(i - 1, i++)) > 0 ||
                    s.chars().distinct().count() < s.length()
                ) {
                    return;            // a rule was broken
                }
            }
            System.out.print(s);       // if we made it this far, it's a success!
            System.exit(0);
        }
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.