Czy liczba jest podzielna przez każdą z jej cyfr?

47

Mój przyjaciel i ja pracowaliśmy w laboratorium na naszej zajęciach z informatyki AP i postanowiliśmy zakodować jeden z problemów, ponieważ nadal mieliśmy połowę zajęć po zakończeniu. Oto pytanie:

Biorąc pod uwagę liczbę n, czy n jest podzielne przez każdą z jej cyfr?

Na przykład 128 przejdzie ten test - dzieli się go przez 1,2 i 8. Wszelkie liczby z zerem automatycznie dyskwalifikują liczbę. Chociaż możesz używać innych języków i publikować w nich rozwiązania, jeśli chcesz, najbardziej interesuje nas to, jak kompaktowi ludzie mogą tworzyć program w Javie, ponieważ jest to język, którego używamy w klasie. Jak dotąd oboje mamy 51. Oto mój obecny kod:

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.

Wymagania

Podpis metody może być dowolny. Po prostu policz ciało funkcji. Upewnij się jednak, że metoda zwraca wartość logiczną i przekazuje tylko jeden parametr numeryczny (nie ciąg znaków).

Kod musi być w stanie przekazać wszystkie te przypadki (aby zachować zgodność z kierunkami pierwotnego pytania, tylko logiczne wartości prawda i fałsz liczą się, jeśli język obsługuje wartości logiczne. Jeśli i tylko wtedy, gdy twój język nie ma zmiennych boolowskich, ty może reprezentować false z 0 i true z dowolną niezerową liczbą całkowitą (najlepiej 1 lub -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

Nie liczyliśmy też spacji, więc możesz zrobić to samo, chyba że spacja jest niezbędna do działania programu (więc nowe wiersze w Javie się nie liczą, ale jedna spacja między inti x=1ma znaczenie.) Powodzenia !

Mathew Kirschbaum
źródło
18
Witamy w PPCG! Kilka sugestii: 1. Nie liczenie funkcjonalnych białych znaków to zły pomysł. Każda odpowiedź napisana w Whitespace automatycznie wygrywa. 2. Czy nasze zgłoszenie powinno zostać wydrukowane / zwrócone truei falseczy wartości prawdy / fałszu również są w porządku? 3. javaZnacznik tak naprawdę nie ma tu zastosowania, ponieważ samo wyzwanie nie jest związane z Javą.
Dennis
W porządku. przepraszam za problemy. Żeby to wyjaśnić, czy można by uznać, że spacja w 'int p = n' jest funkcjonalna, ponieważ wcześniej tego nie robiłem. Naprawię inne problemy, które wskazałeś.
Mathew Kirschbaum
5
Wszystkie białe znaki wymagane do działania kodu działają.
FryAmTheEggman
OK, dziękuję za odpowiedź!
Mathew Kirschbaum
1
@RickyDemer: ponieważ 0 byłoby w tym przypadku wyjątkowym wprowadzeniem (jest to jedyna cyfra z 0cyframi będąca wielokrotnością każdej z nich), wyobrażam sobie, że większość odpowiedzi wydłużyłaby się w nieciekawy sposób, aby włączyć sprawdzenie. Dlatego bardziej podoba mi się problem związany z tytułem (podzielny przez cyfry, a nie wielokrotność jego cyfr, co wyklucza 0).
Jeroen Mostert

Odpowiedzi:

23

Perl 6, 13

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

Używa zmiennej niejawnej $_- $_ %% .comb.alljest równoważne z $_ %% all($_.comb). %%jest operatorem „jest podzielna” i combbez dodatkowego argumentu zwraca listę znaków w ciągu. Na przykład, jeśli argument to 123, funkcja ocenia

123 %% all(123.comb)

który jest

123 %% all(1, 2, 3)

robi to automatyczne przeszukiwanie węzłów

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

który jest

all(True, False, True)

co jest fałszem w kontekście logicznym, ponieważ jest to połączenie „wszystko” i wyraźnie nie wszystkie jego elementy są prawdziwe.

Powinno być możliwe wymuszanie wartości zwracanej Booli ukrywanie połączenia przed obiektami wywołującymi poprzez utworzenie podpisu funkcji sub golf($_ --> Bool()), ale koercje w podpisach funkcji nie działają jeszcze w Rakudo. Zwracana wartość jest nadal poprawnie prawdą lub fałszem, po prostu nie jest Truelub False.

Hobbs
źródło
Jeśli chcesz, aby to zwróciło, po Boolprostu dodaj sona początku kodu so$_%%.comb.all.
Brad Gilbert b2gills
21

C # i System.Linq - 26/40

Zgodnie z regułami, nie licząc samej deklaracji metody.

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

Pokazując to po raz kolejny, C # jest najlepszym wyborem, gdy rozważa się Javę ... Żartuję, żartuję!

Niestety, ta funkcja (i wiele innych odpowiedzi) nie da poprawnych wyników dla negatywnych danych wejściowych. Możemy to naprawić, ale rozwiązanie traci wiele ze swojego uroku (i dorasta do 46 znaków):

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

Edycja : zgoliłem jedną postać z sugestią Tima.

Edycja : wraz z wprowadzeniem pełnoprawnych członków w C # 6 możemy to jeszcze bardziej ograniczyć, odcinając return:

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

za łącznie 26 znaków (moim zdaniem =>nie powinno być więcej niż nawiasy klamrowe). Wersja obsługująca liczby ujemne może być podobnie skrócona.

Jeroen Mostert
źródło
Dlaczego .0? Nie potrzeba niczego poza modułem całkowitym.
Peter Taylor
3
@PeterTaylor: Jest, jeśli chcesz najkrótszy program - i % 0z iliczbą całkowitą daje DivideByZeroException.
Jeroen Mostert
2
I z podwójnym daje NaN! Miły!
Peter Taylor
2
48djest taki sam jak 48.0, ale o jeden mniej znaków (d dla podwójnej).
Tim S.
1
@StuartLC: lambdas nie są metodami; ich zakres jest inny, więc myślę, że to wygina reguły zbyt daleko. Ale odkąd C # 6 (który poprzedza ta odpowiedź), mamy pełnoprawnych członków, którzy pozwalają nam skrócić definicję. W przypadku negatywnym nie możemy użyć &, ponieważ &nie powoduje zwarcia - otrzymasz wyjątek dzielenia przez zero %. Możemy to naprawić, czyniąc to podwójnym (z d), ale potem znowu straciliśmy jedną postać.
Jeroen Mostert
18

APL ( 13 11)

(najwyraźniej nawiasy się nie liczą)

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

Wyjaśnienie:

  • ⍎¨⍕⍵: oceń każdy znak w reprezentacji ciągu
  • ⍵|⍨: dla każdego z nich znajdź jego modulo i
  • 0∧.=: sprawdź, czy wszystkie są równe 0

Przypadki testowe:

      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
marinus
źródło
APL może zrobić X%0? bez rzucania?
Optymalizator
@Optimizer: tak. 0|Xdaje X.
marinus
Słodkie. Twoja odpowiedź to 11 bajtów, a nie 13
Optymalizator
9
Tylko APL nie dawałby błędu na modulo o 0 i zawieszał się przy ocenie non-bool jako bool;)
FryAmTheEggman
3
Jedna postać krótsza z pociągiem zamiast (0∧.=⍎¨∘⍕|⊢)
dfn
14

Python 2: 43 znaków

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

Sprawdza, czy liczba ma jakieś niezerowe reszty modulo swoje cyfry, i wysyła negację tego. Cyfry zerowe są dziwnie obsługiwane: ponieważ przetwarzanie %0powoduje błąd, cyfry 0są zastępowane przez .3, co wydaje się zawsze dawać niezerowy wynik z powodu niedokładności liczb zmiennoprzecinkowych.

Ciało funkcji ma 32 znaki.

xnor
źródło
14

Perl - 27 bajtów

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

Nie licząc podpisu funkcji, zgodnie z instrukcją.

Przykładowe użycie:

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

Przykładowe dane wyjściowe:

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

Rozwiązanie problemu: „Liczą się tylko logiczne wartości prawda i fałsz. Wartości prawda / falsey się nie liczą”.

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

Wyjścia:

1
""

„Prawda” i „Fałsz” są zdefiniowane jako 1i "".

Erratum:
Jak słusznie zauważa Brad Gilbert , perl definiuje prawdę jako skalar, który jest jednocześnie liczbą całkowitą 1i ciągiem "1", a fałsz jako skalar, który jest jednocześnie liczbą całkowitą 0i ciągiem "".

primo
źródło
To może być skrócony przez nie za pomocą $_: pop=~s///ger<1. Nie wiem, czy PO się na to zgodzi 1i czy ""są to ważne wyniki. Jeśli nie, to można to naprawić dwoma dodatkowymi bajtami: wystarczy dodać |0.
hvd
perl -pe'$_=s/./!$&||$_%$&/ger<1|0'ma 26 bajtów łącznie z flagą |0i -p. Nie musisz używać funkcji.
hmatt1
1
W rzeczywistości wartości Prawda i Fałsz są bardziej podobne do dualvar(1,'1')i dualvar(0,'').
Brad Gilbert b2gills
1
@BradGilbert To ciekawe. Znam się dobrze na perlguts, ale nie zdawałem sobie sprawy, że prawda i fałsz są wyjątkowe. W rzeczywistości są to „potrójne skalary”, oznaczone jako SVIV(int), SVNV(double) i SVPV(string).
primo
1
W rzeczywistości przy pierwszym użyciu łańcucha jako liczby lub liczby jako łańcucha zmienna zostaje zmodyfikowana w celu przechowywania tych dodatkowych danych. Dlatego otrzymujesz ostrzeżenie tylko przy pierwszym użyciu 'abc'jako liczby (zakładając, że masz use warnings;włączony.)
Brad Gilbert b2gills
13

CJam, 11 10 bajtów

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

Definiuje nazwaną funkcję Fi odrzuca blok ze stosu.

Wypróbuj online.

Przypadki testowe

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

Jak to działa

_      " 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.                                        ";
Dennis
źródło
Czy CJam miał funkcje używane w 10-bajtowym rozwiązaniu, gdy pytanie zostało napisane?
lirtosiast
@ThomasKwa: Tak, zrobiło to. Testowałem kod w wersji 0.6.2, która została wydana w lipcu 2014 r.
Dennis
12

JavaScript ES6, 39 32 28 bajtów

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

Dzięki za sugestię core1024 zastąpienia (""+v).split("")z [...""+v]i openorclose dla sugeruje użycie everyfunkcji.

Odpowiedź obecnie nie zawiera jednego bitu mojego kodu: O

Poprzednie rozwiązanie

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

==""nie jest poprawnym sposobem sprawdzenia, czy tablica jest pusta, ponieważ [""]==""zwraca true, ale tablica gwarantuje, że zawiera niepusty łańcuch, więc działa tutaj.

Reszta to dość standardowa konwersja typu skróconego w JavaScript.

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳
źródło
1
Możesz zapisać niektóre postacie, zastępując (""+v).split("")je [...""+v].
core1024
1
Dlaczego nie skorzystać z tej everymetody? v=>[...""+v].every(x=>v%x<1);
openorclose
@openorclose: Dzięki. Nigdy nie miałem okazji użyć go w JS, więc nigdy nie myślałem o poszukiwaniu takiej funkcji.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳
v=>![...""+v].some(x=>v%x)
l4m2
@ l4m2 Ponieważ v%0zwraca, NaNa NaN == falsewięc w twoim przypadku numery zawierające 0, takie jak 10, mogą zwrócić true.
Shieru Asakoto,
9

Java 8, 46 bajtów (treść metody)

Korzystanie z konwersji Jeroena Mosterta na podwójną lewę.

public static boolean dividesSelf(int n) {
    return(""+n).chars().allMatch(x->n%(x-48d)<1);
}
cPu1
źródło
8

Pyth, 12 bajtów

!f|!vT%vzvTz

To filtruje znaki w łańcuchu jako zero ( !vT) lub brak dzielenia input ( %vzvT), a następnie logiczne nie z wynikowej listy.

Wypróbuj tutaj.

isaacg
źródło
Nie, nic mi nie jest, jeśli funkcja nie jest używana. Chciałem tylko wskazać każdemu, kto używa funkcji, że nie muszą liczyć deklaracji, a tylko kod w środku.
Mathew Kirschbaum
8

Ruby, 44 bajty (treść funkcji: 37)

Prawdopodobnie ma potencjał do dalszej gry w golfa.

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

Dane wejściowe przejęte przez funkcję f. Przykładowe użycie:

f[128] # => true
f[12]  # => true
f[120] # => false
...
sierpień
źródło
1
Możesz zmienić .to_ina .hex, ponieważ liczby jednocyfrowe są takie same w bazie 16, i możesz zmienić ==0na <1.
histocrat
8

Python - 59 50 49 47 bajtów

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

Jestem pewien, że jest szybszy sposób ... no cóż.

Edycja - Podziękowania dla FryAmTheEggman za wskazówki dotyczące gry w golfa.

Edycja 2 - FryAmTheEggman równie dobrze mógł napisać to w tym momencie, ups

Edycja 3 - Ręce do góry, jeśli nawet nie wiedziałeś, że geneksy to coś. ...Tylko ja?

Kasran
źródło
Oh dzięki wielkie! Ciągle zapominam o tych wszystkich rzeczach. (Nie zdawałem sobie również sprawy, że można w ten sposób uzyskać mniej niż znaki).
Kasran
Och, odwracanie logiki wydaje się również, aby je skrócić trochę: f=lambda n:all([c>'0'and 0==n%int(c)for c in`n`]). I nie ma problemu :)
FryAmTheEggman
Och, nie zdawał sobie sprawy, że nawet byłoall metoda.
Kasran
Czy 1>n%int(c)zadziała?
Sp3000,
3
Dlaczego rozumienie listy? Korzystanie z genexp: all(c>'0'and 0==n%int(c)for c in`n`)robi dokładnie to samo, z 2 znakami mniej, a nawet zapisuje przydział listy.
Bakuriu
8

