Bagilah dan bagilah dan taklukkan


22

Kadang-kadang, ketika saya iseng mencoba faktor apa pun nomor muncul di depan saya in, setelah beberapa saat saya menyadari itu lebih mudah daripada yang saya pikirkan. Ambil 2156contoh: akhirnya terjadi kepada saya bahwa baik 21dan 56merupakan kelipatan dari 7, dan begitu tentu 2156 = 21 x 100 + 56juga merupakan kelipatan 7.

Tugas Anda adalah menulis beberapa kode yang mengidentifikasi angka-angka yang lebih mudah difaktorkan karena kebetulan seperti ini.

Lebih tepatnya:

Tulis program atau fungsi yang mengambil bilangan bulat positif nsebagai input, dan mengembalikan nilai kebenaran jika ada pembagi d(lebih besar dari 1) sehingga ndapat dipotong menjadi dua untuk menghasilkan dua bilangan bulat positif, masing-masing merupakan kelipatan dari d; mengembalikan nilai yang salah jika tidak.

  • "Cincang dua" berarti apa yang Anda pikirkan: representasi basis-10 yang biasa ndipartisi pada beberapa titik menjadi setengah bagian depan dan setengah belakang untuk menghasilkan dua bilangan bulat basis-10 lainnya. Tidak apa-apa jika bilangan bulat kedua memiliki nol di depan (tetapi perhatikan bahwa itu harus bilangan bulat positif, jadi pisahkan 1230menjadi 123dan 0tidak valid).
  • Nilai kebenaran dan kepalsuan dapat bergantung pada input. Misalnya, jika ada bilangan bulat bukan kebenaran dalam bahasa pilihan Anda, maka Anda dipersilakan untuk mengembalikan pembagi datau salah satu "bagian" dari n(atau nitu sendiri dalam hal ini).
  • Misalnya, setiap angka genap dengan setidaknya dua digit di set {2, 4, 6, 8}akan menghasilkan nilai yang benar: hanya membaginya setelah angka genap pertama. Sebagai contoh, setiap bilangan prima nakan menghasilkan nilai palsu, seperti halnya bilangan satu digit.
  • Perhatikan bahwa cukup untuk mempertimbangkan pembagi utama d.
  • Anda dapat berasumsi bahwa input tersebut valid (yaitu, bilangan bulat positif).

Ini adalah , jadi kode terpendek dalam byte menang. Tetapi solusi dalam semua bahasa dipersilahkan, sehingga kami dapat mengusahakan kode terpendek di setiap bahasa, bukan hanya kode terpendek secara keseluruhan.

Uji kasus

(Anda hanya perlu menampilkan nilai yang benar atau salah; penjelasan di bawah ini hanya dengan penjelasan.) Beberapa input yang menghasilkan nilai yang benar adalah:

39  (3 divides both 3 and 9)
64  (2 divides both 6 and 4)
497  (7 divides both 49 and 7)
990  (splitting into 99 and 0 is invalid; but 9 divides both 9 and 90)
2233  (11 divides both 22 and 33)
9156  (3 divides both 9 and 156; or, 7 divides both 91 and 56)
11791  (13 divides both 117 and 91)
91015  (5 divides both 910 and 15)
1912496621  (23 divides both 1912496 and 621; some splittings are multiples of 7 as well)
9372679892  (2473 divides both 937267 and 9892; some splittings are multiples of 2 as well)

Beberapa input yang menghasilkan nilai palsu adalah:

52
61
130  (note that 13 and 0 is not a valid splitting)
691
899
2397
9029
26315
77300  (neither 7730 and 0 nor 773 and 00 are valid splittings)
2242593803

¹ ya saya benar-benar melakukan ini

Jawaban:


7

Retina , 31 29 byte


,$';$`
\d+
$*
;(11+)\1*,\1+;

Cobalah online!

Menghasilkan bilangan bulat positif untuk input yang valid dan nol untuk yang tidak valid.

Saya tidak akan merekomendasikan menunggu kasus uji yang lebih besar ...

Penjelasan


,$';$`

Pada setiap posisi input masukkan koma, lalu semuanya sebelum posisi itu, lalu titik koma, lalu semuanya setelah posisi ini. Apa fungsinya? Ini memberi kita semua kemungkinan angka (dibagi oleh ,, dipisahkan oleh ;), dan kemudian input lagi di akhir. Jadi input 123menjadi

,123;1,23;12,3;123,;123
     ^     ^     ^

