Apakah angka dapat dibagi oleh masing-masing digit?


47

Teman saya dan saya sedang mengerjakan laboratorium di kelas Ilmu Komputer AP kami dan memutuskan untuk membuat kode golf satu masalah karena kami masih memiliki setengah kelas gratis setelah kami selesai. Ini pertanyaannya:

Diberi angka n, apakah n dapat dibagi dengan masing-masing digitnya?

Sebagai contoh, 128 akan lulus tes ini - itu dapat dibagi dengan 1,2, dan 8. Setiap angka dengan nol secara otomatis mendiskualifikasi angka tersebut. Meskipun Anda dapat menggunakan bahasa lain dan memposting solusi jika Anda suka, kami sangat tertarik melihat bagaimana orang yang kompak dapat membuat program di Jawa, karena itu adalah bahasa yang kami gunakan di kelas. Sejauh ini, kami berdua memiliki 51. Ini kode saya saat ini:

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.

Persyaratan

Tanda tangan metode dapat menjadi apa pun yang Anda inginkan. Hitung saja fungsi tubuhnya. Namun, pastikan bahwa metode mengembalikan nilai boolean dan hanya meneruskan dalam satu parameter numerik (bukan string).

Kode harus dapat melewati semua kasus ini (agar tetap benar dengan arah pertanyaan asli, hanya nilai boolean true dan false yang dihitung jika bahasa mendukung booleans. Jika dan hanya jika bahasa Anda tidak memiliki variabel boolean Anda dapat mewakili false dengan 0 dan true dengan sembarang bilangan nol (lebih disukai 1 atau -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

Juga, kami tidak menghitung spasi putih, jadi jangan ragu untuk melakukan hal yang sama, kecuali spasi putih sangat penting untuk kerja program (jadi baris baru di Jawa tidak masuk hitungan, tetapi satu ruang antara intdan x=1tidak dihitung.) Semoga beruntung !


18
Selamat datang di PPCG! Beberapa saran: 1. Tidak menghitung spasi putih fungsional adalah ide yang buruk. Setiap jawaban yang ditulis di Whitespace akan secara otomatis menang. 2. Haruskah kiriman kami mencetak / mengembalikan truedan falseatau apakah nilai kebenaran / kepalsuan juga baik? 3. javaTag tidak benar-benar berlaku di sini, karena tantangan itu sendiri tidak terkait dengan Java.
Dennis

Baik. maaf untuk masalahnya. Hanya untuk menjernihkannya, apakah Anda menganggap ruang dalam 'int p = n' berfungsi, karena saya tidak sebelumnya. Saya akan memperbaiki masalah lain yang Anda tunjukkan.
Mathew Kirschbaum

5
Semua spasi putih yang diperlukan agar kode berfungsi berfungsi.
FryAmTheEggman

Oke, terima kasih atas tanggapannya!
Mathew Kirschbaum

1
@ RickyDemer: karena 0 akan menjadi input yang luar biasa dalam kasus itu (itu satu-satunya angka dengan 0digit yang merupakan kelipatan dari masing-masing), saya membayangkan sebagian besar jawaban hanya akan lebih lama dengan cara yang tidak menarik untuk menyertakan cek untuk itu. Jadi saya suka masalah yang ditimbulkan oleh judul lebih baik (dapat dibagi dengan digit-digitnya, daripada kelipatan digitnya, yang tidak termasuk 0).
Jeroen Mostert

Jawaban:


23

Perl 6, 13

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

Menggunakan variabel implisit $_- $_ %% .comb.allsetara dengan $_ %% all($_.comb). %%adalah operator "habis dibagi", dan combtanpa argumen tambahan mengembalikan daftar karakter dalam sebuah string. Sebagai contoh, jika argumennya adalah 123, maka fungsinya mengevaluasi

123 %% all(123.comb)

yang mana

123 %% all(1, 2, 3)

persimpangan autothreading membuatnya

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

yang mana

all(True, False, True)

yang salah dalam konteks boolean karena ini merupakan persimpangan "semua" dan jelas tidak semua elemennya benar.

Seharusnya dimungkinkan untuk memaksa nilai balik ke Booldan menyembunyikan persimpangan dari penelepon dengan membuat tanda tangan fungsi sub golf($_ --> Bool()), tetapi paksaan dalam tanda tangan fungsi belum berfungsi di Rakudo. Nilai kembali masih benar atau salah, hanya saja tidak Trueatau False.


Jika Anda ingin mengembalikannya, Booltambahkan saja soke bagian depan kode so$_%%.comb.all.
Brad Gilbert b2gills

21

C # dan Sistem.Linq - 26/40

Sesuai aturan, tidak termasuk metode deklarasi itu sendiri.

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

Menunjukkan itu sekali lagi, C # adalah pilihan terbaik ketika Java sedang dipertimbangkan ... I nak, I nak!

Sayangnya, fungsi ini (dan banyak di jawaban lain) tidak akan menghasilkan hasil yang benar untuk input negatif. Kami dapat memperbaiki ini, tetapi solusinya kehilangan banyak daya tariknya (dan panjangnya mencapai 46 karakter):

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

Sunting : mencukur satu karakter dengan saran Tim.

Sunting : dengan pengenalan anggota bertubuh ekspresi di C # 6, kita dapat menguraikan ini lebih jauh dengan memotong return:

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

untuk total 26 karakter (menurut saya, =>seharusnya tidak dimasukkan lebih dari kawat gigi akan menjadi). Versi yang menangani angka negatif juga dapat dipersingkat.


Mengapa .0? Tidak perlu apa pun selain modulus integer.
Peter Taylor

3
@PeterTaylor: Ada jika Anda ingin program terpendek - i % 0dengan ibilangan bulat memberikan a DivideByZeroException.
Jeroen Mostert

2
Dan dengan ganda itu memberi NaN! Bagus!
Peter Taylor

2
48dsama dengan 48.0, tetapi satu karakter kurang (d untuk ganda).
Tim S.

1
@StuartLC: lambdas bukan metode; ruang lingkup mereka berbeda, jadi saya pikir itu membengkokkan aturan terlalu jauh. Tetapi karena C # 6 (yang mana jawabannya mendahului), kami memiliki anggota yang berekspresi, yang memungkinkan kami untuk mempersingkat definisi. Untuk kasus negatif, kami tidak dapat menggunakan &, justru karena &tidak mengalami hubungan pendek - Anda akan mendapatkan pembagian dengan pengecualian nol pada %. Kita dapat memperbaikinya dengan membuatnya menjadi ganda (dengan d), tetapi kemudian kita kehilangan satu karakter lagi.
Jeroen Mostert

18

APL ( 13 11)

(ternyata tanda kurung tidak masuk hitungan)

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

Penjelasan:

  • ⍎¨⍕⍵: mengevaluasi setiap karakter dalam representasi string
  • ⍵|⍨: untuk masing-masing, cari modulo dan
  • 0∧.=: lihat apakah semua itu sama dengan 0

Testcases:

      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 bisa lakukan X%0? tanpa melempar?
Pengoptimal

@Optimizer: ya. 0|Xmemberi X.
marinus

Manis. Juga jawaban Anda adalah 11 byte, bukan 13
Pengoptimal

9
Hanya APL yang tidak akan memberikan kesalahan pada modulo oleh 0, dan crash saat mengevaluasi non-bool sebagai bool;)
FryAmTheEggman

3
Satu karakter lebih pendek dengan kereta bukannya dfn:(0∧.=⍎¨∘⍕|⊢)
ngn

14

Python 2: 43 karakter

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

Cek apakah nomor memiliki sisa nol modulo digitnya, dan output negasi itu. Nol digit ditangani dengan aneh: karena komputasi %0menyebabkan kesalahan, digit 0diganti dengan .3, yang tampaknya selalu memberikan hasil bukan nol karena ketidakakuratan floating point.

Badan fungsi adalah 32 karakter.


14

Perl - 27 byte

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

Tidak menghitung fungsi tanda tangan, seperti yang diinstruksikan.

Penggunaan sampel:

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

Output sampel:

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

Mengatasi spesifikasi masalah: "Hanya nilai true dan false boolean yang dihitung. Nilai kebenaran / falsey tidak dihitung."

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

Output:

1
""

'Benar' dan 'Salah' didefinisikan sebagai 1dan "".

Erratum:
Seperti yang ditunjukkan oleh Brad Gilbert , perl mendefinisikan true sebagai skalar yang merupakan integer 1dan string "1"secara bersamaan, dan false sebagai skalar yang merupakan integer 0dan string ""secara bersamaan.


Ini dapat dipersingkat dengan tidak menggunakan $_: pop=~s///ger<1. Saya tidak tahu apakah OP akan menyetujui itu 1dan ""merupakan hasil yang valid. Jika tidak, maka bisa diperbaiki dengan dua byte lagi: cukup tambahkan |0.
hvd

perl -pe'$_=s/./!$&||$_%$&/ger<1|0'adalah 26 byte termasuk tanda |0dan -p. Anda tidak harus menggunakan fungsi.
hmatt1

1
Sebenarnya nilai True dan False lebih seperti dualvar(1,'1')dan dualvar(0,'').
Brad Gilbert b2gills

1
@BradGilbert Itu menarik. Saya cukup akrab dengan perlguts, tetapi saya tidak menyadari bahwa benar dan salah adalah casing khusus. Mereka sebenarnya 'skalar tiga', ditandai sebagai SVIV(int), SVNV(ganda), dan SVPV(string).
Primo

1
Sebenarnya saat pertama kali Anda menggunakan string sebagai angka atau angka sebagai string, variabel akan dimodifikasi untuk menampung data tambahan itu. Itulah sebabnya Anda hanya mendapat peringatan saat pertama kali Anda menggunakan 'abc'angka (dengan asumsi Anda telah use warnings;mengaktifkannya.)
Brad Gilbert b2gills

13

CJam, 11 10 byte

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

Ini mendefinisikan fungsi bernama Fdan membuang blok dari tumpukan.

Cobalah online.

Uji kasus

$ 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]