Pyth 11

!f%Q|vT.3`Q

Łączy to odpowiedzi @ isaacg i @ xnor . Filtruje cyfry z wejścia, sprawdzając wartość input % (eval(current_digit) or .3). Następnie sprawdza, czy wynikowy ciąg jest pusty, czy nie.

Znalazłem kilka innych wariantów tej samej długości:

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

Wypróbuj online.

FryAmTheEggman
źródło
5

Bash + coreutils, 44 bajty

Pełna definicja funkcji to:

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

Nie jestem pewien, jak to ocenić, ponieważ normalnie funkcje powłoki używają jednego zestawu {}lub ()zawierają ciało funkcji. Znalazłem tutaj, że mogę również użyć podwójnego, (())aby zawrzeć ciało funkcji, które powoduje rozszerzenie arytmetyczne, czego potrzebuję tutaj. Na razie liczę tylko jedną parę tych nawiasów - dalsza dyskusja na ten temat jest mile widziana.

Wynik:

$ 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 $
$
Cyfrowa trauma
źródło
Uh - nie jest dla mnie jasne, czy cyfry 1 i 0 są dopuszczalne, czy też muszę wydrukować true/ false?
Digital Trauma
4

J - 14 znaków

Ciało funkcji jest częścią po =:. Jeśli chcemy zminimalizować liczbę znaków dla całej funkcji, jest to 15 znaków */@(0=,.&.":|]).

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

,.&.":to najkrótsza droga w J, aby rozwinąć liczbę jako liczbę cyfr dziesiętnych: przekonwertować na ciąg, oddzielić cyfry i przekonwertować każdą cyfrę z powrotem na liczbę. ,.&.":|]pobiera numer wejścia ( ]) modulo ( |) z tych cyfr. 0*/@:=zwraca true, jeśli wszystkie wyniki były równe 0, w przeciwnym razie daje false.

   f 162
1
   f every 204 212 213
0 1 0
algorytmshark
źródło
3

Java - 121 102 97 79 78 bajtów

Wiem tylko, że to później zostanie zablokowane. No cóż.

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

Wrócę.

Stretch Maniac
źródło
1
Możesz teraz nazwać swoją funkcję, jak chcesz. Zmieniłem reguły, abyś liczył tylko obliczenia w rzeczywistej funkcji, ale funkcja musi zwracać typ boolowski. Tak więc obecnie ma 86 znaków.
Mathew Kirschbaum
3

Haskell - 100 54 38

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

Wciąż się uczę, krytyka jest doceniana

globby
źródło
Miałem tutaj komentarz, ale jakoś go przypadkowo usunąłem ... W każdym razie kilka sugestii: 1) Upuść length, są niepotrzebne. 2) Zastąp tjego definicją. 3) elem y sjest niepotrzebny. 4) /='0'można przesunąć na lewy filtr zamiast elem y s. 5) W tym przypadku /='0'jest równoważne >'0', ponieważ każda litera jest cyfrą. 6) Wstaw modbackticks, aby stał się infix. 7) Umieść wszystko w jednym wierszu.
Zgarb
1 i 3 pochodzą z czasów, gdy próbowałem to zrobić inaczej i odzyskałem kod. Dzięki za wskazówki.
globby
1
moje sugestie: zamiast korzystać s==filter(...)s, powinieneś użyć all(...)s. teraz, ponieważ spojawia się tylko raz w wyrażeniu, możesz go zastąpić jego definicją i upuścić where. zamiast tego ==0możesz użyć <1.
dumny haskeller
wielkie ulepszenie od pierwszej wersji!
dumny haskeller
Myślę, że nadal można przegrać jeden bajt, jeśli zastąpić all(\y->...)$show xprzez and[...|y<-show x].
Zgarb
2

CJam, 15 bajtów

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

Jest to blok, najbliższy funkcji w CJam. Liczę tylko ciało (tzn. Pomijając aparat ortodontyczny). Możesz użyć tego w następujący sposób:

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

Lub jeśli chcesz przetestować szereg danych wejściowych, możesz to zrobić

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

Blok pozostawia 0(fałsz) lub 1(prawda) na stosie, aby wskazać wynik. (CJam nie ma typu logicznego.)

Sprawdź to tutaj.

Wyjaśnienie:

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

Alternatywnie, również 15 bajtów

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

Wyjaśnienie

: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.";
Martin Ender
źródło
2

CJam, 15 bajtów

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

{}jest najbliższą funkcją w CJam. Właśnie liczę treść tej funkcji

Użyj tego w ten sposób:

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

Aby uzyskać albo 1(jeśli liczba jest podzielna), albo 0(jeśli liczba nie jest podzielna przez swoje cyfry).

Wypróbuj online tutaj

Wyjaśnienie

_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";
Optymalizator
źródło
Być może czegoś mi brakuje, ale po szybkim przeczytaniu CJam niektóre rzeczy wydają się nie mieć sensu: jak Abrozdzielić cyfry? Wydaje się, że po prostu przekonwertował go na bazę 10. Ponadto, skąd% wie, aby modyfikować według liczby, a nie tylko następnej cyfry, ponieważ wydaje się, że następna cyfra będzie następna na stosie?
Mathew Kirschbaum
Odpowiedź na wszystkie twoje pytania będzie trudna. Bardzo łatwo byłoby się nauczyć, umieszczając ed po każdym znaku w kodzie. Spróbuj uruchomić128{ed_edAedbedf{ed_ed{ed%ed}1ed?ed}ed1edbed!ed}~
Optymalizator
1
Odpowiedzi na określone pytania: wykonanie bazy 10 daje tablicę liczb konwersji 10 baz, które w tym przypadku są same cyframi. %po prostu weź dwie ostatnie liczby (w tym przypadku) i oblicz mod. Dwie ostatnie liczby tutaj to rzeczywista liczba i cyfra (zawsze)
Optymalizator
OK, dziękuję za radę!
Mathew Kirschbaum
2

C89, 43 bajty

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

C89 nie ma typu boolowskiego. Mam nadzieję, że to działa. Użyłem również drugiego parametru, aby przekazać kopię oryginalnego numeru przez stos, ale definicja może być dowolna. Aby uzyskać poprawny wynik, wystarczy wywołać funkcję o tej samej wartości dla obu parametrów ( d(128, 128)).

EDYCJA: Zastosowane sugerowane zmiany przez anonimowego użytkownika

MarcDefiant
źródło
Spójrz na codegolf.stackexchange.com/review/suggested-edits/17160 , ktoś dał ci kilka sugestii dotyczących gry w golfa
Justin
Szczególnie wbrew zasadom. Jeden parametr.
edc65,
Tak, ten post jest właściwie powodem, dla którego postanowiłem wprowadzić tę regułę, ponieważ nie wydawało się właściwe, aby użytkownik wykonał kopię zamiast programu.
Mathew Kirschbaum
Chyba będę musiał dodać funkcję otoki. Czy deklaracja tej funkcji dodaje się do liczby bajtów?
MarcDefiant,
2

C11 - 44 bajtów w ciele funkcyjnym

Kolejna wersja C, nierekurencyjna i bez wyjątku zmiennoprzecinkowego.

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

Działa to również w C ++, Javie i większości innych języków podobnych do C.

Edytowano, aby uwzględnić ulepszenie komentarza primo.

SBI
źródło
1
Wersja kompilująca się w Javie (1.7.0_45-b18): int n=i;for(;i%10>0&&n%(i%10)<1;i/=10);return i<1;jeden bajt krótszy niż kod OP.
primo
2

Julia 32 25 23

Poprawiono za pomocą cyfr

Naprawiono również problem z liczbami ujemnymi

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

Stara metoda

Wszystkie cyfry dzielą się, jeśli suma wszystkich pozostałych wynosi 0. Podobnie jak inne, problem z liczbami ujemnymi.

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

Wynik

[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

Ulepszona metoda obsługuje również BigInt

selfDivides(BigInt(11111111111111111111111111111111111111112))
true

jednak

selfDivides(BigInt(11111111111111111111111111111111111111113))
false

dlatego

BigInt(11111111111111111111111111111111111111113) %3
1
waTeim
źródło
2

C / C ++, 58 bajtów (44 w treści)

Wywołuje niezdefiniowane zachowanie (patrz komentarze)

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

truei false mają wartość 1 i 0, ale możesz dodać jeden znak do podpisu, aby zwrócić a bool.

I dla zabawy, wersja rekurencyjna, która jest mniejsza, jeśli zezwolisz na wywołania formularza r(128,128)

Edycja : teraz zabronione przez reguły:

C / C ++, 53 bajty (33 w treści)

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

etheranger
źródło
2
# 1 umiera z wyjątkiem zmiennoprzecinkowym dla liczb zawierających 0, ponieważ j% (i% 10) będzie nielegalne dla i% 10 = 0.
SBI
Zmiennoprzecinkowych wyjątek? Dziwne. Działa idealnie na moim kompilatorze, ale masz rację, jest to niezdefiniowane zachowanie. Nie jestem pewien, jaka jest ogólna postawa PCG na UB zależnym od kompilatora.
etheranger
Co to jest „zależny od kompilatora UB”? Albo jest to UB, albo nie jest (a dzielenie przez zero, a raczej modulo zero, faktycznie jest UB). UB nie powinno być dozwolone, ponieważ dosłownie wszystko może się zdarzyć. Możemy założyć, że twój program będzie działał na maszynie, która wysadzi w powietrze i zabije wszystkich wokół niego, gdy nastąpi podział przez zero. Teraz jestem pewien, że chcesz, abyśmy wszyscy żyli ... C ma pojęcie zachowania zdefiniowanego w implementacji, ale dzielenie przez zero nie mieści się w tym.
Jeroen Mostert
2
@etheranger: Dzielenie przez 0 jest nazywane wyjątkiem zmiennoprzecinkowym z przyczyn historycznych: stackoverflow.com/questions/16928942/…
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
2
@JeroenMostert: Powiedziałbym, że ponad 90% wszystkich odpowiedzi C w tej witrynie wywołuje UB. Tak długo, jak działa z jakimś kompilatorem na pewnym komputerze, odpowiedź jest uważana za poprawną.
Dennis
2

R: 72 67 65

Funkcja

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

Dzięki @AlexA i @plannapus za oszczędności

Testowe uruchomienie

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
MickyT
źródło
Liczę obecnie 70 bajtów w ciele funkcji, a nie 72. Ale możesz sprowadzić go do 67 za pomocą d=as.double(strsplit(toString(a),"")[[1]]);!(anyNA(a%%d)|sum(a%%d)). :)
Alex A.,
@AlexA. Dzięki. Jedna z moich pierwszych prób z R. Willem na pewno
wrócę
@MickyT paste(a)zamiast toString(a)daje ten sam wynik.
plannapus
@plannapus Dzięki, schludna mała sztuczka. Musisz o tym pamiętać
MickyT,
1

GNU Awk: 53 znaki

Policzona część:

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

Cała funkcja:

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

    return ! r
}

Ponieważ Awk nie ma wartości boolowskich, zwraca 1 tor true i 0 dla false.

człowiek w pracy
źródło
1

JavaScript (ES6) 30

Funkcja z jednym parametrem numerycznym. Używając% i odejmowania, nie trzeba specjalnego przypadku „0”, ponieważ 0% 0 to NaN w JavaScript.

Edytuj Zapisano 1 znak dzięki DocMax

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

Dla zabawy, nadużywanie zasady nie liczenia podpisu funkcji, 4

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

Testuj w konsoli FireFox / FireBug

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

Wynik

128 -> true
12 -> true
120 -> false
122 -> true
13 -> false
32 -> false
22 -> true
42 -> false
212 -> true
213 -> false
162 -> true
204 -> false
edc65
źródło
Powiem „nie” wprowadzaniu łańcucha.
Mathew Kirschbaum
1
Konsola Firefox jest zadowolona z zamiany na of(t=n+'')of t=n+''
opcję
1

PHP: 85 bajtów (64 bajty na ciele)

Aby ta funkcja działała, wystarczy przekazać ciąg znaków lub liczbę.

0 poprawnie zwróci false.

Kod:

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

NIE USTAWAJ II PARAMETRU!

JavaScript: 76 bajtów (61 bajtów w treści)

Jest to przepisanie poprzedniej funkcji.

Niewiele zmieniło się między obiema wersjami.

Oto 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 bajty (76 84 bajty bez płyty grzewczej):

Dlaczego to zrobiłem?

Z powodu, a może dlatego, że mogę!

Zignoruj ​​błąd w PHP: i tak działa!
Nie jest już potrzebny, został naprawiony przez usunięcie 3 bajtów.

Oto arcydzieło:

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

Możesz uruchomić ten kod zarówno na konsoli, jak i na tłumaczu PHP!


Stara wersja:

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);}
Ismael Miguel
źródło
„i przekazuje tylko jeden parametr numeryczny”. Bez tego możesz ewaluować ($ x) i przekazać cały kod w $ x
abc667
@ abc667 Przepraszam, ale nie rozumiem.
Ismael Miguel
1

Oktawa, 33 (39 łącznie z konfiguracją funkcji)

Korzystanie z konwersji numerycznej na macierz:

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

Podziel liczbę elementarnie przez macierz X, gdzie X jest tworzony przez konwersję liczby na ciąg i odejmowanie 48, aby ponownie przejść od wartości ASCII do liczb. Weź modulo 1, aby uzyskać część dziesiętną każdego podziału, potwierdź, że wszystkie są zerowe (jeśli jakieś są NaN z powodu / 0, suma będzie NaN, a zatem nie zero).

Przykładowe dane wejściowe przy użyciu 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

Wynik:

ans =  1
ans =  1
ans = 0
ans =  1
ans = 0
ans = 0
ans =  1
ans = 0
ans =  1
ans = 0
ans =  1
ans = 0
Jørgen
źródło
Jak możemy to przetestować?
Ismael Miguel
octave-online.net - wprowadź definicję kodu z góry, a następnie (na przykład) f (128). Dodaje dane wyjściowe
Jørgen
Znalazłem kompilator i wypróbowałem go, zanim zapytałem. Ale wydaje się, że działa dobrze (z wyjątkiem f(123), który można podzielić przez 1, 2 i 3). Ale to działa dla podanych przypadków testowych.
Ismael Miguel
1

MATLAB - 39 znaków

function [b] = dividesSelf(i)
b=all(~mod(i,sscanf(num2str(i),'%1d')))
end
Bastian35022
źródło
1

BASH - 117 znaków

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

testy

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
Brian
źródło
1

PHP - 74 71 64 znaków

Gra w golfa:

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

Mniej gra w golfa:

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

Wyniki testu:

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

(Wynik)

128 -> True
12 -> True
120 -> False
122 -> True
13 -> False
32 -> True
22 -> True
42 -> True
212 -> True
213 -> True
162 -> False
204 -> False
JPMC
źródło