tempat saya menandai karakter input asli (hal-hal yang tidak ditandai adalah apa yang kami sisipkan). Perhatikan bahwa ini membuat perpecahan tidak valid yang bukan perpecahan aktual dan juga tidak peduli apakah komponen tambahannya nol, tapi kami akan menghindari menerimanya nanti. Manfaat membuat pemisahan yang tidak valid adalah kita tahu bahwa setiap pemisahan yang valid memiliki ;di depan dan setelahnya, sehingga kita dapat menyimpan dua byte pada batas kata.

\d+
$*

Ubah setiap nomor menjadi unary.

;(11+)\1*,\1+;

Cocokkan pemisahan dengan mencocokkan kedua bagian sebagai kelipatan dari beberapa angka yang setidaknya 2.


Pertanyaan singkat tentang Retina: Apa yang dilakukan oleh baris baru?
HyperNeutrino

@HyperNeutrino Nah, baris pertama adalah regex pertama yang cocok dengan kami, dan kami ingin mencocokkan regex kosong, untuk memasukkan subtitusi ke setiap posisi di antara karakter.
Martin Ender

Oh baiklah. Terima kasih! Saya mungkin harus melihat sedikit lebih pada Retina; karena tampaknya sebagian besar berdasarkan regex mungkin baik untuk masalah kompleksitas-kolmogorov .
HyperNeutrino

Mungkinkah baris terakhir adalah;(11+)+,\1+;
Riley

@Riley yang tidak menjamin bahwa segmen pertama adalah kelipatan dari faktor yang sama.
Martin Ender

6

Brachylog (2), 8 byte

~c₂ḋᵐ∋ᵐ=

Cobalah online!

Penjelasan

~c₂ḋᵐ∋ᵐ=
~c₂       Split the input into two pieces
    ᵐ ᵐ   On each of those pieces:
   ḋ ∋      Choose a prime factor
       =  such that both the chosen factors are equal

Jelas, jika nomor yang sama (lebih besar dari 1) membagi kedua bagian, bilangan prima yang sama akan membagi keduanya. Mewajibkan faktor untuk prima dengan rapi tidak mengizinkan 1 sebagai faktor. Ini juga mencegah literal 0dipilih sebagai segmen nomor (karena 0tidak memiliki faktorisasi utama, dan akan menyebabkan kegagalan).

Tidak perlu memeriksa terhadap nol internal yang cocok; jika pemisahan xdan 0yvalid, x0dan yakan bekerja dengan baik (dan sebaliknya, jika x0dan ybekerja, maka kami memiliki solusi yang berfungsi terlepas dari apakah xdan 0yakan bekerja atau tidak).

Program lengkap Brachylog, seperti ini, mengembalikan Boolean; true.jika ada beberapa cara untuk menjalankannya tanpa kegagalan (yaitu membuat pilihan sedemikian rupa sehingga tidak ada kesalahan terjadi), false.jika semua jalur mengarah ke kegagalan. Itulah yang kami inginkan di sini.


4

Jelly , 14 12 11 10 byte

ŒṖḌo1g/€P>

Terima kasih kepada @JonathanAllan untuk bermain golf 1 byte!

Cobalah online!

Bagaimana itu bekerja

ŒṖḌo1g/€P>  Main link. Argument: n

ŒṖ          Compute all partitions of n's decimal digits.
  Ḍ         Undecimal; convert each array in each partition back to integer.
   o1       OR 1; replace disallowed zeroes with ones.
     g/€    Reduce (/) each (€) partition by GCD (g).
            The last GCD corresponds to the singleton partition and will always be
            equal to n. For a falsy input, all other GCDs will be 1.
        P   Take the product of all GCDs.
         >  Compare the product with n.

Saya pikir Anda dapat menjatuhkan D, seperti make_digitsberlaku untuk ŒṖ.
Jonathan Allan

Untuk beberapa alasan, saya berasumsi itu akan membuat jangkauan ... Terima kasih!
Dennis

3

Mathematica, 63 62 byte

(1 byte terima kasih kepada Greg Martin)