Bagaimana itu bekerja

_      " 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.                                        ";

Apakah CJam memiliki fitur yang Anda gunakan untuk solusi 10-byte saat pertanyaan itu ditulis?
lirtosiast

@ ThomasKwa: Ya, benar. Saya telah menguji kode dalam versi 0.6.2, yang dirilis pada Juli 2014.
Dennis

12

JavaScript ES6, 39 32 28 byte

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

Terima kasih core1024 untuk saran untuk mengganti (""+v).split("")dengan [...""+v], dan openorclose untuk menyarankan penggunaan everyfungsi.

Jawabannya saat ini tidak mengandung sedikit pun kode saya: O

Solusi sebelumnya

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

==""bukan cara yang valid untuk memeriksa apakah array kosong, karena [""]==""kembali true, tetapi array dijamin mengandung string yang tidak kosong, jadi array ini berfungsi di sini.

Sisanya adalah konversi tipe steno yang cukup standar dalam JavaScript.


1
Anda dapat menyimpan beberapa karakter dengan menggantinya (""+v).split("")dengan [...""+v].
core1024

1
Mengapa tidak menggunakan everymetode ini? v=>[...""+v].every(x=>v%x<1);
openorclose

@openorclose: Terima kasih. Tidak pernah memiliki kesempatan untuk menggunakannya di JS, jadi saya tidak pernah berpikir untuk mencari fungsi tersebut.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

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

