Chia và chia và chinh phục


22

Đôi khi, khi tôi ngớ ngẩn cố gắng tính bất cứ con số nào xuất hiện trước mặt tôi, sau một thời gian tôi nhận ra nó dễ dàng hơn tôi nghĩ. Lấy 2156ví dụ: cuối cùng tôi nhận ra rằng cả hai 2156là bội số của 7, và vì vậy chắc chắn 2156 = 21 x 100 + 56cũng là bội số của 7.

Nhiệm vụ của bạn là viết một số mã xác định các số dễ dàng hơn do sự trùng hợp của loại này.

Chính xác hơn:

Viết chương trình hoặc hàm lấy số nguyên dương nlàm đầu vào và trả về giá trị trung thực nếu tồn tại một ước số d(lớn hơn 1) sao cho ncó thể chia thành hai để lấy hai số nguyên dương, mỗi số nguyên là bội số của d; trả về một giá trị giả nếu không.

  • "Chặt làm hai" có nghĩa là những gì bạn nghĩ: đại diện cơ sở-10 thông thường được nphân vùng tại một số điểm thành một nửa trước và một nửa sau để mang lại hai số nguyên cơ số 10 khác. Không sao nếu số nguyên thứ hai có số 0 đứng đầu (nhưng lưu ý rằng nó phải là số nguyên dương, vì vậy việc chia 1230thành 1230không hợp lệ).
  • Các giá trị trung thực và giả có thể phụ thuộc vào đầu vào. Ví dụ: nếu bất kỳ số nguyên khác nào là trung thực trong ngôn ngữ bạn chọn, thì bạn có thể trả lại số chia dhoặc một trong các "phần" của n(hoặc nchính nó cho vấn đề đó).
  • Ví dụ: bất kỳ số chẵn nào có ít nhất hai chữ số trong tập hợp {2, 4, 6, 8}sẽ mang lại giá trị trung thực: chỉ cần chia nó sau chữ số chẵn đầu tiên. Ngoài ra, ví dụ, bất kỳ số nguyên tố nào ncũng sẽ mang lại giá trị giả, cũng như bất kỳ số nào có một chữ số.
  • Lưu ý rằng nó đủ để xem xét các ước số nguyên tố d.
  • Bạn có thể giả sử đầu vào là hợp lệ (nghĩa là số nguyên dương).

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng. Nhưng các giải pháp trong tất cả các ngôn ngữ đều được chào đón, vì vậy chúng tôi có thể phấn đấu cho mã ngắn nhất trong mỗi ngôn ngữ, không chỉ là mã ngắn nhất nói chung.

Các trường hợp thử nghiệm

(Bạn chỉ phải đưa ra một giá trị trung thực hoặc sai lệch; các chú thích bên dưới chỉ bằng cách giải thích.) Một số đầu vào mang lại giá trị trung thực là:

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)

Một số đầu vào mang lại giá trị giả là:

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

Vâng tôi thực sự làm điều này

Câu trả lời:


7

Võng mạc , 31 29 byte


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

Hãy thử trực tuyến!

Xuất ra một số nguyên dương cho các đầu vào hợp lệ và 0 cho các đầu vào không hợp lệ.

Tôi không khuyên bạn nên chờ đợi các trường hợp thử nghiệm lớn hơn ...

Giải trình


,$';$`

Tại mỗi vị trí của đầu vào chèn một dấu phẩy, sau đó mọi thứ trước vị trí đó, rồi dấu chấm phẩy, rồi mọi thứ sau vị trí này. Cái đó làm cái gì? Nó cung cấp cho chúng ta tất cả các mối nối có thể có của một số (được chia bởi ,, được phân tách bằng ;) và sau đó nhập lại vào cuối. Vì vậy, đầu vào 123trở thành

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

trong đó tôi đã đánh dấu các ký tự đầu vào ban đầu (nội dung không được đánh dấu là những gì chúng tôi đã chèn). Lưu ý rằng điều này tạo ra các mối nối không hợp lệ không phải là mối nối thực tế và cũng không quan tâm liệu thành phần cuối có phải là số không hay không, nhưng chúng ta sẽ tránh chấp nhận những lần sau. Lợi ích của việc tạo các mối nối không hợp lệ là chúng tôi biết rằng mỗi phân tách hợp lệ có một ;phía trước và sau nó, vì vậy chúng tôi có thể lưu hai byte trên các ranh giới từ.

\d+
$*

Chuyển đổi từng số để unary.

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

Ghép một phần tách bằng cách khớp cả hai nửa dưới dạng bội số của một số ít nhất là 2.


Câu hỏi nhanh về Retina: Dòng mới hàng đầu làm gì?
HyperNeutrino

@HyperNeutrino Vâng, dòng đầu tiên là regex đầu tiên chúng ta khớp và chúng ta muốn khớp với regex trống, để chèn sự thay thế vào mọi vị trí giữa các ký tự.
Martin Ender