1<Max@@GCD@@@Table[1~Max~#&/@Floor@{Mod[#,t=10^n],#/t},{n,#}]&

Ini adalah fungsi yang mengambil integer sebagai input dan mengembalikan Trueatau False. Jika Anda mengujinya dalam jumlah besar, bawalah buku untuk dibaca sambil menunggu.

Penjelasan:

  • Floor@{Mod[#,t=10^n],#/t}membagi secara hitung input menjadi ndigit terakhir dan digit yang tersisa m-n(di mana mjumlah total digit).
  • Table[1~Max~#&/@...,{n,#}]melakukan ini untuk setiap nhingga nomor input. (Ini terlalu besar. Kita hanya perlu melakukan ini hingga jumlah digit input, tetapi cara ini menyimpan byte dan masih memberikan hasil yang benar.) 1~Max~#&/@Bit menghilangkan nol, jadi angka seperti 130 -> {13,0}tidak masuk hitungan sebagai True.
  • 1<Max@@GCD@@@... menemukan pembagi umum terbesar dari masing-masing pasangan ini, dan memeriksa apakah ada pembagi ini lebih dari 1. Jika ya, kami telah menemukan cara untuk memperhitungkan faktor dengan memisahkannya.

1
Jawaban bagus! Anda dapat menyimpan satu byte dengan salah satu {#~Mod~10^n,#/10^n}atau {Mod[#,t=10^n],#/t}.
Greg Martin

Saya mencoba #~Mod~10^n, tetapi tampaknya mendapatkan tanda kurung seperti Mod[#,10]^nbukan Mod[#,10^n]. Saya tidak memikirkan saran kedua Anda!
Bukan pohon

titik adil padaMod[#,10]^n
Greg Martin


2

C, 145 142 139 138 135 byte

i,a,b;f(){char s[99];scanf("%s",s);for(char*p=s;*p++;)for(b=atoi(p),i=*p,*p=0,a=atoi(s),*p=i,i=1;i++<b;)*s=a%i-b%i|b%i?*s:0;return!*s;}

2

JavaScript (ES6), 74 71 70 byte

f=(s,t='',u)=>u?s%t?f(t,s%t,1):t:s&&f(t+=s[0],s=s.slice(1),1)>1|f(s,t)
<input oninput=o.textContent=f(this.value)><span id=o>

Mengambil input sebagai string, yang berguna untuk cuplikan. Sunting: Disimpan 3 byte berkat @ user81655.


Menghemat dua byte: (c,i)-> c, i+1-> ++i, t=''-> i=t='', trik ini berguna setiap kali Anda perlu menggunakan indeks 1 berbasis dan memiliki tempat untuk menginisialisasinya iuntuk 0.
user81655

Saya juga percaya t=''bisa t=0, karena menambahkan ccoerces ke string.
user81655

@ user81655 Ini terjadi karena saya awalnya memotong dari dan ke i, jadi saya tidak perlu indeks berbasis 1, tapi kemudian saya bermain golf irisan pertama t+=c.
Neil

Ah, baiklah. Juga satu hal lagi, saya pikir ini juga bisa menjadi lebih pendek sebagai fungsi rekursif: f=(x,y,z)=>z?x%y?g(y,x%y):y:x?f(x,y,1)>1||f(x.slice(1),~~y+x[0]):0. Saya menggabungkan fungsi GCD Anda dengan fjuga. Mungkin bisa bermain golf lebih lanjut. Saran terakhir, aku janji! : P
user81655

@ user81655 Sayangnya gcdfungsi saya yang terlalu disederhanakan tidak bekerja kapan x=0, dan mengatasinya dan kesalahan ketik Anda membawa saya ke 72 byte, jadi untungnya saya kemudian bisa bermain golf sejauh 2 byte.
Neil

2

Python 3, 133 118 117 byte

i,j=int,input()
from fractions import*
print(any(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j))))

Tentu bukan yang terpendek, mungkin bisa dipersingkat sedikit. Bekerja O(n)tepat waktu. Input diambil dalam format \d+dan output diberikan dalam format (True|False)sesuai standar nilai boolean Python
-3 byte berkat Dead Possum
-15 byte berkat ovs
-1 byte terima kasih kepada Orang Ini


from fractions import*akan menghemat 3 byte
Dead Possum

Mengembalikan Benar untuk 900. Saya kira, itu salah. Mb Anda harus mengubah anyke dalam all? Jika itu masalahnya, Anda dapat mengubah semua bagian i(j[k:])and i(j[:k])itu agar semuanya menjadi 125 byte. Ini adalah perbaikan
Dead Possum

Anda dapat mengganti dan dan semuanya dengan multiplikasi:any(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j)))
ovs

@DeadPossum Oh benar, saya harus melakukan itu. Dan ya, metode saya saat ini memiliki banyak bagian golf di dalamnya, tapi saya akan mengikuti saran Ovs. Terima kasih telah menunjukkan itu! (benar-benar harus mengujinya sendiri ... oh well ...)
HyperNeutrino

Anda dapat menghapus byte (hampir tidak ada) dengan menghapus spasi antara)) for
caird coinheringaahing

1

QBIC , 91 90 byte