@ l4m2 Sejak v%0kembali NaNdan NaN == false, maka dalam nomor kasus Anda yang berisi 0, seperti 10, dapat kembali true.
Shieru Asakoto

9

Java 8, 46 Bytes (metode tubuh)

Menggunakan Jeroen Mostert yang mengkonversi ke trik ganda.

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

8

Pyth, 12 byte

!f|!vT%vzvTz

Ini memfilter karakter dalam string menjadi nol ( !vT) atau tidak membagi input ( %vzvT), kemudian mengambil logika bukan dari daftar yang dihasilkan.

Coba di sini.


Tidak, saya baik-baik saja jika suatu fungsi tidak digunakan. Saya hanya ingin menunjukkan kepada siapa saja yang menggunakan fungsi yang tidak perlu mereka hitung deklarasi, dan hanya kode di dalamnya.
Mathew Kirschbaum

8

Ruby, 44 byte (badan fungsi: 37)

Mungkin memiliki potensi untuk bermain golf lebih lanjut.

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

Input diambil melalui fungsi f. Contoh penggunaan:

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

1
Anda dapat mengubah .to_ike .hex, karena angka satu digit sama dengan basis 16, dan dapat berubah ==0menjadi <1.
histokrat

8

Python - 59 50 49 47 byte

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

