Là một số chia hết cho mỗi chữ số của nó?


47

Bạn tôi và tôi đang làm việc trong một phòng thí nghiệm trong lớp Khoa học Máy tính AP của chúng tôi và quyết định viết mã một trong những vấn đề vì chúng tôi vẫn còn một nửa lớp miễn phí sau khi chúng tôi hoàn thành. Đây là câu hỏi:

Cho một số n, n có chia hết cho mỗi chữ số của nó không?

Ví dụ: 128 sẽ vượt qua bài kiểm tra này - nó chia hết cho 1,2 và 8. Bất kỳ số nào có số 0 sẽ tự động loại bỏ số đó. Mặc dù bạn có thể sử dụng các ngôn ngữ khác và đăng các giải pháp với chúng nếu bạn thích, chúng tôi quan tâm nhất là xem mọi người có thể tạo chương trình bằng Java như thế nào, vì đó là ngôn ngữ chúng tôi sử dụng trong lớp. Cho đến nay, cả hai chúng tôi đều có 51. Đây là mã hiện tại của tôi:

public boolean dividesSelf(int n){for(int p=n;n%10>0;)n/=p%(n%10)>0?.1:10;return n<1;}
// 51 characters

// Breakdown:
// for(int p=n;         Saves one semicolon to put declaration into for loop
// n%10>0;)             Basic check-for-zero
// n/=                  Pretty simple, discarding one number off of n at a time
// p%(n%10)>0?          If p (the given value) is not divisible by n%10 (the current digit)...
// .1:10;               Divide by .1 (multiply by 10) so it fails the check next iteration. If it is divisible, divide by 10 to truncate the last digit
// return n<1           If the number was fully divisible, every digit would be truncated, and n would be 0. Else, there would still be non-zero digits.

Yêu cầu

Chữ ký phương thức có thể là bất cứ điều gì bạn muốn. Chỉ cần đếm cơ thể chức năng. Mặc dù vậy, hãy chắc chắn rằng phương thức trả về giá trị boolean và chỉ truyền vào một tham số số (không phải là một chuỗi).