Ờ được rồi. Cảm ơn! Tôi có lẽ nên nhìn thêm một chút về Retina; vì có vẻ như phần lớn regex dựa trên nó có thể tốt cho các vấn đề phức tạp kolmogorov .
HyperNeutrino

Dòng cuối cùng có thể là;(11+)+,\1+;
Riley

@Riley không đảm bảo rằng phân khúc đầu tiên là bội số của cùng một yếu tố.
Martin Ender

6

Brachylog (2), 8 byte

~c₂ḋᵐ∋ᵐ=

Hãy thử trực tuyến!

Giải trình

~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

Rõ ràng, nếu cùng một số (lớn hơn 1) chia cả hai phần, thì số nguyên tố giống nhau sẽ chia cả hai. Yêu cầu yếu tố là nguyên tố gọn gàng không cho phép 1 là một yếu tố. Nó cũng ngăn chặn một nghĩa đen 0được chọn là một phân đoạn của một số (vì 0không có thừa số nguyên tố, và sẽ gây ra thất bại).

Không cần phải kiểm tra so với các số 0 nội bộ phù hợp; nếu một phân chia x0yhợp lệ, x0ysẽ hoạt động tốt (và đi theo cách khác, nếu x0yhoạt động, thì chúng tôi có một giải pháp làm việc bất kể có x0ysẽ làm việc hay không).

Một chương trình đầy đủ của Brachylog, như chương trình này, trả về Boolean; true.nếu có cách nào đó để chạy nó mà không bị lỗi (nghĩa là đưa ra các lựa chọn sao cho không xảy ra lỗi), false.nếu tất cả các đường dẫn đều dẫn đến thất bại. Đó chính xác là những gì chúng tôi muốn ở đây.


4

Thạch , 14 12 11 10 byte

ŒṖḌo1g/€P>

Cảm ơn @Jonathan ALLan vì đã chơi golf 1 byte!

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

ŒṖḌ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.

Tôi nghĩ rằng bạn có thể thả D, như make_digitscó hiệu lực cho ŒṖ.
Jonathan Allan

Vì một số lý do, tôi cho rằng sẽ tạo ra một phạm vi ... Cảm ơn!
Dennis

3

Toán học, 63 62 byte

(1 byte nhờ Greg Martin)

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

Đây là một hàm lấy một số nguyên làm đầu vào và trả về Truehoặc False. Nếu bạn kiểm tra nó trên một số lượng lớn, hãy mang theo một cuốn sách để đọc trong khi bạn chờ đợi.

Giải trình:

  • Floor@{Mod[#,t=10^n],#/t}chia một cách hợp lý đầu vào thành các nchữ số cuối cùng và các m-nchữ số còn lại (trong đó mtổng số chữ số).
  • Table[1~Max~#&/@...,{n,#}]làm điều này cho mỗi nlên đến số đầu vào. (Đây là cách quá lớn. Chúng ta chỉ cần làm điều này với số chữ số của đầu vào, nhưng cách này giúp tiết kiệm byte và vẫn cho kết quả chính xác.) 1~Max~#&/@Bit bị loại bỏ các số 0, vì vậy các số như 130 -> {13,0}không được tính như True.
  • 1<Max@@GCD@@@... tìm ước số chung lớn nhất của mỗi cặp này và kiểm tra xem có bất kỳ ước nào trong số này là hơn 1. Nếu có, chúng tôi đã tìm ra cách tính số bằng cách chia số đó.

1
Câu trả lời tốt đẹp! Bạn có thể lưu một byte bằng {#~Mod~10^n,#/10^n}hoặc {Mod[#,t=10^n],#/t}.
Greg Martin

Tôi đã thử #~Mod~10^n, nhưng nó dường như được đóng khung như Mod[#,10]^nthay vì Mod[#,10^n]. Tôi đã không nghĩ đến đề nghị thứ hai của bạn, mặc dù!
Không phải là một cái cây vào

điểm công bằng trênMod[#,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>

Lấy đầu vào dưới dạng một chuỗi, tiện dụng cho đoạn mã. Chỉnh sửa: Đã lưu 3 byte nhờ @ user81655.


Tiết kiệm hai byte: (c,i)-> c, i+1-> ++i, t=''-> i=t='', thủ thuật này rất hữu ích bất cứ lúc nào bạn cần sử dụng chỉ số 1 có trụ sở và có nơi nào đó để khởi iđến 0.
dùng81655

Ngoài ra tôi tin rằng t=''có thể t=0, vì cdù sao cũng buộc nó vào một chuỗi.
dùng81655

@ user81655 Điều này xảy ra bởi vì ban đầu tôi đã cắt từ và đến i, vì vậy tôi không cần các chỉ số dựa trên 1, nhưng sau đó tôi đã chơi gôn ở lát đầu tiên t+=c.
Neil

À, được rồi Ngoài ra, một điều cuối cùng, tôi nghĩ rằng điều này cũng có thể ngắn hơn như là một hàm đệ quy : 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. Tôi đã kết hợp chức năng GCD của bạn flà tốt. Có lẽ có thể được chơi golf hơn nữa. Đề nghị cuối cùng, tôi hứa! : P
user81655

@ user81655 Đáng buồn là gcdchức năng đơn giản hóa của tôi không hoạt động khi x=0và hoạt động xung quanh đó và lỗi đánh máy của tôi đã đưa tôi tới 72 byte, vì vậy thật may mắn khi tôi đã có thể chơi golf 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))))

Chắc chắn không phải là ngắn nhất, có lẽ có thể rút ngắn một chút. Hoạt động O(n)đúng lúc. Đầu vào được lấy theo định dạng \d+và đầu ra được đưa ra ở định dạng (True|False)theo giá trị boolean Python mặc định
-3 byte nhờ Dead Possum
-15 byte nhờ vào
các byte -1 byte nhờ This Guy


from fractions import*sẽ tiết kiệm được 3 byte
Dead Possum

Nó trả về True cho 900. Tôi đoán, đó là sai. Mb bạn nên thay đổi bên trong anyđể all? Nếu đó là trường hợp, bạn có thể thay đổi tất cả phần đó để i(j[k:])and i(j[:k])mang tất cả thành 125 byte. Dưới đây là các bản sửa lỗi
Dead Possum

Bạn có thể thay thế và tất cả bằng cách nhân:any(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j)))
ovs

