Bir sayı, her basamağı tarafından bölünebilir mi?


47

Arkadaşım ve ben AP Computer Science sınıfımızdaki bir laboratuarda çalışıyorduk ve bir tanesini problemleri kodlamaya karar verdik, çünkü sınıfımızın yarısını bitirdikten sonra hala sınıfın yarısı boş kaldı. İşte soru:

Bir sayı n verildiğinde, n rakamlarının her biri tarafından bölünebilir mi?

Örneğin, 128 bu testi geçecek - 1,2 ve 8 ile bölünebilir. Sıfır olan herhangi bir sayı otomatik olarak sayıyı diskalifiye eder. İsterseniz diğer dilleri kullanabilir ve onlarla çözüm gönderebilirsiniz, ancak sınıfta kullandığımız dil olduğu gibi insanların Java'da programı nasıl kompakt hale getirebileceğini görmekle ilgileniyoruz. Şimdiye kadar ikimizde 51 var. İşte benim kodum:

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.

Gereksinimler

Yöntem imzası, istediğiniz ne olabilir. Sadece fonksiyon gövdesini say. Ancak, yöntemin bir boolean değeri döndürdüğünden ve yalnızca bir sayısal parametrede (bir dize değil) geçtiğinden emin olun .

Kod, tüm bu durumları geçebilmelidir (orijinal sorunun yönlerine sadık kalabilmek için , dil booleanleri destekliyorsa , yalnızca boolean doğru ve yanlış değerler sayılır. sıfırla yanlış temsil edebilir ve sıfır olmayan bir tamsayıyla true (tercihen 1 veya -1) olabilir:

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

Ayrıca, boşlukları saymadık, bu yüzden programın çalışması için boşluklar gerekli olmadıkça aynı şeyi yapmaktan çekinmeyin (Java'daki yeni satırlar sayılmaz, ancak aralarındaki intve arasındaki tek bir boşluk var x=1.) İyi şanslar !


18
PPCG'ye Hoşgeldiniz! Birkaç öneri: 1. İşlevsel boşlukları saymamak kötü bir fikirdir. Boşluk ile yazılmış herhangi bir cevap otomatik olarak kazanacaktır. 2. Olmalı ilgili gönderim baskı / dönüş trueve falseya vardır truthy / falsy değerler TAMAM yanı? 3. javaEtiket burada gerçekten geçerli değildir, çünkü meydan okuma Java ile ilişkili değildir.
Dennis

Tamam. sorunlar için özür dilerim. Sadece temizlemek için, 'int p = n' içindeki boşluğun işlevsel olduğunu düşünür müsün, çünkü daha önce yapmadım. Belirtdiğin diğer sorunları çözeceğim.
Mathew Kirschbaum

5
Kodun çalışması için gereken tüm boşluklar işlevseldir.
FryAmTheEggman

Tamam, cevap için teşekkürler!
Mathew Kirschbaum

1
@RickyDemer: 0, bu durumda istisnai bir girdi olacağından 0(her birinin bir katı olan rakam olan tek sayıdır ), çoğu cevabın, bir çek eklemek için ilginç olmayan bir şekilde daha uzun olacağını tahmin ediyorum. Bu yüzden, başlığın ortaya koyduğu problemi daha iyi seviyorum (rakamın bir katı olmak yerine, 0 rakamı hariç olmak üzere rakamlarıyla bölünebilir).
Jeroen Mostert

Yanıtlar:


23

Perl 6, 13

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

Kapalı değişkeni kullanır $_- $_ %% .comb.alleşittir $_ %% all($_.comb). %%"bölünebilir" işlecidir ve combek bir argüman olmadan bir dizedeki karakterlerin listesini döndürür. Örnek olarak, eğer argüman 123 ise, fonksiyon değerlendirir

123 %% all(123.comb)

hangisi

123 %% all(1, 2, 3)

kavşak autothreading yapar

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

hangisi

all(True, False, True)

Bu, boolean bağlamında yanlış, çünkü bu bir "hepsi" kavşağı ve açıkça tüm unsurları doğru değil.

Boolİşlev imzasını yaparak geri dönüş değerini zorlamak ve bağlantıyı arayanlardan gizlemek mümkün olmalıdır sub golf($_ --> Bool()), ancak işlev imzalarındaki zorlamalar henüz Rakudo'da çalışmaz. Dönüş değeri hala doğru ya da yanlış, sadece Trueya da değil False.


Bunu yapmak istiyorsanız, Boolsadece sokodun önüne bir ekleme ekleyin so$_%%.comb.all.
Brad Gilbert,

21

C # ve Sistem.Linq - 26/40

Kurallara göre, yöntem bildiriminin kendisi sayılmaz.

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

Bir kez daha gösteriliyor, C # göz önüne alındığında, C # göze çarpıyorsa üstün bir seçimdir.

Ne yazık ki, bu işlev (ve diğer birçok cevapta) negatif girdi için doğru sonuçlar vermeyecektir. Bunu düzeltebiliriz, ancak çözüm cazibesinin çoğunu kaybeder (ve 46 karakter uzunluğunda olur):

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

Düzenleme : Tim'in önerisiyle bir karakter traş oldu.

Düzenleme : İfade gövdeli üyelerin C # 6 ile tanıtılmasıyla, aşağıdakileri keserek daha fazla bilgi verebiliriz return:

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

toplam 26 karakter için (bence, =>parantezden daha fazla dahil edilmemelidir). Negatif sayılarla işlem yapan sürüm benzer şekilde kısaltılabilir.


Neden .0? Tamsayılı modülden başka bir şeye gerek yoktur.
Peter Taylor

3
@PeterTaylor: - Eğer en kısa programı istiyorsanız yoktur i % 0ile ibir tamsayı bir verir DivideByZeroException.
Jeroen Mostert

2
Ve bir çift ile NaN verir! Güzel!
Peter Taylor

2
48daynı 48.0, ancak bir daha az karakter (d için çift).
Tim S.

1
@StuartLC: lambdas yöntem değildir; kapsamları farklı, bu yüzden kuralları çok fazla esnetiyor bence. Fakat C # 6'dan beri (ki bu cevap daha önce gelmiyor), tanımı kısaltmamıza izin veren ifadeli üyelerimiz var. Olumsuz durum için &, kesinlikle kullanamayız , çünkü &kısa devre yapmaz - üzerinde sıfır istisnasına sahip bir bölünme elde edersiniz %. Bunu iki katına çıkararak düzeltebiliriz d, ancak sonra yine bir karakter kaybettik.
Jeroen Mostert

18

APL ( 13 11)

(görünüşe göre parantez sayılmaz)

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

Açıklama:

  • ⍎¨⍕⍵: her karakteri karakter dizgesinde değerlendirebilir.
  • ⍵|⍨: her biri için, onun modülünü bul ve
  • 0∧.=: hepsinin eşit olup olmadığını görün 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 yapabilir X%0? atmadan mı?
Doktor

@Optimizer: evet. 0|Xverir X.
marinus

Tatlı. Ayrıca cevabınız 11 bayt, 13 değil
Optimizer

9
Yalnızca APL
moduloda

3
(0∧.=⍎¨∘⍕|⊢)
Dfn

14

Python 2: 43 karakter

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

Numaranın sıfır kalan kalıntısı olup olmadığını kontrol eder, rakamlarını değiştirir ve bunun ihmalini verir. Sıfır basamaklar garip bir şekilde işlenir: hesaplama %0bir hataya neden olduğu için, sayılarla 0değiştirilir; .3kayan nokta yanlışlıkları nedeniyle her zaman sıfır olmayan bir sonuç verir.

İşlev gövdesi 32 karakterdir.


14

Perl - 27 bayt

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

İşlev imzasını belirtildiği gibi saymamak.

Örnek Kullanım:

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

Örnek çıktı:

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

Sorun şartname hitaben: "Yalnızca mantıksal doğru ve yanlış değerler saymak Truthy / Falsey değerleri yoktur. Not say."

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

Çıktılar:

1
""

'True' ve 'Yanlış' olarak tanımlanan 1ve "".

Erratum:
As Brad Gilbert haklı olarak işaret ettiği , perl tanımlar gerçek tamsayı hem bir sayısal alan olarak 1ve dize "1"aynı anda ve false tamsayı hem bir sayısal alan olarak 0ve dize ""aynı anda.


Bu kullanmayan kısaltılabilir $_: pop=~s///ger<1. OP'nin buna katılıp katılmayacağını 1ve ""geçerli sonuçlar olup olmadığını bilmiyorum . Değilse, iki bayt ile düzeltilebilir: sadece ekleyin |0.
hvd

perl -pe'$_=s/./!$&||$_%$&/ger<1|0'|0ve -pbayrağını içeren 26 bayttır . Bir işlev kullanmak zorunda değilsiniz.
hmatt1

1
Aslında Doğru ve Yanlış değerleri daha fazla dualvar(1,'1')ve benzerdir dualvar(0,'').
Brad Gilbert,

1
@BradGilbert Bu ilginç. Ben perlgutlara makul derecede aşinayım, ama doğru ve yanlışın özel bir kasa olduğunu bilmiyordum . Aslında, SVIV(int), SVNV(double) ve SVPV(string) ile işaretlenmiş 'üçlü skalarlar' .
primo

1
Aslında bir dizeyi sayı olarak veya dizeyi sayı olarak ilk kez kullandığınızda, değişken bu ek verileri tutacak şekilde değiştirilir. Bu yüzden sadece ilk defa ilk defa kullandığınızda 'abc'( use warnings;etkinleştirmiş olduğunuz varsayılarak) bir uyarı alırsınız .
Brad Gilbert b2gills 28:14

13

CJam, 11 10 bayt

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

Bu, adlandırılmış bir işlevi tanımlar Fve bloğu yığından atar.

Çevrimiçi deneyin.

Test durumları

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

Nasıl çalışır

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

CJam, soru yazılırken 10 baytlık çözüm için kullandığınız özelliklere sahip miydi?
lirtosiast,

@ThomasKwa: Evet yaptı. Kodu Temmuz 2014’de yayımlanan 0.6.2 sürümünde test ettim.
Dennis

12

JavaScript ES6, 39 32 28 bayt

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

Teşekkür yerine öneri için core1024 (""+v).split("")ile [...""+v]kullanılmasını öneren ve openorclose everyfonksiyonu.

Cevap şu anda kodumun bir bitini içermiyor: O

Önceki çözüm

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

==""bir dizinin boş olup olmadığını kontrol etmek için geçerli bir yol değildir, çünkü [""]==""döndürür true, ancak dizi boş olmayan bir dize içerme garantisidir, bu nedenle burada çalışır.

Gerisi JavaScript'te oldukça standart kestirme tip dönüşümüdür.


1
Sen değiştirerek bazı characteras kaydedebilirsiniz (""+v).split("")ile [...""+v].
core1024,

1
Neden everyyöntemi kullanmıyorsun ? v=>[...""+v].every(x=>v%x<1);
openorclose

@ openorclose: Teşekkürler. JS'de kullanma şansım hiç olmadı, bu yüzden böyle bir fonksiyonu aramayı hiç düşünmedim.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

v=>![...""+v].some(x=>v%x)
14m2'de

@ l4m2 O zamandan beri v%0döner NaNve NaN == falsebu nedenle durumunuzda 0 içeren sayılar 10geri dönebilir true.
Shieru Asakoto

9

Java 8, 46 Bayt (yöntem gövdesi)

Jeroen Mostert'ı kullanarak çift ​​hile dönüştürüyor.

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

8

Pyth, 12 bayt

!f|!vT%vzvTz

Bu, dizedeki karakterleri sıfır ( !vT) olması veya girişi ( %vzvT) bölmemesi için filtreler , ardından elde edilen listenin mantıksızlığını alır.

Burada dene.


Hayır, bir işlev kullanılmazsa ben iyiyim. Sadece bildirimi sayması gerekmeyen fonksiyonları kullanan ve sadece içindeki kodu belirtmek istedim.
Mathew Kirschbaum

8

Yakut, 44 bayt (işlev gövdesi: 37)

Muhtemelen daha fazla golf oynama potansiyeli var.

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

Fonksiyon üzerinden alınan girdi f. Örnek kullanım:

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

1
Değişebilirsin .to_iiçin .hextek haneli sayılar tabana 16'da aynı olduğundan, ve değiştirebilirsiniz ==0için <1.
histocrat

8

Python - 59 50 49 47 bayt

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

Eminim daha hızlı bir yol vardır.

Düzenleme - FryAmTheEggman'a golf önerileri için teşekkürler.

Düzen 2 - FryAmTheEggman bu noktada yazmış olabilir, ayy,

Düzen 3 - Genexps bir şey olduğunu bile bilmiyorsanız eller yukarı. ...Benim?


Oh çok teşekkürler! Tüm bunları unutmaya devam ediyorum. (Ayrıca bu şekilde karakterlerden daha az olabileceğinizi fark etmedim.)
Kasran

Ah, mantık saygısız da biraz kısaltın görünüyor: f=lambda n:all([c>'0'and 0==n%int(c)for c in`n`]). Ve sorun değil :)
FryAmTheEggman

Ah, orada fark etmedi bile oldu bir allyöntem.
Kasran

Çalışır 1>n%int(c)mı?
Sp3000

3
Neden bir liste anlama? Bir genexp kullanarak: all(c>'0'and 0==n%int(c)for c in`n`)tam olarak aynı, 2 karakter daha az ve hatta liste tahsisini kaydederek yapar.
Bakuriu

8

Pyth 11

!f%Q|vT.3`Q

Bu birleştirir isaacg en @ ve @ XNOR en cevapları. Değerini kontrol ederek girdideki rakamları filtreler input % (eval(current_digit) or .3). Sonra ortaya çıkan dizenin boş olup olmadığını kontrol eder.

Başka bir çift aynı uzunlukta varyantlarla karşılaştım:

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

Çevrimiçi deneyin.


5

Bash + coreutils, 44 bayt

Tam fonksiyon tanımı:

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

Normalde kabuk fonksiyonlarının tek bir set kullandığı {}veya ()fonksiyon gövdesini içerdiği için bunu nasıl puanlayacağımı bilmiyorum . Burada (())ihtiyacım olan şey olan aritmetik genişlemeye neden olan fonksiyon gövdesini içermek için çift ​​kullanabileceğimi öğrendim. Şimdilik bu parantezin sadece bir çiftini sayıyorum - bununla ilgili daha fazla tartışma açıktır.

Çıktı:

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

Ah - onun 1'ler ve 0'lar kabul edilebilir ya da ben varsa yazdırmak isteyip bana belli değil true/ false?
Dijital Travma

4

J - 14 karakter

İşlev gövdesi, sonrasındaki kısımdır =:. Tüm fonksiyon için karakter sayısını en aza indirmek istiyorsak, bu 15 karakterdir */@(0=,.&.":|]).

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

,.&.":J'de ondalık basamakların bir listesine sayı olarak genişletmenin en kısa yoludur: dizeye dönüştür, basamakları ayır ve her basamağı bir sayıya dönüştür. ,.&.":|]giriş sayısını ( ]) modulo ( |) bu rakamları alır. 0*/@:=Tüm sonuçlar 0 olsaydı true, aksi halde yanlış verir.

   f 162
1
   f every 204 212 213
0 1 0

3

Java - 121 102 97 79 78 bayt

Sadece bunun sonradan clober edileceğini biliyorum . Oh iyi.

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

Geri döneceğim.


1
Artık fonksiyonunuza ne istediğinizi adlandırabilirsiniz. Sadece gerçek işlevi içinde hesaplamalar saymak, ancak işlevi yüzden kuralları değiştirdi gerekir bir boolean türü döndürür. Yani şu anda 86 karakter.
Mathew Kirschbaum

3

Haskell - 100 54 38

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

Hala öğrenme, eleştiriler takdir


Burada bir yorum yaptım, ancak bir şekilde yanlışlıkla sildim ... Her neyse, bazı öneriler: 1) Bırakın, lengthgereksiz. 2) tTanımı ile değiştirin . 3) elem y sgereksizdir. 4) /='0', yerine soldaki filtreye taşınabilir elem y s. 5) Bu durumda, her harf bir rakam olduğundan /='0', buna eşittir >'0'. 6) geri modtepmeler koyun , böylece ek haline gelir. 7) Her şeyi tek bir satıra koyun.
Zgarb

1 ve 3 farklı bir yolla yapmaya çalıştığım ve kurtarılan koddan. İpuçları için teşekkürler.
globby

1
önerilerim: kullanmak yerine s==filter(...)skullanmalısınız all(...)s. Şimdi, sifadede yalnızca bir kez göründüğü için, tanımı ve bırakmasıyla değiştirebilirsiniz where. ayrıca, yerine ==0kullanabilirsiniz <1.
Gurur haskeller

İlk versiyondan büyük gelişme!
Gurur haskeller

Ben hala kaybetmek bir byte yerine eğer düşünmeye all(\y->...)$show xtarafından and[...|y<-show x].
Zgarb

2

CJam, 15 bayt

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

Bu bir blok, CJam'daki bir işleve en yakın şey. Ben sadece bedeni sayıyorum (yani diş tellerini atlıyorum). Aşağıdaki gibi kullanabilirsiniz:

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

Veya bir seri girişi test etmek istiyorsanız,

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

Blok , sonucu belirtmek için istif üzerinde 0(sahte) veya 1(truthy) bırakır . (CJam Boolean tipinde değildir.)

Burada test et.

Açıklama:

_               "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, ayrıca 15 bayt

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

açıklama

: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 bayt

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

{}CJam'da bir işleve en yakın şeydir. Ben sadece fonksiyonun gövdesini sayıyorum

Bu şekilde kullanın:

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

Ya da almak için 1(sayı bölünebilir) veya 0(sayısı, basamak ile bölünebilir değilse).

Burada çevrimiçi deneyin

açıklama

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

Bir şeyleri özlüyorum, ancak CJam’ı hızlıca okuduktan sonra, bazı şeylerin bir anlamı yok gibi görünüyor: Abrakamları nasıl bölüştürüyor? Sadece üs 10'a dönüştüğü görülüyor. Ayrıca,% rakamı, sadece bir sonraki hane değil, bir sonraki hane yığının üstünde olacak gibi göründüğü için, sayı ile mod değiştirmeyi nasıl biliyor?
Mathew Kirschbaum

Tüm sorunuzu cevaplamak zor olacak. Koddaki her karakterden sonra ed koyarak öğrenmesi çok kolay olacaktır. 128{ed_edAedbedf{ed_ed{ed%ed}1ed?ed}ed1edbed!ed}~
Doktor

1
Belirli soruların cevapları: 10 tabanını yapmak, bu durumda hanelerin kendileri olan 10 tabanını dönüştürülmüş bir sayı dizisi verir. %son iki sayıyı almanız (bu durumda) ve mod'u hesaplamanız yeterlidir. Buradaki son iki sayı gerçek sayı ve rakamdır (her zaman)
Doktor

Tamam, tavsiyen için teşekkürler!
Mathew Kirschbaum

2

C89, 43 bayt

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

C89'un bir boolean tipi yok. Umarım işe yarar. Ayrıca, orjinal sayının bir kopyasını istifin üzerinden geçirmek için ikinci bir parametre kullandım, ancak tanım her şey olabilir. Doğru sonucu almak için her iki parametre ( d(128, 128)) için aynı değere sahip işlevi çağırmanız yeterlidir .

EDIT: İsimsiz bir kullanıcı tarafından önerilen önerilen düzenlemeler


Codegolf.stackexchange.com/review/suggested-edits/17160 adresine bir göz atın , birisi size bazı golf önerileri verdi
Justin

Özellikle kurallara aykırı. Bir parametre.
edc65

Evet, bu yazı aslında bu kuralı yapmaya karar verdim, çünkü kullanıcının program yerine kopyalamayı yapması gerektiği doğru değildi.
Mathew Kirschbaum

Bir sarmalayıcı işlevi eklemek zorunda kalacağım sanırım. Bu işlevin bildirimi bayt sayısına eklenir mi?
MarcDefiant

2

İşlev gövdesinde C11 - 44 Bayt

Özyinelemeli olmayan ve kayan nokta istisnası olmayan bir başka C versiyonu

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

Bu, C ++, Java ve diğer birçok C benzeri dilde de çalışacaktır.

Primo yorumunun iyileştirilmesini içerecek şekilde düzenlendi.


1
Java'da derlenen sürüm (1.7.0_45-b18): int n=i;for(;i%10>0&&n%(i%10)<1;i/=10);return i<1;OP kodundan bir bayt daha kısa.
primo

2

Julia 32 25 23

Rakamlar kullanılarak iyileştirildi

Ayrıca negatif sayılarla olan sorunu düzeltir

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

Eski yöntem

Tüm haneler, kalanların toplamı 0 ise bölünür. Diğerleri gibi negatif sayılarla ilgili bir sorun varsa.

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

Çıktı

[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

Geliştirilmiş yöntem aynı zamanda BigInt'ı da yönetir

selfDivides(BigInt(11111111111111111111111111111111111111112))
true

ancak

selfDivides(BigInt(11111111111111111111111111111111111111113))
false

Çünkü

BigInt(11111111111111111111111111111111111111113) %3
1

2

C / C ++, 58 bayt (vücutta 44)

Tanımsız Davranışı Çalıştırır (Yorumlara bakınız)

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

trueve false olan 1 ve 0, ama bir dönmek için imzaya bir karakter eklemek için çekinmeyin bool.

Ve eğlence için, formun çağrılmasına izin verirseniz daha küçük olan özyinelemeli bir sürüm r(128,128)

Düzenleme : Şimdi kurallara uymuyor:

C / C ++, 53 bayt (vücutta 33)

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


2
# 1, 0 içeren sayılar için kayan nokta istisnasıyla ölür, çünkü j% (i% 10), i% 10 = 0 için geçersizdir.
SBI

Bir kayan nokta özel durumu? Tuhaf. Derleyicimde mükemmel çalışıyor ama haklısın, tanımsız davranış. Derleyiciye bağlı UB'deki genel PCG duruşunun ne olduğundan emin değil.
etheranger

"Derleyiciye bağlı UB" nedir? Ya UB ya da değil (ve sıfıra bölmek, ya da daha ziyade modulo sıfır, aslında UB'dir). UB'ye izin verilmemeli çünkü tam anlamıyla bir şeyler olabilir. Programınızın, sıfıra bölündüğü zaman etrafındaki herkesi havaya uçuracak ve öldürecek bir makine üzerinde çalışacağını varsayabiliriz. Şimdi, hepimizin yaşamasını istediğinizden eminim ... C'nin uygulama tanımlı bir davranış kavramı var, ancak sıfıra bölmek bunun altına girmiyor.
Jeroen Mostert

2
@etheranger: 0'a bölünme, tarihi sebeplerden dolayı kayan nokta istisnası olarak adlandırılır: stackoverflow.com/questions/16928942/…
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

2
@JeroenMostert: Bu sitedeki tüm C cevaplarının% 90'ından fazlasının UB'yi çağırdığını söyleyebilirim. Sürece ile çalışır olarak bazı üzerinde derleyici bazı makine, cevap geçerli kabul edilir.
Dennis

2

R: 72 67 65

İşlev

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

Tasarruf için @AlexA ve @plannapus sayesinde

Test sürüşü

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

Şu anda işlev bedeninizde 72 bayt sayıyorum, 72 değil. Ancak bunu kullanarak 67'ye indirebilirsiniz d=as.double(strsplit(toString(a),"")[[1]]);!(anyNA(a%%d)|sum(a%%d)). :)
Alex A.

@AlexA. Teşekkürler.
Rih

@MickyT paste(a)yerine toString(a)aynı sonucu verir.
plannapus

@plannapus Teşekkürler, temiz küçük hile. Bunu hatırlamalısın
MickyT

1

GNU Awk: 53 karakter

Sayılan kısım:

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

Tüm fonksiyon:

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

    return ! r
}

Awk'nin boole değerleri olmadığından, 1 tor true ve false için 0 döndürür.


1

JavaScript (ES6) 30

Bir sayısal parametre ile işlev. % Ve çıkarma kullanarak, '0' özel durumuna gerek yoktur, çünkü% 0 0, JavaScript'te NaN'dir.

Düzenle Kaydet 1 char thx DocMax

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

Sadece eğlence için, işlev imzasını saymama kuralını kötüye kullanma, 4

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

FireFox / FireBug konsolunda test edin

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

Çıktı

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

Bir dize girmek için hayır diyeceğim.
Mathew Kirschbaum

1
Firefox konsolu, of(t=n+'')yalnızca of t=n+''1 tasarruf etmek yerine kullanılmasından memnuniyet
duyuyor

1

PHP: 85 bayt (vücutta 64 bayt)

Bu işlevin çalışması için, sadece bir dize veya sayı iletin.

0 doğru yanlış döndürür.

Kod:

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

Lütfen 2. PARAMETREYİ AYARLAMAYIN!

Javascript: 76 bayt (vücutta 61 bayt)

Bu önceki işlevin bir tekrarıdır.

Her iki sürüm arasında da pek bir değişiklik yok.

İşte kod:

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

Polyglot: Javascript + PHP 187 217 bayt (76 Boylersiz 84 bayt):

Neden yaptım?

Sebep yüzünden ve belki de yapabilirim!

Sadece PHP'deki hatayı göz ardı edin: yine de işe yarıyor!
Artık gerek yok, bu 3 baytı kaldırarak düzeltildi.

İşte başyapıt:

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

Bu kodu hem konsolunuzda hem de bir PHP tercüman üzerinde çalıştırabilirsiniz!


Eski versiyon:

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

"ve sadece bir sayısal parametrede geçer". Bu olmadan, değerlendirmek ($ x) ve tüm kodu $ x
abc667 11

@ abc667 Üzgünüm, ama anlamadım.
Ismael Miguel

1

Octave, 33 (39 fonksiyon kurulumu dahil)

Sayısal-matris dönüşümünü kullanarak:

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

Sayıyı elemanlara X matrisine bölün, burada X, sayıyı dizgeye dönüştürerek ve 48'i çıkartarak, ASCII değerlerinden tekrar sayılara gitmek için yapılır. Her bölümün ondalık bölümünü almak için modulo 1'i alın, bunların hepsinin sıfır olduğunu onaylayın (eğer varsa / NaN ise, toplam NaN olacaktır ve dolayısıyla sıfır olmayacaktır).

Www.octave-online.net kullanarak örnek girdi:

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

Çıktı:

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

Bunu nasıl test edebiliriz?
Ismael Miguel

octave-online.net - yukarıdan kod tanımını girin ve ardından (örneğin) f (128). Çıkış ekleyecektir
Jørgen

Derleyiciyi buldum ve sormadan önce denedim. Fakat iyi çalışıyor gibi görünüyor (hariç f(123), 1, 2 ve 3 ile bölünebilen). Ancak verilen test durumlarında işe yarıyor.
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));}

testler

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 Karakterler

golfed:

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

Daha Az Golf:

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

Test sonuçları:

(Kod)

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

(Çıktı)

128 -> True
12 -> True
120 -> False
122 -> True
13 -> False
32 -> True
22 -> True
42 -> True
212 -> True
213 -> True
162 -> False
204 -> False
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.