Mã phải có khả năng vượt qua tất cả các trường hợp này (để giữ đúng hướng của câu hỏi ban đầu, chỉ có giá trị boolean đúng và sai nếu ngôn ngữ hỗ trợ booleans. Nếu và chỉ khi ngôn ngữ của bạn không có biến boolean bạn có thể biểu thị sai với 0 và đúng với bất kỳ số nguyên khác nào (tốt nhất là 1 hoặc -1):

128 -> true
 12 -> true
120 -> false
122 -> true
 13 -> false
 32 -> false
 22 -> true
 42 -> false
212 -> true
213 -> false
162 -> true
204 -> false

Ngoài ra, chúng tôi đã không tính khoảng trắng, vì vậy hãy thoải mái làm điều tương tự, trừ khi khoảng trắng là điều cần thiết cho hoạt động của chương trình (vì vậy các dòng mới trong Java không được tính, nhưng một khoảng trống giữa intx=1không được tính.) Chúc may mắn !


18
Chào mừng đến với PPCG! Một vài gợi ý: 1. Không tính khoảng trắng chức năng là một ý tưởng tồi. Bất kỳ câu trả lời được viết trong Whitespace sẽ tự động giành chiến thắng. 2. Nên chúng tôi in trình / khứ hồi truefalsehoặc là truthy / falsy giá trị OK không? 3. javaThẻ không thực sự áp dụng ở đây, vì bản thân thách thức không liên quan đến Java.
Dennis

Được chứ. xin lỗi vì những vấn đề Chỉ cần xóa nó đi, bạn có xem khoảng trống trong 'int p = n' là chức năng không, vì trước đây tôi không có. Tôi sẽ sửa các vấn đề khác mà bạn chỉ ra.
Mathew Kirschbaum

5
Tất cả các khoảng trắng cần thiết để mã hoạt động là chức năng.
FryAmTheEggman

Được rồi, cảm ơn đã phản hồi!
Mathew Kirschbaum

1
@RickyDemer: vì 0 sẽ là một đầu vào đặc biệt trong trường hợp đó (đó là số duy nhất có các 0chữ số là bội số của mỗi số đó), tôi tưởng tượng hầu hết các câu trả lời sẽ dài hơn theo cách không thú vị để bao gồm kiểm tra cho nó. Vì vậy, tôi thích vấn đề được đặt ra bởi tiêu đề tốt hơn (chia hết cho các chữ số của nó, thay vì là bội số của các chữ số, loại trừ 0).
Jeroen Mostert

Câu trả lời:


23

Perl 6, 13

sub golf($_) {
   $_%%.comb.all
}

Sử dụng biến ẩn $_- $_ %% .comb.alltương đương với $_ %% all($_.comb). %%là toán tử "là chia hết" và combkhông có đối số bổ sung nào trả về danh sách các ký tự trong chuỗi. Ví dụ: nếu đối số là 123, thì hàm sẽ đánh giá

123 %% all(123.comb)

đó là

123 %% all(1, 2, 3)

ngã ba tự động làm cho nó

all(123 %% 1, 123 %% 2, 123 %% 3)

đó là

all(True, False, True)

đó là sai trong bối cảnh boolean bởi vì đó là một ngã ba "tất cả" và rõ ràng không phải tất cả các yếu tố của nó là đúng.

Có thể ép buộc giá trị trả về Boolvà ẩn mối nối với người gọi bằng cách tạo chữ ký hàm sub golf($_ --> Bool()), nhưng các ép buộc trong chữ ký hàm chưa hoạt động trong Rakudo. Giá trị trả về vẫn đúng hoặc sai, chỉ là không Truehoặc False.


Nếu bạn muốn làm cho nó trở lại, Boolchỉ cần thêm sovào phía trước của mã so$_%%.comb.all.
Brad Gilbert b2gills

21

C # và System.Linq - 26/40

Theo các quy tắc, không tính khai báo phương thức.

bool dividesSelf(int i) { 
    return(i+"").All(d=>i%(d-48d)<1);
}

Cho thấy một lần nữa, C # là lựa chọn ưu việt khi Java đang được xem xét ... Tôi là đứa trẻ, tôi là đứa trẻ!

Thật không may, chức năng này (và nhiều câu trả lời khác) sẽ không tạo ra kết quả chính xác cho đầu vào tiêu cực. Chúng tôi có thể khắc phục điều này, nhưng giải pháp mất rất nhiều sức hấp dẫn của nó (và tăng lên 46 ký tự):

return(i+"").All(d=>d>48&&i%(d-48)==0||d==45);

Chỉnh sửa : xóa một ký tự với đề xuất của Tim.

Chỉnh sửa : với việc giới thiệu các thành viên thân thể biểu hiện trong C # 6, chúng ta có thể giảm bớt điều này bằng cách cắt bỏ return:

bool dividesSelf(int i) =>
    (i+"").All(d=>i%(d-48d)<1);

với tổng số 26 ký tự (theo ý kiến ​​của tôi, =>không nên bao gồm nhiều hơn số lần niềng răng). Phiên bản xử lý số âm có thể được rút ngắn tương tự.


Tại sao .0? Không cần bất cứ thứ gì ngoài mô đun số nguyên.
Peter Taylor

3
@PeterTaylor: Có nếu bạn muốn chương trình ngắn nhất - i % 0với imột số nguyên cho a DivideByZeroException.
Jeroen Mostert

2
Và với một cú đúp nó mang lại cho NaN! Đẹp!
Peter Taylor

2
48dlà giống như 48.0, nhưng một ký tự ít hơn (d cho gấp đôi).
Tim S.

1
@StuartLC: lambdas không có phương pháp; phạm vi của chúng là khác nhau, vì vậy tôi nghĩ rằng điều đó đã bẻ cong các quy tắc quá xa. Nhưng vì C # 6 (mà câu trả lời này có trước), chúng tôi có các thành viên thân biểu hiện, điều này cho phép chúng tôi rút ngắn định nghĩa. Đối với trường hợp tiêu cực, chúng tôi không thể sử dụng &, chính xác là vì &không bị đoản mạch - bạn sẽ được chia cho số không ngoại lệ trên %. Chúng ta có thể khắc phục điều đó bằng cách biến nó thành một (hai d), nhưng sau đó chúng ta lại mất một ký tự.
Jeroen Mostert

18

APL ( 13 11)

(hình như dấu ngoặc không được tính)

{0∧.=⍵|⍨⍎¨⍕⍵}

Giải trình:

  • ⍎¨⍕⍵: đánh giá từng ký tự trong biểu diễn chuỗi của
  • ⍵|⍨: cho mỗi cái, tìm modulo của nó và
  • 0∧.=: xem liệu tất cả những thứ đó có bằng 0

Testcase:

      N,[.5] {0∧.=⍵|⍨⍎¨⍕⍵} ¨ N←128 12 120 122 13 32 22 42 212 213 162 204
128 12 120 122 13 32 22 42 212 213 162 204
  1  1   0   1  0  0  1  0   1   0   1   0

APL có thể làm gì X%0? mà không ném?
Tối ưu hóa

@Optimizer: có. 0|Xcho X.
marinus

Ngọt. Ngoài ra câu trả lời của bạn là 11 byte, không phải 13
Trình tối ưu hóa

9
Chỉ APL sẽ không đưa ra lỗi trên modulo bằng 0 và không đánh giá được một bool không phải là bool;)
FryAmTheEggman

3
Một nhân vật ngắn hơn với một chuyến tàu thay vì dfn:(0∧.=⍎¨∘⍕|⊢)
ngn

14

Python 2: 43 ký tự

f=lambda n:any(n%(int(d)or.3)for d in`n`)<1

Kiểm tra xem số có bất kỳ số dư nào không thay đổi modulo các chữ số của nó hay không và đưa ra phủ định của số đó. Các chữ số 0 được xử lý một cách kỳ lạ: vì tính toán %0gây ra lỗi, các chữ số 0được thay thế bằng .3, dường như luôn cho kết quả khác không do các điểm không chính xác.