;_LA|[a-1|B=left$(A,b)┘C=right$(A,a-b)┘x=!B!┘y=!C![2,x|~(x>1)*(y>1)*(x%c=0)*(y%c=0)|_Xq}?0

Penjelasan:

;               Get A$ from the command prompt
_LA|            Get the length of A$ and place it in a% (num var)
[a-1|           for b%=1; b% <= a%-1; b%++
B=left$(A,b)    break A$ in two components on index b%
C=right$(A,a-b)
x=!B!┘y=!C!     Convert both parts from string to num, assign to x% and y%
[2,x|           FOR c% = 2; c% <= x%; c%++

This next IF (~ in QBIC) is a bit ... iffy. It consists of a set of comparators.
Each comparator yields a -1 or a 0. We take the product of these. At any failed
comparison this will yield 0. When successful, it yields 1, which is seen as true by QBasic.

~(x>1)*(y>1)        IF X>1 and Y>1 --> this stops '00' and '1' splits.
*(x%c=0)*(y%c=0)    Trial divide the splits on loop counter c%.

|_Xq            Success? THEN END, and PRINT q (which is set to 1 in QBIC)
}               Close all language constructs (2 FOR loops and an IF)
?0              We didn't quit on match, so print 0


1

Perl 5 , 46 byte

43 byte kode + 3 byte untuk -pflag.

s~~$\|=grep!($`%$_|$'%$_),2..$`if$`*$'~ge}{

Cobalah online! atau coba versi modifikasi ini yang memungkinkan banyak input.
Anda mungkin tidak ingin mencoba ini pada input terbesar, karena mungkin butuh waktu (sangat lama).

Penjelasan:
Kami beralih melalui setiap posisi dalam kata dengan s~~~g, dengan $`berisi angka sebelum dan $'angka sesudahnya. Jika $`*$'benar (itu berarti tidak ada yang kosong, dan tidak ada yang ada 0), maka kami memeriksa apakah angka antara 2 dan $`membagi keduanya (dengan grep!(...),2..$`). Jika demikian, $\|=..akan ditetapkan $\ke nilai bukan nol, yang dicetak secara implisit di akhir berkat -pbenderanya.


2
Jika ada yang tahu cara merender $<backquote>dalam penurunan harga SE, saya akan berterima kasih jika Anda memberi tahu saya caranya.
Dada

1
Anda dapat melakukannya dengan menggunakan eksplisit <code>... </code>(daripada `... `), lalu keluar dari backquotes sebagai \`. Juga, komentar ini sangat menyakitkan untuk ditulis, karena harus diloloskan ganda (dan dua set aturan pelarian berbeda!).

@ ais523 Luar biasa, terima kasih banyak! :)
Dada

0

Python 2 , 69 byte

f=lambda n,d=10,k=2:k<d<n and(n/d%k+n%d%k<1<n%d)|f(n,d,k+1)|f(n,10*d)

Menggunakan rekursi sebagai ganti built-in GCD.

Cobalah online!

Bagaimana itu bekerja

Ketika f dipanggil dengan satu hingga tiga argumen ( d default ke 10 , k ke 2 ), ia pertama-tama memeriksa nilai ekspresi k<d<n. Jika ketidaksetaraan k <d dan d <n keduanya bertahan, ekspresi berikut anddijalankan dan nilainya dikembalikan; jika tidak, f hanya akan mengembalikan False .

Dalam kasus sebelumnya, kita mulai dengan mengevaluasi ekspresi n/d%k+n%d%k<1<n%d.

d akan selalu menjadi kekuatan sepuluh, jadi n/ddan n%dsecara efektif membagi angka desimal pada n menjadi dua irisan. Irisan ini dapat dibagi oleh k jika dan hanya jika n/d%k+n%d%kbernilai 0 , yang diuji dengan membandingkan hasilnya dengan 1 .

Karena bagian dari persyaratan adalah bahwa kedua irisan harus mewakili bilangan bulat positif, nilainya n%djuga dibandingkan dengan 1 . Perhatikan bahwa 1 tidak memiliki pembagi utama, sehingga perbandingan yang lebih mahal dengan 0 tidak diperlukan. Juga, perhatikan bahwa d <n sudah memastikan yang n/dakan mengevaluasi ke bilangan bulat positif.

Akhirnya secara rekursif semua f(n,d,k+1)(mencoba pembagi umum potensial berikutnya) dan f(n,10*d)(mencoba pemisahan) dan mengembalikan logika ATAU dari ketiga hasil. Ini berarti f akan mengembalikan True jika (dan hanya jika) k adalah pembagi umum n / d dan n% d atau yang sama berlaku untuk nilai k yang lebih besar dan / atau kekuatan yang lebih tinggi dari sepuluh d .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.