Saya yakin ada cara yang lebih cepat ... oh well.

Sunting - Terima kasih kepada FryAmTheEggman untuk tips golfnya.

Sunting 2 - FryAmTheEggman mungkin telah menulis ini pada saat ini, oops

Sunting 3 - Angkat tangan jika Anda bahkan tidak tahu genexps adalah sesuatu. ...Hanya aku?


Oh terima kasih banyak! Saya selalu lupa tentang semua hal itu. (Saya juga tidak menyadari bahwa Anda bisa kurang dari karakter dengan cara itu.)
Kasran

Oh, membalik logika juga tampaknya untuk mempersingkat sedikit: f=lambda n:all([c>'0'and 0==n%int(c)for c in`n`]). Dan tidak ada masalah :)
FryAmTheEggman

Oh, saya tidak menyadari ada bahkan adalah sebuah allmetode.
Kasran

Akan 1>n%int(c)bekerja
Sp3000

3
Mengapa daftar-pemahaman? Menggunakan genexp: all(c>'0'and 0==n%int(c)for c in`n`)tidak persis sama, dengan 2 char lebih sedikit dan bahkan menyimpan alokasi daftar.
Bakuriu

8

Pyth 11

!f%Q|vT.3`Q

Ini menggabungkan jawaban @ isaacg dan @ xnor . Ini memfilter digit dari input dengan memeriksa nilai input % (eval(current_digit) or .3). Kemudian memeriksa apakah string yang dihasilkan kosong atau tidak.

Datang di varian lain dengan panjang yang sama:

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

Cobalah online.


5

Bash + coreutils, 44 byte

Definisi fungsi penuh adalah:

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

Saya tidak yakin bagaimana cara menilai ini karena fungsi shell biasanya menggunakan satu set {}atau ()untuk memuat fungsi body. Saya menemukan di sini saya juga bisa menggunakan ganda (())untuk memuat fungsi tubuh yang menyebabkan ekspansi aritmatika yang saya butuhkan di sini. Jadi untuk saat ini saya menghitung hanya sepasang kurung itu - diskusi lebih lanjut tentang ini disambut baik.

Keluaran:

$ 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 - tidak jelas bagi saya apakah 1 dan 0 dapat diterima atau jika saya harus mencetak true/ false?
Digital Trauma

4

J - 14 char

Fungsi tubuh adalah bagian setelah =:. Jika kita ingin meminimalkan jumlah karakter untuk seluruh fungsi, itu adalah 15 karakter */@(0=,.&.":|]).

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

,.&.":adalah cara terpendek dalam J untuk memperluas sebagai angka ke dalam daftar angka desimalnya: konversikan ke string, pisahkan digit, dan ubah setiap digit kembali menjadi angka. ,.&.":|]mengambil nomor input ( ]) modulo ( |) digit tersebut. 0*/@:=mengembalikan true jika semua hasil adalah 0, yang lain memberikan false.

   f 162
1
   f every 204 212 213
0 1 0

3

Java - 121 102 97 79 78 byte

Saya hanya tahu ini akan musnah nanti. Baiklah.

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

Aku akan kembali.


1
Anda sekarang dapat memberi nama fungsi Anda apa pun yang Anda inginkan. Saya mengubah aturan sehingga Anda hanya menghitung perhitungan di dalam fungsi aktual, tetapi fungsi tersebut harus mengembalikan tipe boolean. Jadi saat ini di 86 karakter.
Mathew Kirschbaum

3

Haskell - 100 54 38

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

Masih belajar, kritik dihargai


Saya punya komentar di sini, tapi entah bagaimana saya tidak sengaja menghapusnya ... Bagaimanapun, beberapa saran: 1) Drop lengths, mereka tidak perlu. 2) Ganti tdengan definisinya. 3) elem y stidak perlu. 4) /='0'dapat dipindahkan ke filter kiri, di tempat elem y s. 5) Dalam hal ini, /='0'sama dengan >'0', karena setiap huruf adalah angka. 6) Masukkan modbackticks, sehingga menjadi infix. 7) Letakkan semuanya dalam satu baris.
Zgarb

1 dan 3 berasal dari ketika saya mencoba melakukannya dengan cara yang berbeda dan menyelamatkan kode. Terima kasih atas tipsnya.
globby

1
saran saya: alih-alih menggunakan s==filter(...)sAnda harus menggunakan all(...)s. sekarang, karena shanya muncul sekali dalam ekspresi, Anda dapat menggantinya dengan definisi dan dropnya where. juga, bukannya ==0Anda bisa menggunakan <1.
haskeller bangga

peningkatan besar dari versi pertama!
haskeller bangga

Saya pikir Anda masih bisa kehilangan satu byte jika Anda ganti all(\y->...)$show xdengan and[...|y<-show x].
Zgarb

2

CJam, 15 byte

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

Ini adalah blok, hal yang paling dekat dengan fungsi di CJam. Saya hanya menghitung tubuh (yaitu menghilangkan kawat gigi). Anda dapat menggunakannya sebagai berikut:

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

Atau jika Anda ingin menguji serangkaian input, Anda bisa melakukannya

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

Blok itu pergi 0 (falsy) atau 1(benar) di tumpukan untuk menunjukkan hasilnya. (CJam tidak memiliki tipe Boolean.)

Uji di sini.

Penjelasan:

_               "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.";

Alternatif, juga 15 byte

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

Penjelasan

: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!}

{}adalah hal yang paling dekat dengan fungsi di CJam. Saya hanya menghitung tubuh fungsi

Gunakan seperti ini:

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

Untuk mendapatkan 1(jika nomornya dapat dibagi) atau0 (jika jumlahnya tidak dapat dibagi dengan digit-digitnya).

Cobalah online di sini

Penjelasan

_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";

Saya mungkin kehilangan sesuatu, tetapi setelah cepat membaca tentang CJam, beberapa hal tampaknya tidak masuk akal: bagaimana cara Abmembagi angka? Tampaknya hanya mengubahnya menjadi basis 10. Juga, bagaimana% tahu mod dengan angka, dan bukan hanya angka berikutnya, karena tampaknya angka berikutnya akan berada di tumpukan berikutnya?
Mathew Kirschbaum

Menjawab semua pertanyaan Anda akan sulit. Akan sangat mudah dipelajari dengan menempatkan ed setelah setiap karakter dalam kode. Coba jalankan128{ed_edAedbedf{ed_ed{ed%ed}1ed?ed}ed1edbed!ed}~
Pengoptimal

1
Jawaban untuk pertanyaan-pertanyaan tertentu: melakukan basis 10 memberikan array dari basis 10 angka yang dikonversi, yang merupakan digit sendiri dalam kasus ini. %cukup ambil dua angka terakhir (dalam hal ini) dan hitung mod. Dua angka terakhir di sini adalah angka dan digit aktual (selalu)
Pengoptimal

Oke, terima kasih atas sarannya!
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 tidak memiliki tipe boolean. Semoga itu berhasil. Saya juga menggunakan parameter kedua untuk meneruskan salinan nomor asli melalui tumpukan, tetapi definisi bisa apa saja. Untuk mendapatkan hasil yang benar, Anda hanya perlu memanggil fungsi dengan nilai yang sama untuk kedua parameter ( d(128, 128)).

SUNTING: Suntingan yang disarankan diterapkan oleh pengguna anonim


Lihatlah codegolf.stackexchange.com/review/suggested-edits/17160 , seseorang memberi Anda beberapa saran bermain golf
Justin

Khususnya melanggar aturan. Satu parameter.
edc65

Yup, posting ini sebenarnya mengapa saya memutuskan untuk membuat aturan itu, karena tampaknya tidak benar bahwa pengguna harus melakukan duplikasi daripada program.
Mathew Kirschbaum

Saya kira saya harus menambahkan fungsi wrapper. Apakah deklarasi fungsi itu menambah jumlah byte?
MarcDefiant

2

C11 - 44 Bytes di badan fungsi

Versi C lain, non rekursif dan tanpa pengecualian floating point.

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

Ini juga akan berfungsi dalam C ++, Java, dan sebagian besar bahasa mirip-C lainnya.

Diedit untuk memasukkan peningkatan komentar primo.


1
Versi yang mengkompilasi di Java (1.7.0_45-b18):, int n=i;for(;i%10>0&&n%(i%10)<1;i/=10);return i<1;satu byte lebih pendek dari kode OP.
Primo

2

Julia 32 25 23

Ditingkatkan menggunakan digit

Juga memperbaiki masalah dengan angka negatif

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

Metode lama

Semua digit dibagi jika jumlah semua sisanya adalah 0. Seperti yang lain, memiliki masalah dengan angka negatif.

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

Keluaran

[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

Metode yang ditingkatkan juga menangani BigInt

selfDivides(BigInt(11111111111111111111111111111111111111112))
true

namun

selfDivides(BigInt(11111111111111111111111111111111111111113))
false

karena

BigInt(11111111111111111111111111111111111111113) %3
1

2

C / C ++, 58 byte (44 dalam tubuh)

Meminta Perilaku Tidak Terdefinisi (lihat komentar)

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

truedan false yang 1 dan 0, tetapi merasa bebas untuk menambahkan satu karakter ke tanda tangan untuk kembali bool.

Dan untuk bersenang-senang, versi rekursif yang lebih kecil jika Anda mengizinkan panggilan formulir r(128,128)

Sunting : Sekarang tidak diizinkan oleh aturan:

C / C ++, 53 byte (33 dalam tubuh)

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


2
# 1 mati dengan pengecualian floating point untuk angka yang mengandung 0 karena j% (i% 10) akan ilegal untuk i% 10 = 0.
SBI

Sebuah floating point pengecualian? Aneh. Ini berfungsi dengan baik pada kompiler saya tetapi Anda benar, itu perilaku yang tidak terdefinisi. Tidak yakin apa sikap PCG umum tentang UB yang bergantung pada compiler.
etheranger

Apa itu "UB yang bergantung pada kompiler"? Entah itu UB atau bukan (dan pembagian dengan nol, atau lebih tepatnya modulo nol, memang UB). Seharusnya UB tidak diperbolehkan karena apa pun bisa terjadi. Kami mungkin menganggap program Anda akan berjalan pada mesin yang akan meledak dan membunuh semua orang di sekitarnya ketika pembagian dengan nol terjadi. Sekarang, saya yakin Anda ingin kita semua hidup ... C memang memiliki konsep perilaku yang ditentukan implementasi, tetapi membaginya dengan nol tidak termasuk di dalamnya.
Jeroen Mostert

2
@etheranger: Division by 0 disebut pengecualian floating point karena alasan historis: stackoverflow.com/questions/16928942/…
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

2
@ JoeroenMostert: Saya akan mengatakan lebih dari 90% dari semua jawaban C di situs ini memanggil UB. Selama ini bekerja dengan beberapa kompiler pada beberapa mesin, jawabannya dianggap valid.
Dennis

2

R: 72 67 65

Fungsinya

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

Terima kasih kepada @AlexA dan @plannapus untuk penghematannya

Uji coba

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

Saya menghitung 70 byte di tubuh fungsi Anda saat ini, bukan 72. Tapi Anda bisa mendapatkannya hingga 67 menggunakan d=as.double(strsplit(toString(a),"")[[1]]);!(anyNA(a%%d)|sum(a%%d)). :)
Alex A.

@AlexA. Terima kasih. Salah satu upaya pertama saya dengan R. Pasti akan mengunjungi kembali :)
MickyT

@MickyT paste(a)bukannya toString(a)memberikan hasil yang sama.
plannapus

@plannapus Terima kasih, trik kecil yang rapi. Harus ingat itu
MickyT

1

GNU Awk: 53 karakter

Bagian yang dihitung:

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

Seluruh fungsi:

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

    return ! r
}

Karena Awk tidak memiliki nilai boolean, mengembalikan 1 tor true dan 0 untuk false.


1

JavaScript (ES6) 30

Berfungsi dengan satu parameter numerik. Menggunakan% dan pengurangan, tidak perlu huruf khusus '0' karena 0% 0 adalah NaN dalam JavaScript.

Edit Disimpan 1 char thx DocMax

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

Hanya untuk bersenang-senang, menyalahgunakan aturan tentang tidak menghitung tanda tangan fungsi, 4

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

Uji di konsol FireFox / FireBug

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

Keluaran

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

Saya akan mengatakan tidak untuk memasukkan string.
Mathew Kirschbaum

1
Konsol Firefox senang dengan penggantian of(t=n+'')hanya of t=n+''dengan menghemat 1.
DocMax

1

PHP: 85 byte (64 byte pada badan)

Agar fungsi ini berfungsi, cukup masukkan string atau angka.

0 akan kembali dengan benar salah.

Kode:

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

Tolong, JANGAN TETAP PARAMETER 2ND!

Javascript: 76 byte (61 byte pada tubuh)

Ini adalah penulisan ulang fungsi sebelumnya.

Tidak banyak berubah di antara kedua versi.

Ini kodenya:

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

Polyglot: Javascript + PHP 187 217 byte (76 84 byte tanpa boilerplate):

Kenapa saya membuatnya?

Karena alasan dan mungkin karena aku bisa!

Abaikan saja kesalahan pada PHP: tetap berfungsi!
Tidak lagi diperlukan, ini diperbaiki dengan menghapus 3 byte.

Inilah mahakarya:

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

Anda dapat menjalankan kode ini baik di konsol Anda maupun pada penerjemah PHP!


Versi lama:

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

+ msgstr "dan hanya lewat dalam satu parameter numerik". Tanpa ini, Anda dapat eval ($ x) dan mengirimkan seluruh kode dalam $ x
abc667

@ abc667 Maaf, tapi saya tidak mengerti.
Ismael Miguel

1

Oktaf, 33 (39 termasuk pengaturan fungsi)

Menggunakan konversi numerik ke matriks:

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

Bagilah angka secara elemen dengan matriks X, di mana X dibuat dengan mengubah angka menjadi string dan kurangi 48 untuk beralih dari nilai ASCII ke angka lagi. Ambil modulo 1 untuk mendapatkan bagian desimal dari setiap divisi, konfirmasikan bahwa semua ini nol (jika ada NaN karena / 0, jumlahnya akan menjadi NaN dan karenanya bukan nol).

Masukan sampel menggunakan 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

Keluaran:

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

Bagaimana kita bisa menguji ini?
Ismael Miguel

octave-online.net - masukkan definisi kode dari atas dan kemudian (misalnya) f (128). Akan menambah keluaran
Jørgen

Saya telah menemukan kompiler dan mencobanya sebelum bertanya. Tetapi tampaknya berfungsi dengan baik (kecuali untuk f(123), yang dapat dibagi oleh 1, 2 dan 3). Tetapi itu bekerja untuk kasus-kasus uji yang disediakan.
Ismael Miguel

1

MATLAB - 39 karakter

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

1

BASH - 117 karakter

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

tes

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 Karakter

Golf:

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

Kurang Golf:

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

Hasil tes:

(Kode)

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

(Keluaran)

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