Cơ thể chức năng là 32 ký tự.


14

Perl - 27 byte

sub dividesSelf{
    $_=pop;s/./!$&||$_%$&/ger<1
}

Không tính chữ ký chức năng, theo hướng dẫn.

Sử dụng mẫu:

use Data::Dump qw(dump);
for $i (128, 12, 120, 122, 13, 32, 22, 42, 212, 213, 162, 204) {
  printf "%3d -> %s\n", $i, dump(dividesSelf $i);
}

Đầu ra mẫu:

128 -> 1
 12 -> 1
120 -> ""
122 -> 1
 13 -> ""
 32 -> ""
 22 -> 1
 42 -> ""
212 -> 1
213 -> ""
162 -> 1
204 -> ""

Giải quyết đặc tả vấn đề: "Chỉ tính giá trị boolean đúng và sai. Giá trị thật / falsey không được tính."

use Data::Dump qw(dump);
dump(1 == 1);
dump(0 == 1);

Đầu ra:

1
""

'Đúng' và 'Sai' được định nghĩa là 1"".

Erratum:
Như Brad Gilbert đã chỉ ra một cách đúng đắn , perl định nghĩa đúng là một vô hướng vừa là số nguyên 1vừa là chuỗi "1"sai là một số vô hướng đồng thời là số nguyên 0và chuỗi "".


Điều này có thể được rút ngắn bằng cách không sử dụng $_: pop=~s///ger<1. Tôi không biết liệu OP có đồng ý điều đó 1hay không và ""là kết quả hợp lệ. Nếu không, thì nó có thể được sửa với hai byte nữa: chỉ cần thêm |0.
hvd

perl -pe'$_=s/./!$&||$_%$&/ger<1|0'là 26 byte bao gồm |0-pcờ. Bạn không phải sử dụng một chức năng.
hmatt1

1
Trên thực tế, các giá trị ĐúngSai giống dualvar(1,'1')và hơn dualvar(0,'').
Brad Gilbert b2gills

1
@BradGilbert Điều đó thật thú vị. Tôi khá quen thuộc với perlguts, nhưng tôi không biết rằng đúngsai là những trường hợp đặc biệt. Chúng thực sự là 'ba số vô hướng', được đánh dấu là SVIV(int), SVNV(double) và SVPV(chuỗi).
primo

1
Trên thực tế lần đầu tiên bạn sử dụng một chuỗi như một số hoặc một số làm một chuỗi, biến được sửa đổi để giữ dữ liệu bổ sung đó. Đó là lý do tại sao bạn chỉ nhận được cảnh báo lần đầu tiên bạn sử dụng 'abc'làm số (giả sử bạn đã use warnings;bật.)
Brad Gilbert b2gills

13

CJam, 11 10 byte

{
    _Ab:df%:+!
}:F;

Điều này xác định một chức năng được đặt tên Fvà loại bỏ khối khỏi ngăn xếp.

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

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

$ cjam <(echo '{_Ab:df%:+!}:F;[128 12 120 122 13 32 22 42 212 213 162 204]{F}%p')
[1 1 0 1 0 0 1 0 1 0 1 0]

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

_      " Copy the integer on the stack.                                          ";
Ab     " Push the array of its digits in base 10.                                ";
:d     " Cast each digit to Double.                                              ";
f%     " Take the integer on the stack modulus each of its digits.               ";
:+     " Add the results.                                                        ";
!      " Push the logical NOT of the sum.                                        ";

Có phải CJam có các tính năng bạn đã sử dụng cho giải pháp 10 byte khi câu hỏi được viết không?
lirtosiast

@ThomasKwa: Có rồi. Tôi đã kiểm tra mã trong phiên bản 0.6.2, được phát hành vào tháng 7 năm 2014.
Dennis

12

JavaScript ES6, 39 32 28 byte

v=>[...""+v].every(x=>v%x<1)

Cảm ơn core1024 cho những gợi ý để thay thế (""+v).split("")với [...""+v], và openorclose cho thấy việc sử dụng các everychức năng.

Câu trả lời hiện không chứa một bit mã của tôi: O

Giải pháp trước

v=>[...""+v].filter(x=>v%x|!+x)==""

==""không phải là một cách hợp lệ để kiểm tra xem một mảng có trống không, vì [""]==""trả về true, nhưng mảng được đảm bảo chứa chuỗi không trống, vì vậy nó hoạt động ở đây.

Phần còn lại là chuyển đổi loại tốc ký khá chuẩn trong JavaScript.


1
Bạn có thể lưu một số ký tự bằng cách thay thế (""+v).split("")bằng [...""+v].
core1024

1
Tại sao không sử dụng everyphương pháp? v=>[...""+v].every(x=>v%x<1);
openorc Đóng

@openorclose: Cảm ơn. Chưa bao giờ có cơ hội sử dụng nó trong JS, vì vậy tôi chưa bao giờ nghĩ đến việc tìm kiếm chức năng như vậy.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

