ตัวเลขในลูกโซ่


15

จำนวนเต็มบวกบางตัวสามารถแสดงได้ว่ามีคุณสมบัติที่เรียกว่าการแบ่งแยกแบบลูกโซ่ เพื่อให้ตัวเลขหารด้วยห่วงโซ่โดย  nจะต้องตอบสนองความต้องการสามประการ:

  1. แต่ละหลักหารตัวเลขที่เกิดขึ้นจาก  ตัวเลขnที่ตามมา

    ตัวอย่างเช่นจำนวน 7143 เป็นห่วงโซ่หารด้วย 2 เพราะ 7 หาร 14 และ 1 หาร 43 มันไม่ใช่ห่วงโซ่หารด้วย 3 เพราะ 7 ไม่หาร 143

  2. แต่ละองค์ประกอบที่คำนึงถึงการหารต้องไม่มีเลขศูนย์นำหน้า

    ตัวอย่างเช่นหมายเลข 14208 นั้นไม่สามารถแบ่งย่อยได้ด้วย 2 เพราะ 08 เป็นศูนย์นำหน้า อย่างไรก็ตามเป็นห่วงโซ่ที่หารด้วย 3 ได้เพราะ 208 ไม่มีศูนย์นำหน้า

  3. ตัวเลขทั้งหมดในหมายเลขต้องไม่ซ้ำกัน

ตัวอย่างเช่นจำนวน 14280 เป็นห่วงโซ่หารด้วย 2, 3 และ 4 หากคำอธิบายของฉันเกี่ยวกับการแบ่งแยกห่วงโซ่ไม่ชัดเจนโปรดถามคำถามในความคิดเห็น

อินพุต

อินพุตไปยังโปรแกรมประกอบด้วยเลขจำนวนเต็มเดียวnตามด้วยช่องว่างจากนั้นตัวเลขที่มีตัวเลขที่แน่นอนแทนที่ด้วยเครื่องหมายขีดล่าง ตัวอย่างเช่นต่อไปนี้เป็นอินพุตที่เป็นไปได้:

3 6__2__4508

nจะมากกว่า 1 ตัวเลขจะไม่มีขีดล่างทั้งหมด คุณไม่สามารถรับประกันได้ว่าตัวเลขตัวแรกจะไม่ใช่ขีดล่าง ตัวเลขตัวแรกจะไม่เป็น 0. nจะไม่มากกว่าหรือเท่ากับจำนวนหลักในจำนวนนั้น

เอาท์พุต

การส่งออกจำนวนที่มีตัวเลขแทนที่ด้วยจำนวนเต็มเช่นว่าจำนวนที่เกิดเป็นห่วงโซ่หารด้วยn หากมีมากกว่าหนึ่งวิธีในการเติมจำนวนลูกโซ่ที่หารได้ให้คงอยู่อาจใช้วิธีใดก็ได้เป็นผลลัพธ์ no answerหากมีตัวเลขที่ไม่สามารถดำเนินการได้ผลผลิต ตัวอย่างเช่นผลลัพธ์ของอินพุตตัวอย่างอาจเป็น:

6132794508

นี่คือรหัสกอล์ฟดังนั้นรหัสที่สั้นที่สุดชนะ


ฉันคิดว่าถ้าnมากกว่าหรือเท่ากับจำนวนหลักในจำนวนนั้นจำนวนนั้นจะหารด้วยลูกโซ่?
John Dvorak

@Jan Dvorak n จะไม่เท่ากับหรือมากกว่าจำนวนหลักในอินพุต มันจะเล็กกว่าเสมอ ฉันจะแก้ไขเพื่อสะท้อนสิ่งนั้น
absinthe

เราจำเป็นต้องเขียนโปรแกรมเต็มหรือฟังก์ชั่นเพียงพอหรือไม่
John Dvorak

@ มาร์ตินใช่ การ จำกัด จำนวนอักขระ
absinthe

@Jan Dvorak โปรแกรมเต็มรูปแบบ
absinthe

คำตอบ:


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

Python - 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 ดูประวัติการแก้ไขสำหรับเวอร์ชั่นดั้งเดิม

แก้ไข:แก้ไขกรณีขีดเส้นใต้นำหน้า


ไม่ควรใช้การเรียงสับเปลี่ยนแทน Tuples (มองเห็นจำนวนตัวอักษร)
DavidC

@DavidCarraher ทำไม ฉันจะคิดถึงชุดค่าผสมจำนวนมากที่นั่นใช่มั้ย
Martin Ender

ตัวเลขแต่ละตัวต้องไม่ซ้ำกัน Tuplesไม่ได้กำหนดข้อ จำกัด ดังกล่าว Permutationsจะให้มีไม่มีตัวเลขซ้ำในชุดอินพุต และคุณสามารถเปลี่ยนเฉพาะตัวเลขที่ยังไม่ได้ใช้ (แม้ว่าอีกครั้งสิ่งนี้อาจทำให้รหัสของคุณยาวขึ้น)
DavidC

@ DavidCarraher Ohhh ฉันมองข้ามความต้องการเฉพาะ ฉันต้องเพิ่มมันเข้าไปในลูปด้านในซึ่งในกรณีนี้ฉันอาจติดด้วยTuplesเพราะมันสั้นกว่า
Martin Ender

@DavidCarraher แก้ไขแล้ว
Martin Ender

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);}}}

golfed น้อยกับคำอธิบาย:

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.