@DeadPossum Oh đúng, tôi nên làm điều đó. Và vâng, phương pháp hiện tại của tôi có rất nhiều bộ phận có thể chơi được trong đó, nhưng tôi sẽ làm theo đề xuất của ovs. Cảm ơn đã chỉ ra rằng! (thực sự nên tự mình kiểm tra nó ... ồ ...)
HyperNeutrino

Bạn có thể xóa một byte (hầu như không có gì) bằng cách xóa khoảng trắng giữa)) 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

Giải trình:

;               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 mã + 3 byte cho -pcờ.

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

Hãy thử trực tuyến! hoặc thử phiên bản sửa đổi này cho phép nhiều đầu vào.
Bạn có thể không muốn thử điều này trên đầu vào lớn nhất, vì có thể mất một lúc (rất lâu).

Giải thích:
Chúng tôi lặp qua từng vị trí trong từ với s~~~g, $`chứa các số trước và $'số sau. Nếu $`*$'là đúng (có nghĩa là không có sản phẩm nào và không có gì 0), thì chúng tôi sẽ kiểm tra xem một số có nằm giữa 2 và $`chia cả hai số đó hay không (với số grep!(...),2..$`). Nếu vậy, $\|=..sẽ được đặt $\thành một giá trị khác không, được in ngầm ở cuối nhờ -pcờ.


2
Nếu bất cứ ai biết làm thế nào để hiển thị $<backquote>trong SE markdown, tôi sẽ biết ơn nếu bạn cho tôi biết làm thế nào.
Dada

1
Bạn có thể làm điều đó thông qua sử dụng rõ ràng <code>... </code>(chứ không phải `... `), sau đó thoát khỏi backquotes như \`. Ngoài ra, bình luận này là một nỗi đau để viết, bởi vì nó phải được thoát hai lần (và hai bộ quy tắc thoát là khác nhau!).

@ ais523 Tuyệt vời, cảm ơn bạn rất nhiều! :)
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)

Sử dụng đệ quy thay vì tích hợp GCD.

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Khi f được gọi với một đến ba đối số ( d mặc định là 10 , k đến 2 ), trước tiên, nó sẽ kiểm tra giá trị của biểu thức k<d<n. Nếu bất đẳng thức k <dd <n đều giữ, biểu thức sau andđược thực thi và giá trị của nó được trả về; nếu không, f sẽ trả về Sai .

Trong trường hợp trước, chúng ta bắt đầu bằng cách đánh giá biểu thức n/d%k+n%d%k<1<n%d.

d sẽ luôn là lũy thừa mười, vì vậy n/dn%dphân chia các chữ số thập phân trên n thành hai lát một cách hiệu quả . Các lát cắt này đều chia hết cho k khi và chỉ khi n/d%k+n%d%kước lượng bằng 0 , được kiểm tra bằng cách so sánh kết quả với 1 .

Do một phần của các yêu cầu là cả hai lát phải đại diện cho các số nguyên dương, nên giá trị của n%dcũng được so sánh với 1 . Lưu ý rằng 1 không có ước số nguyên tố, vì vậy không cần phải so sánh đắt hơn với 0 . Ngoài ra, lưu ý rằng d <n đã đảm bảo rằng n/dsẽ đánh giá thành một số nguyên dương.

Cuối cùng, nó đệ quy tất cả f(n,d,k+1)(thử ước số chung tiềm năng tiếp theo) và f(n,10*d)(thử chia tách) và trả về OR logic của cả ba kết quả. Điều này có nghĩa là f sẽ trả về True nếu (và chỉ khi) k là ước số chung của n / dn% d hoặc tương tự là đúng với giá trị lớn hơn của k và / hoặc công suất cao hơn mười d .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.