v=>![...""+v].some(x=>v%x)
l4m2 17/12/17

@ l4m2 Vì v%0trả về NaNNaN == false, do đó, trong trường hợp của bạn, số có chứa 0, chẳng hạn như 10, có thể trả về true.
Shieru Asakoto

9

Java 8, 46 byte (thân phương thức)

Sử dụng chuyển đổi của Jeroen Mostert để lừa đôi.

public static boolean dividesSelf(int n) {
    return(""+n).chars().allMatch(x->n%(x-48d)<1);
}

8

Bình thường, 12 byte

!f|!vT%vzvTz

Cái này lọc các ký tự trong chuỗi thành 0 ( !vT) hoặc không chia đầu vào ( %vzvT), sau đó lấy logic không phải của danh sách kết quả.

Hãy thử nó ở đây.


Không, tôi ổn nếu một chức năng không được sử dụng. Tôi chỉ muốn chỉ ra cho bất kỳ ai đang sử dụng các hàm mà họ không cần phải đếm khai báo và chỉ có mã bên trong.
Mathew Kirschbaum

8

Ruby, 44 byte (thân hàm: 37)

Có lẽ có tiềm năng để được chơi golf hơn nữa.

f=->n{n.to_s.chars.all?{|x|x>?0&&n%x.hex<1}}

Đầu vào được thực hiện thông qua chức năng f. Ví dụ sử dụng:

f[128] # => true
f[12]  # => true
f[120] # => false
...

1
Bạn có thể thay đổi .to_ithành .hex, vì các số có một chữ số giống nhau ở cơ sở 16 và có thể thay đổi ==0thành <1.
lịch sử

8

Python - 59 50 49 47 byte

f=lambda n:all(c>'0'and 0==n%int(c)for c in`n`)

Tôi chắc chắn có một cách nhanh hơn ... oh tốt.

Chỉnh sửa - Cảm ơn FryAmTheEggman về các mẹo chơi gôn.

Chỉnh sửa 2 - FryAmTheEggman cũng có thể đã viết điều này vào thời điểm này, rất tiếc

Chỉnh sửa 3 - Giơ tay nếu bạn thậm chí không biết genexps là một thứ. ...Chỉ mình tôi?


Oh cảm ơn rất nhiều! Tôi tiếp tục quên đi tất cả những điều đó. (Tôi cũng không nhận ra bạn có thể ít hơn ký tự theo cách đó.)
Kasran

Ồ, lật logic dường như cũng rút ngắn lại một chút : f=lambda n:all([c>'0'and 0==n%int(c)for c in`n`]). Và không có vấn đề gì :)
FryAmTheEggman

Ồ, tôi đã không nhận ra có thậm chí một allphương pháp.
Kasran

Sẽ 1>n%int(c)làm việc?
Sp3000

3
Tại sao một danh sách hiểu? Sử dụng một genEx: all(c>'0'and 0==n%int(c)for c in`n`)thực hiện chính xác như nhau, với 2 char ít hơn và thậm chí tiết kiệm việc phân bổ danh sách.
Bakuriu

8

Số 11

!f%Q|vT.3`Q

Điều này kết hợp câu trả lời của @ isaacg@ xnor . Nó lọc các chữ số từ đầu vào bằng cách kiểm tra giá trị của input % (eval(current_digit) or .3). Sau đó, nó kiểm tra xem chuỗi kết quả có trống hay không.

Đã qua một vài biến thể có cùng chiều dài khác:

!f%Q|T.3jQT
!f|!T%QTjQT

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


5

Bash + coreutils, 44 byte

Định nghĩa chức năng đầy đủ là:

f()((`tr 0-9 \10<<<$1``sed "s/./||$1%&/g"<<<$1`))

Tôi không chắc làm thế nào để chấm điểm này vì các hàm shell thông thường sử dụng một bộ duy nhất {}hoặc ()để chứa thân hàm. Tôi tìm thấy ở đây tôi cũng có thể sử dụng gấp đôi (())để chứa phần thân hàm gây ra sự mở rộng số học, đây là thứ tôi cần ở đây. Vì vậy, bây giờ tôi chỉ đếm một cặp trong số các dấu ngoặc đó - thảo luận thêm về điều này được chào đón.

Đầu ra:

$ for i in 128 12 120 122 13 32 22 42 212 213 162 204; do f $i; printf "%d " $?; done
1 1 0 1 0 0 1 0 1 0 1 0 $
$

Uh - tôi không rõ liệu 1 và 0 có được chấp nhận hay tôi phải in true/ false?
Chấn thương kỹ thuật số

4

J - 14 char

Cơ thể chức năng là phần sau =:. Nếu chúng ta muốn giảm thiểu số lượng ký tự cho toàn bộ chức năng, đó là 15 char */@(0=,.&.":|]).

f=:0*/@:=,.&.":|]

,.&.":là cách ngắn nhất trong J để mở rộng dưới dạng số thành một danh sách các chữ số thập phân của nó: chuyển đổi thành chuỗi, tách các chữ số và chuyển đổi mỗi chữ số trở lại thành một số. ,.&.":|]lấy số đầu vào ( ]) modulo ( |) các chữ số đó. 0*/@:=trả về true nếu tất cả các kết quả là 0, khác sẽ cho sai.

   f 162
1
   f every 204 212 213
0 1 0

3

Java - 121 102 97 79 78 byte

Tôi chỉ biết điều này sẽ bị tắc nghẽn sau này. Ồ tốt

boolean b(int a){int m=10,j,t=1;for(;m<a*10;m*=10){j=10*(a%m)/m;if(j==0||a%j>0)t=0;}return t>0;}

Tôi sẽ trở lại.


1
Bây giờ bạn có thể đặt tên cho chức năng của bạn bất cứ điều gì bạn muốn. Tôi đã thay đổi các quy tắc để bạn chỉ đếm các tính toán bên trong hàm thực tế, nhưng hàm phải trả về kiểu boolean. Vì vậy, hiện tại là 86 ký tự.
Mathew Kirschbaum

3

Haskell - 100 54 38

f x=all(\y->y>'0'&&x`mod`read[y]<1)$show x

Vẫn đang học, phê bình đánh giá cao


Tôi đã có một bình luận ở đây, nhưng tôi đã vô tình xóa nó bằng cách nào đó ... Dù sao, một số gợi ý: 1) Thả lengths, chúng không cần thiết. 2) Thay thế ttheo định nghĩa của nó. 3) elem y slà không cần thiết. 4) /='0'có thể được chuyển sang bộ lọc bên trái, thay cho elem y s. 5) Trong trường hợp này, /='0'tương đương với >'0', vì mỗi chữ cái là một chữ số. 6) Đặt modbackticks, vì vậy nó trở thành infix. 7) Đặt mọi thứ trên một dòng duy nhất.
Zgarb

1 và 3 là từ khi tôi đang cố gắng thực hiện nó theo một cách khác và mã được trục vớt. Cảm ơn vì những lời khuyên.
globalby

1
đề nghị của tôi: thay vì sử dụng s==filter(...)sbạn nên sử dụng all(...)s. bây giờ, vì schỉ xuất hiện một lần trong biểu thức, bạn có thể thay thế nó bằng định nghĩa và thả where. Ngoài ra, thay vì ==0bạn có thể sử dụng <1.
tự hào

cải tiến tuyệt vời từ phiên bản đầu tiên!
tự hào

Tôi nghĩ bạn vẫn có thể mất một byte nếu thay thế all(\y->...)$show xbằng and[...|y<-show x].
Zgarb

2

CJam, 15 byte

{_Abf{_g{%}*}:|!}

Đây là một khối, thứ gần nhất với một chức năng trong CJam. Tôi chỉ đếm cơ thể (tức là bỏ qua niềng răng). Bạn có thể sử dụng nó như sau:

128{_Abf{_g{%}*}:|!}~

Hoặc nếu bạn muốn kiểm tra một loạt các đầu vào, bạn có thể làm

[128 12 120 122 13 32 22 42 212 213 162 204]{{_Abf{_g{%}*}:|!}~}%

Khối rời 0(giả) hoặc 1(trung thực) trên ngăn xếp để chỉ ra kết quả. (CJam không có loại Boolean.)

Kiểm tra nó ở đây.

Giải trình:

_               "Duplicate input.";
 Ab             "Get base-10 digits.";
   f{      }    "This maps the block onto the list of digits, supplying the input each time.";
     _g         "Duplicate digit, get signum S (0 or 1).";
       { }*     "Repeat this block S times.";
        %       "Take input modulo digit.";
                "This leaves an array of zeroes for divisible digits, non-zeroes
                 for non-divisible digits, and non-zero junk for zeroes.";
            :|  "Fold OR onto this list. One could also sum the list with :+";
              ! "Logical NOT. Turns 0 into 1, and non-zero values into 0.";

Thay thế, cũng 15 byte

{:XAb{X\_X)?%},!}

Giải trình

:X              "Store input in X.";
  Ab            "Get base-10 digits.";
    {       },  "Filter this list by the result of the block.";
     X\         "Push another copy of X, swap with digit.";
       _        "Duplicate digit.";
        X)      "Push X+1.";
          ?     "Select digit itself or X+1, depending on whether digit is 0 or not.";
           %    "Take modulo. X%(X+1) will always be nonzero for positive integers.";
              ! "Logical NOT. Turns an empty list into 1 and a non-empty list into 0.";

2

CJam, 15 byte

{_Abf{_{%}1?}1b!}

{}là thứ gần nhất với một chức năng trong CJam. Tôi chỉ đang đếm cơ thể của chức năng

Sử dụng nó như thế này:

128{_Abf{_{%}1?}1b!}~

Để có được một trong hai 1(nếu số đó chia hết) hoặc 0(nếu số đó không chia hết cho các chữ số của nó).

Dùng thử trực tuyến tại đây

Giải trình

_Ab                "Copy the number and split it to its digits";
   f{      }       "For each digit, run this code block on the number";
     _{%}1?        "If the digit is 0, put 1, otherwise perform number modulus digit";
            1b     "We now have an array of modulus corresponding to each digit. Sum it up";
              !    "Negate the sum. If all digits were divisible, sum of modules will be"
                   "0, thus answer should be 1 and vice versa";

Tôi có thể đang thiếu một cái gì đó, nhưng sau khi đọc nhanh về CJam, một số thứ dường như không có ý nghĩa: làm thế nào để Abphân chia các chữ số? Có vẻ như chỉ chuyển đổi nó thành cơ sở 10. Ngoài ra, làm thế nào% biết mod theo số, và không chỉ chữ số tiếp theo, vì dường như chữ số tiếp theo sẽ nằm trên ngăn xếp?
Mathew Kirschbaum

Trả lời tất cả các câu hỏi của bạn sẽ là khó khăn. Nó sẽ rất dễ học bằng cách đặt ed sau mỗi ký tự trong mã. Hãy thử chạy128{ed_edAedbedf{ed_ed{ed%ed}1ed?ed}ed1edbed!ed}~
Trình tối ưu hóa

1
Trả lời cho các câu hỏi cụ thể: làm cơ sở 10 đưa ra một mảng gồm các số cơ sở 10 được chuyển đổi, đó là các chữ số trong trường hợp này. %chỉ cần lấy hai số cuối (trong trường hợp này) và tính mod. Hai số cuối ở đây là số và chữ số thực tế (luôn luôn)
Trình tối ưu hóa

Được rồi, cảm ơn vì lời khuyên!
Mathew Kirschbaum

2

C89, 43 byte

unsigned char d(int n, int c) {
        int a=n%10;return!n||a&&!(c%a)&&d(n/10,c);
}

C89 không có kiểu boolean. Hy vọng rằng hoạt động. Ngoài ra tôi đã sử dụng một tham số thứ hai để truyền một bản sao của số gốc thông qua ngăn xếp, nhưng định nghĩa có thể là bất cứ điều gì. Để có kết quả chính xác, bạn chỉ cần gọi hàm có cùng giá trị cho cả hai tham số ( d(128, 128)).

EDIT: Ứng dụng chỉnh sửa được đề xuất bởi người dùng ẩn danh


Hãy xem codegolf.stackexchange.com/review/suggested-edits/17160 , ai đó đã cho bạn một số đề xuất chơi gôn
Justin

Cụ thể chống lại các quy tắc. Một tham số.
edc65

Vâng, bài đăng này thực sự là lý do tại sao tôi quyết định thực hiện quy tắc đó, vì có vẻ như người dùng không nên thực hiện sao chép thay vì chương trình.
Mathew Kirschbaum

Tôi đoán tôi sẽ phải thêm một chức năng bao bọc. Khai báo của hàm đó có thêm vào số byte không?
MarcDefiant

2

C11 - 44 byte trong cơ thể chức năng

Một phiên bản C khác, không đệ quy và không có ngoại lệ dấu phẩy động.

bool digit_multiple(int i)
{
    for(int n=i;i%10&&n%(i%10)<1;i/=10);return!i;
}

Điều này cũng sẽ hoạt động trong C ++, Java và hầu hết các ngôn ngữ giống C khác.

Chỉnh sửa để bao gồm cải thiện nhận xét của primo.


1
Một phiên bản biên dịch bằng Java (1.7.0_45-b18) : int n=i;for(;i%10>0&&n%(i%10)<1;i/=10);return i<1;, ngắn hơn một byte so với mã của OP.
primo

2

Julia 32 25 23

Cải thiện bằng chữ số

Cũng khắc phục sự cố với số âm

selfDivides(x)=sum(x%digits(x).^1.)==0

Phương pháp cũ

Tất cả các chữ số chia nếu tổng của tất cả các phần dư là 0. Giống như các số khác, có vấn đề với các số âm.

selfDivides(x)=sum(x.%(Float64["$x"...]-48))==0

Đầu ra

[selfDivides(x) for x in [128,12,120,122,13,32,22,42,212,213,162,204]]
12-element Array{Any,1}:
  true
  true
 false
  true
 false
 false
  true
 false
  true
 false
  true
 false

Phương pháp cải tiến cũng xử lý BigInt

selfDivides(BigInt(11111111111111111111111111111111111111112))
true

Tuy nhiên

selfDivides(BigInt(11111111111111111111111111111111111111113))
false

bởi vì

BigInt(11111111111111111111111111111111111111113) %3
1

2

C / C ++, 58 byte (44 trong cơ thể)

Gọi hành vi không xác định (xem bình luận)

int d(int i){int j=i;while(i&&!(j%(i%10)))i/=10;return!i;}

truefalse 1 và 0, nhưng vui lòng thêm một ký tự vào chữ ký để trả về a bool.

Và để giải trí, một phiên bản đệ quy nhỏ hơn nếu bạn cho phép các cuộc gọi có hình thức r(128,128)

Chỉnh sửa : Bây giờ không được phép bởi các quy tắc:

C / C ++, 53 byte (cơ thể 33)

int r(int i,int j){return!i||!(j%(i%10))&&r(i/10,j);}


2
Số 1 chết với ngoại lệ dấu phẩy động cho các số chứa 0 vì j% (i% 10) sẽ là bất hợp pháp đối với i% 10 = 0.
SBI

Một ngoại lệ điểm nổi ? Kỳ dị. Nó hoạt động hoàn hảo trên trình biên dịch của tôi nhưng bạn nói đúng, đó là hành vi không xác định. Không chắc lập trường PCG chung về UB phụ thuộc vào trình biên dịch là gì.
etheranger

"UB phụ thuộc trình biên dịch" là gì? Đó là UB hoặc không phải (và chia cho 0, hay đúng hơn là modulo zero, thực sự là UB). UB không nên được cho phép bởi vì nghĩa đen là bất cứ điều gì có thể xảy ra. Chúng tôi có thể giả định rằng chương trình của bạn sẽ chạy trên một cỗ máy sẽ nổ tung và giết chết mọi người xung quanh khi sự phân chia bằng 0 xảy ra. Bây giờ, tôi chắc chắn rằng bạn muốn tất cả chúng ta sống ... C có một khái niệm về hành vi được xác định thực hiện, nhưng chia cho số 0 không thuộc về điều đó.
Jeroen Mostert

2
@etheranger: Chia cho 0 được gọi là ngoại lệ dấu phẩy động vì lý do lịch sử: stackoverflow.com/questions/16928942/ Lời
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

2
@JeroenMostert: Tôi muốn nói hơn 90% tất cả các câu trả lời C trên trang web này gọi UB. Miễn là nó hoạt động với một số trình biên dịch trên một số máy, câu trả lời được coi là hợp lệ.
Dennis

2

R: 72 67 65

Chức năng

f<-function(a)!(anyNA(a%%(d=as.double(strsplit(paste0(a),"")[[1]])))|sum(a%%d))

Cảm ơn @AlexA và @plannapus vì sự tiết kiệm

Chạy thử nghiệm

i=c(128,12,120,122,13,32,22,42,212,213,162,204)
for(a in i){print(f(a))}
[1] TRUE
[1] TRUE
[1] FALSE
[1] TRUE
[1] FALSE
[1] FALSE
[1] TRUE
[1] FALSE
[1] TRUE
[1] FALSE
[1] TRUE
[1] FALSE

Tôi đếm 70 byte trong cơ thể chức năng của bạn hiện tại, không phải 72. Nhưng bạn có thể giảm xuống còn 67 bằng cách sử dụng d=as.double(strsplit(toString(a),"")[[1]]);!(anyNA(a%%d)|sum(a%%d)). :)
Alex A.

@AlexA. Cảm ơn. Một trong những nỗ lực đầu tiên của tôi wih R. Chắc chắn sẽ xem xét lại :)
MickyT

@MickyT paste(a)thay vì toString(a)cho kết quả tương tự.
plannapus

@plannapus Cảm ơn, mẹo nhỏ gọn gàng. Phải nhớ điều đó
MickyT

1

GNU Awk: 53 ký tự

Phần được tính:

for(;++i<=split($1,a,//);)r=r||!a[i]||v%a[i];return!r

Toàn bộ chức năng:

function self_divisible(v, i, r)
{
    for (; ++i <= split($1, a, //); )
        r = r || ! a[i] || v % a[i]

    return ! r
}

Vì Awk không có giá trị boolean, trả về 1 tor true và 0 cho false.


1

JavaScript (ES6) 30

Chức năng với một tham số số. Sử dụng% và phép trừ, không cần trường hợp đặc biệt '0' vì 0% 0 là NaN trong JavaScript.

Chỉnh sửa đã lưu 1 char thx DocMax

F=n=>[for(d of t=n+'')t-=n%d]&&t==n 

Chỉ để cho vui, lạm dụng quy tắc về việc không tính chữ ký hàm, 4

Check=(n,t=n+'',q=[for(d of t)n-=t%d])=>t==n

Kiểm tra trong bảng điều khiển FireFox / FireBug

console.log([128, 12, 120, 122, 13, 32, 22, 42, 212, 213, 162, 204]
.map(x=>+x + ' -> ' + F(x)).join('\n'))

Đầu ra

128 -> true
12 -> true
120 -> false
122 -> true
13 -> false
32 -> false
22 -> true
42 -> false
212 -> true
213 -> false
162 -> true
204 -> false

Tôi sẽ nói không với việc nhập một chuỗi.
Mathew Kirschbaum

1
Bảng điều khiển Firefox hài lòng với việc thay thế of(t=n+'')chỉ bằng cách of t=n+''lưu 1.
DocMax

1

PHP: 85 byte (64 byte trên cơ thể)

Để chức năng này hoạt động, chỉ cần truyền một chuỗi hoặc một số.

0 sẽ trả lại sai.

Mật mã:

function f($n,$i=0){for($n.='';$n[$i]&&$t=!($n%$n[$i++]););return$t&&$i==strlen($n);}

Xin vui lòng, KHÔNG THIẾT LẬP PARAMETER 2ND!

Javascript: 76 byte (61 byte trên cơ thể)

Đây là một bản viết lại của chức năng trước đó.

Không có nhiều thay đổi giữa cả hai phiên bản.

Đây là mã:

function f(n){for(i=0,n+='';n[i]/1&&(t=!(n%n[i++])););return t&&i==n.length}

Đa âm: Javascript + PHP 187 217 byte (76 84 byte mà không cần soạn sẵn):

Tại sao tôi làm nó?

Vì lý do và có lẽ vì tôi có thể!

Chỉ cần bỏ qua lỗi trên PHP: dù sao nó cũng hoạt động!
Không còn cần thiết, điều này đã được sửa bằng cách xóa 3 byte.

Đây là kiệt tác:

if('\0'=="\0"){function strlen($s){return $s['length'];}}
function toString(){return'';}
function f($n){for($i=0,$n=$n.toString();$n[$i]/1&&($t=!($n%$n[$i++])););return $t&&$i==strlen($n);}

Bạn có thể chạy mã này cả trên bảng điều khiển và trên trình thông dịch PHP!


Phiên bản cũ:

if('\0'=="\0"){function strlen($s){return $s['length'];}}
function s($s){return('\0'=="\0")?$s+'':str_replace('','',$s);}
function f($n,$i){for($i=0,$n=s($n);$n[$i]/1&&($t=!($n%$n[$i++])););return $t&&$i==strlen($n);}

"và chỉ truyền trong một tham số số". Nếu không có điều này, bạn có thể eval ($ x) và chuyển toàn bộ mã trong $ x
abc667

@ abc667 Xin lỗi, nhưng tôi không hiểu.
Ismael Miguel

1

Octave, 33 (39 bao gồm thiết lập chức năng)

Sử dụng chuyển đổi từ ma trận sang ma trận:

f=@(a)sum(mod(a./(num2str(a)-48),1))==0

Chia số theo từng phần tử cho ma trận X, trong đó X được tạo bằng cách chuyển đổi số thành chuỗi và trừ 48 để chuyển từ giá trị ASCII sang số một lần nữa. Lấy modulo 1 để lấy phần thập phân của mỗi phép chia, xác nhận rằng tất cả các số này đều bằng 0 (nếu có là NaN vì / 0, tổng sẽ là NaN và do đó không phải là 0).

Nhập mẫu bằng cách sử dụng www.octave-online.net:

f=@(a)sum(mod(a./(num2str(a)-48),1))==0
for j=[128,12,120,122,13,32,22,42,212,213,162,204]
f(j)
end

Đầu ra:

ans =  1
ans =  1
ans = 0
ans =  1
ans = 0
ans = 0
ans =  1
ans = 0
ans =  1
ans = 0
ans =  1
ans = 0

Làm thế nào chúng ta có thể kiểm tra điều này?
Ismael Miguel

octave-online.net - nhập định nghĩa mã từ phía trên và sau đó (ví dụ) f (128). Sẽ thêm đầu ra
Jørgen

Tôi đã tìm thấy trình biên dịch và thử nó trước khi hỏi. Nhưng nó dường như hoạt động tốt (ngoại trừ f(123), chia hết cho 1, 2 và 3). Nhưng nó không hoạt động cho các trường hợp thử nghiệm được cung cấp.
Ismael Miguel

1

MATLAB - 39 ký tự

function [b] = dividesSelf(i)
b=all(~mod(i,sscanf(num2str(i),'%1d')))
end

1

BASH - 117 ký tự

f(){ [[ $1 =~ 0 ]]&& return 0 || r=;n=$1;for((i=0;i<${#n};i++));do r=$(($r+${n}%${n:$i:1}));done;return $(($r==0));}

kiểm tra

for N in 128 12 120 122 13 32 22 42 212 213 162 204; do
  f $N
  echo "${N} ->  $?"
done

128 ->  1
12 ->  1
120 ->  0
122 ->  1
13 ->  0
32 ->  0
22 ->  1
42 ->  0
212 ->  1
213 ->  0
162 ->  1
204 ->  0

1

PHP - 74 71 64 Ký tự

Chơi gôn

function t($n){while($n>1){if(!($b=$n%10)||($n%$b)){return 0;}$n/=10;}return 1;}

Ít chơi gôn hơn:

function t($n){
    while($n>1){
        if( !($b=$n%10) || ($n%$b) )
            { return 0; }
        $n/=10;
    }
    return 1;
}

Kết quả kiểm tra:

(Mã)

$ans = array(128,12,120,122,13,32,22,42,212,213,162,204);
foreach($ans as $a)
{ echo "$a -> ".(t($a)?"True":"False").PHP_EOL; }

(Đầu ra)

128 -> True
12 -> True
120 -> False
122 -> True
13 -> False
32 -> True
22 -> True
42 -> True
212 -> True
213 -> True
162 -> False
204 -> False
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.