Чи число ділиться на кожній його цифрі?


47

Ми з моїм другом працювали в лабораторії в нашому класі комп'ютерних наук AP і вирішили зашифрувати один з проблем, оскільки після закінчення ми все ще мали половину класу. Ось питання:

Враховуючи число n, чи поділяється n кожну його цифру?

Наприклад, 128 пройде цей тест - він ділиться на 1,2 та 8. Будь-які числа з нулем автоматично дискваліфікують число. Хоча ви можете використовувати інші мови та розміщувати з ними рішення, якщо вам подобається, ми найбільше зацікавлені в тому, як компактні люди можуть скласти програму на Java, як це мова, якою ми користуємось у класі. Поки у нас обох 51. Ось мій поточний код:

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.

Вимоги

Підпис методу може бути будь-яким, що ви хочете. Просто порахуйте тіло функції. Переконайтеся, що метод повертає булеве значення і передає лише один числовий параметр (а не рядок).

Код повинен бути в змозі передавати всі ці випадки (для того, щоб залишатись вірними вказівкам оригінального запитання, враховуються лише булеві істинні та помилкові значення, якщо мова підтримує булеві значення. Якщо і лише якщо ваша мова не має булевих змінних, ви може представляти помилкове з 0 та істинне з будь-яким ненульовим цілим числом (переважно, 1 або -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

Крім того, ми не враховували пробіли, тому не соромтесь робити те ж саме, якщо пробіл не є важливим для роботи програми (тому нові рядки на Java не враховуються, але єдиний пробіл між intі x=1не рахується.) Удачі !


18
Ласкаво просимо до PPCG! Кілька пропозицій: 1. Не рахуючи функціональних пробілів - це погана ідея. Будь-яка відповідь, написана в Whitespace , автоматично виграє. 2. Чи повинні наші матеріали надрукувати / повернути trueі falseчи добре також є значення " truthy / false" ? 3. javaТег дійсно не застосовується тут, оскільки сам виклик не пов'язаний з Java.
Денніс

Добре. вибачте за проблеми. Тільки для того, щоб прояснити це, чи вважаєте ви простір у "int p = n" функціональним, тому що раніше цього не робив. Я виправлю інші проблеми, на які ви вказали.
Матвій Кіршбаум

5
Все пробіли, необхідні для роботи коду, функціональні.
FryAmTheEggman

Гаразд, дякую за відповідь!
Матвій Кіршбаум

1
@RickyDemer: оскільки 0 в цьому випадку буде винятковою інформацією (це єдине число з 0цифрами, яке є кратним кожної з них), я думаю, що більшість відповідей просто не триватиме нецікавим чином, щоб включити чек на нього. Тож мені подобається, що проблема, поставлена ​​назви, краще (ділиться на її цифри, а не бути кратним її цифрам, що виключає 0).
Jeroen Mostert

Відповіді:


23

Перл 6, 13

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

Використовується неявна змінна $_- $_ %% .comb.allеквівалентна $_ %% all($_.comb). %%є оператором "ділиться" і combбез додаткових аргументів повертає список символів у рядку. Наприклад, якщо аргумент 123, то функція оцінює

123 %% all(123.comb)

який

123 %% all(1, 2, 3)

з'єднання автопоточення робить це

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

який

all(True, False, True)

що в булевому контексті помилково, тому що це перехід "все" і, очевидно, не всі його елементи є істинними.

Повинно бути можливим примусити повернути значення Boolта приховати з'єднання від викликаючих, зробивши функцію підпису sub golf($_ --> Bool()), але примушення в підписах функції ще не працюють у Ракудо. Повернене значення все-таки правильно істинне або помилкове, воно просто ні Trueабо False.


Якщо ви хочете змусити його повернути Boolпросто додавання soна передню частину коду so$_%%.comb.all.
Бред Гілберт b2gills

21

C # і System.Linq - 26/40

Відповідно до правил, не рахуючи самого оголошення декларації.

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

Показавши це ще раз, C # - це найкращий вибір, коли розглядається Java ... Я малюк, я дитина!

На жаль, ця функція (і багато інших відповідей) не дасть правильних результатів для негативного введення. Ми можемо це виправити, але рішення втрачає багато своєї чарівності (і зростає до 46 символів):

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

Редагувати : побрив один символ із пропозицією Тіма.

Редагувати : із введенням виразних членів у C # 6, ми можемо це ще більше зменшити, вирізавши return:

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

в цілому 26 символів (на мою думку, =>не слід включати більше, ніж дужки). Аналогічно можна скоротити версію, що обробляє негативні цифри.


Чому .0? Немає нічого іншого, крім цілого модуля.
Пітер Тейлор

3
@PeterTaylor: Є, якщо ви хочете найкоротшу програму - i % 0з iцілим числом дає а DivideByZeroException.
Jeroen Mostert

2
І з подвійною це дає NaN! Приємно!
Пітер Тейлор

2
48dтакий же, як 48.0, але один символ менше (d для подвійного).
Тім С.

1
@StuartLC: лямбда - це не методи; сфера їх застосування різна, тому я думаю, що це занадто далеко згинає правила. Але оскільки C # 6 (на що ця відповідь передує), ми маємо виражених членів, які дозволяють нам скоротити визначення. У негативному випадку ми не можемо використовувати &саме через &коротке замикання - ви отримаєте ділення на нульовий виняток на %. Ми можемо це виправити, зробивши його подвійним (з d), але тоді ми знову втратили один символ.
Єроен Мостерт

18

APL ( 13 11)

(мабуть, дужки не враховуються)

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

Пояснення:

  • ⍎¨⍕⍵: оцініть кожен символ у рядковому поданні
  • ⍵|⍨: для кожного з них знайдіть модуль цього і
  • 0∧.=: подивіться, чи всі вони рівні 0

Тести:

      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 може зробити X%0? не кидаючи?
Оптимізатор

@Optimizer: так. 0|Xдає X.
marinus

Солодке. Також ваша відповідь - 11 байт, а не 13
Оптимізатор

9
Тільки APL не дасть помилку по модулю на 0, і збій при оцінці не-bool як bool;)
FryAmTheEggman

3
Один символ коротший із поїздом замість dfn:(0∧.=⍎¨∘⍕|⊢)
ngn

14

Пітон 2: 43 символи

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

Перевіряє, чи число має будь-які ненульові залишки за модулем його цифр, і видає заперечення цього. Нульові цифри обробляються дивним чином: оскільки обчислення %0викликає помилку, цифри 0замінюються на .3, що, здається, завжди дає ненульовий результат через неточності плаваючої точки.

Орган функції - 32 символи.


14

Perl - 27 байт

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

Не рахуючи підпис функції, як вказується.

Використання зразка:

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

Вибірка зразка:

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

Звернення до специфікації проблеми: "Розраховуються лише булеві істинні та помилкові значення. Значення Truthy / Falsey не враховуються."

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

Виходи:

1
""

'True' і 'False' визначаються як 1і "".

Помилка:
Як справедливо зазначає Бред Гілберт , perl визначає істину як скаляр, який є одночасно і цілим числом, 1і рядком "1", і false як скаляр, який є одночасно цілим 0і рядком "".


Це може бути скорочений, не використовуючи $_: pop=~s///ger<1. Я не знаю, чи погодиться ОП з цим 1і ""чи справжні результати. Якщо ні, то це можна виправити ще двома байтами: просто додайте |0.
hvd

perl -pe'$_=s/./!$&||$_%$&/ger<1|0'становить 26 байт, включаючи прапор |0і -p. Вам не потрібно використовувати функцію.
hmatt1

1
Насправді істинні та хибні значення більше схожі dualvar(1,'1')та dualvar(0,'').
Бред Гілберт b2gills

1
@BradGilbert Це цікаво. Я досить добре знайомий з пергутами, але я не знав, що справжнє і хибне є спеціальним випадком. Вони насправді є "потрійними скалярами", позначеними як SVIV(int), SVNV(double) та SVPV(string).
прим

1
Насправді, коли ви використовуєте рядок як число або число як рядок, змінна змінюється, щоб утримувати ці додаткові дані. Ось чому ви отримуєте лише попередження, коли ви вперше використовуєте їх 'abc'як число (якщо припустити, що ви use warnings;увімкнули.)
Бред Гілберт b2gills

13

CJam, 11 10 байт

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

Це визначає функцію, названу Fі відкидає блок від стека.

Спробуйте в Інтернеті.

Тестові справи

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

Як це працює

_      " 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 функції, які ви використовували для 10-байтового рішення, коли запитання було написане?
lirtosiast

@ThomasKwa: Так. Я перевірив код у версії 0.6.2, яка вийшла в липні 2014 р.
Денніс

12

JavaScript ES6, 39 32 28 байт

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

Спасибі core1024 за пропозицію замінити (""+v).split("")з [...""+v], і openorclose для припускаючи використання everyфункції.

Зараз відповідь не містить жодного біта мого коду: O

Попереднє рішення

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

==""не є коректним способом перевірити, чи масив порожній, оскільки [""]==""повертається true, але масив гарантовано містить не порожній рядок, тому він працює тут.

Решта - це досить стандартне скорочення типу JavaScript.


1
Ви можете зберегти деякі символи, замінивши (""+v).split("")на [...""+v].
core1024

1
Чому б не скористатися everyметодом? v=>[...""+v].every(x=>v%x<1);
openorclose

@openorclose: Дякую Ніколи не було можливості використовувати його в JS, тому я ніколи не думав шукати таку функцію.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

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

@ L4m2 Оскільки v%0повертається NaNі NaN == false, таким чином , в вашому випадку чисел , який містить 0, наприклад 10, може повернутися true.
Шиеру Асакото

9

Java 8, 46 байт (тіло методу)

Використання перетворення Джерона Мостерта на подвійний трюк.

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

8

Pyth, 12 байт

!f|!vT%vzvTz

Це фільтрує символи в рядку за тим, що вони є нульовими ( !vT) або не поділяють вхідні дані ( %vzvT), а потім приймає логічне значення не з отриманого списку.

Спробуйте тут.


Ні, я добре, якщо функція не використовується. Я просто хотів вказати на когось, хто використовував функції, що їм не потрібно рахувати декларацію, а лише код всередині.
Матвій Кіршбаум

8

Ruby, 44 байти (функціональне тіло: 37)

Ймовірно, є потенціал для подальшого гольфу.

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

Вхід, взятий через функцію f. Приклад використання:

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

1
Ви можете змінити , .to_iщоб .hex, так як однорозрядні числа збігаються в базі 16, і може змінюватися ==0в <1.
гістократ

8

Пітон - 59 50 49 47 байт

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

Я впевнений, що є більш швидкий шлях ... ну добре.

Редагувати - Дякую FryAmTheEggman за поради щодо гольфу.

Редагувати 2 - FryAmTheEggman, можливо, також написав це в цей момент, на жаль

Edit 3 - Руки вгору, якщо ви навіть не знали, що genexps - річ. ...Тільки я?


О, велике спасибі! Я все забуваю про всі ці речі. (Я також не розумів, що ти можеш менше, ніж символів таким чином.)
Касран,

О, гортати логіка також , здається, скоротити його трохи: f=lambda n:all([c>'0'and 0==n%int(c)for c in`n`]). І жодних проблем :)
FryAmTheEggman

О, я не розумів , що навіть бувall метод.
Касран

Було б 1>n%int(c)працювати?
Sp3000

3
Чому розуміння списку? Використання genexp: all(c>'0'and 0==n%int(c)for c in`n`)робить точно так само, з 2 знаками менше і навіть заощаджує розподіл списку.
Бакуріу

8

Піт 11

!f%Q|vT.3`Q

Це поєднує в собі відповіді @ isaacg та @ xnor . Він фільтрує цифри з вхідних даних, перевіряючи значення input % (eval(current_digit) or .3). Потім він перевіряє, чи є порожній рядок порожнім чи ні.

Натрапив на ще пару варіантів однакової довжини:

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

Спробуйте в Інтернеті.


5

Bash + coreutils, 44 байти

Повне визначення функції:

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

Я не впевнений, як оцінити це, оскільки зазвичай функції оболонки використовують один набір {}або ()містять тіло функції. Я знайшов тут, я міг би також використовувати подвійний, (())щоб містити тіло функції, яке викликає арифметичне розширення, і це те, що мені тут потрібно. Тож наразі я рахую лише одну пару цих дужок - подальше обговорення цього питання вітається.

Вихід:

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

Ага - мені незрозуміло, чи прийнятні 1 і 0, чи потрібно друкувати true/ false?
Цифрова травма

4

J - 14 char

Органом функції є ділянка після =:. Якщо ми хочемо мінімізувати кількість символів для всієї функції, це 15 символів */@(0=,.&.":|]).

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

,.&.":- це найкоротший шлях у J розширити як число до списку його десяткових цифр: перетворити на рядок, розділити цифри та перетворити кожну цифру назад у число. ,.&.":|]приймає вхідне число ( ]) по модулю ( |) ці цифри. 0*/@:=повертає істину, якщо всі результати були 0, інше дає помилкове.

   f 162
1
   f every 204 212 213
0 1 0

3

Java - 121 102 97 79 78 байт

Я просто знаю, що це згортається пізніше. Ну добре.

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

Я повернуся.


1
Тепер ви можете називати свою функцію все, що завгодно. Я змінив правила, щоб ви підраховували лише обчислення всередині фактичної функції, але функція повинна повертати булевий тип. Так що наразі 86 символів.
Матвій Кіршбаум

3

Хаскелл - 100 54 38

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

Ще навчаючись, оцінювали критику


У мене тут був коментар, але я випадково його якось видалив ... У всякому разі, кілька пропозицій: 1) Киньте lengths, вони непотрібні. 2) Замініть tйого визначенням. 3) elem y sнепотрібне. 4) /='0'можна перемістити на лівий фільтр, замість elem y s. 5) У цьому випадку /='0'рівнозначно >'0', оскільки кожна буква є цифрою. 6) Поставте modбекстик, щоб він став інфіксом. 7) Поставте все в один рядок.
Згарб

1 і 3 були з тих пір, коли я намагався зробити це по-іншому і пошкодив код. Дякую за поради.
глоббі

1
мої пропозиції: замість використання s==filter(...)sви повинні використовувати all(...)s. тепер, оскільки sв виразі з’являється лише один раз, ви можете замінити його визначенням і випаданням where. також замість ==0вас можна було б використовувати <1.
гордий haskeller

велике поліпшення від першої версії!
гордий haskeller

Я думаю, ви все одно можете втратити один байт, якщо заміните all(\y->...)$show xна and[...|y<-show x].
Згарб

2

CJam, 15 байт

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

Це блок, найближчий до функції у CJam. Я лише рахую тіло (тобто опускаю брекети). Ви можете використовувати його наступним чином:

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

Або якщо ви хочете перевірити серію входів, ви можете зробити

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

Блок залишає 0(фальшивий) або 1(truthy) на стеці, щоб вказати на результат. (CJam не має булевого типу.)

Перевірте це тут.

Пояснення:

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

Альтернативно, також 15 байт

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

Пояснення

: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 байт

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

{}є найближчим до функції у CJam. Я просто рахую тіло функції

Використовуйте його так:

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

Отримати або 1(якщо число ділиться), або 0(якщо число не ділиться його цифрами).

Спробуйте його онлайн тут

Пояснення

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

Можливо, мені щось не вистачає, але після швидкого читання на CJam, деякі речі, здається, не мають сенсу: як Abподіляються цифри? Здається, просто перетворити його в базу 10. Крім того, як% знає мод за кількістю, а не лише наступною цифрою, оскільки здається, що наступна цифра буде наступною на стеку?
Mathew Kirschbaum

Відповісти на все ваше запитання буде складно. Це було б дуже легко дізнатися, додавши редактор після кожного символу в код. Спробуйте запустити128{ed_edAedbedf{ed_ed{ed%ed}1ed?ed}ed1edbed!ed}~
Оптимізатор

1
Відповіді на конкретні запитання: виконання бази 10 дає масив базових 10 перетворених чисел, які є самими цифрами в цьому випадку. %просто візьміть останні два числа (в даному випадку) і обчисліть мод. Останні два числа тут - фактичне число та цифра (завжди)
Оптимізатор

Гаразд, дякую за пораду!
Матвій Кіршбаум

2

C89, 43 байти

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

C89 не має булевого типу. Сподіваюся, що це працює. Також я використовував другий параметр, щоб передати копію вихідного номера через стек, але визначення може бути будь-яким. Для отримання правильного результату потрібно просто викликати функцію з однаковим значенням для обох параметрів ( d(128, 128)).

EDIT: застосовано запропоновані зміни анонімного користувача


Погляньте на codegolf.stackexchange.com/review/sugges-edits/17160 , хтось дав вам кілька пропозицій щодо гольфу
Джастін

Зокрема, проти правил. Один параметр.
edc65

Так, ця публікація насправді саме тому я вирішив прийняти це правило, оскільки не здавалося правильним, що користувач повинен робити дублювання замість програми.
Mathew Kirschbaum

Я думаю, мені доведеться додати функцію обгортки. Чи додає цю функцію до числа байтів?
MarcDefiant

2

C11 - 44 байти у функціональному тілі

Ще одна версія C, не рекурсивна і без винятку з плаваючою комою.

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

Це також працюватиме на C ++, Java та більшості інших мов, схожих на C.

Відредаговано, щоб включити покращення коментаря примі.


1
Версія, яка компілюється в Java (1.7.0_45-b18):, на int n=i;for(;i%10>0&&n%(i%10)<1;i/=10);return i<1;один байт коротше коду OP.
прим

2

Юлія 32 25 23

Удосконалено за допомогою цифр

Також виправляється проблема з від’ємними числами

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

Старий метод

Усі цифри діляться, якщо сума всіх залишків дорівнює 0. Як і інші, є проблема з від'ємними числами.

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

Вихід

[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

Удосконалений метод також обробляє BigInt

selfDivides(BigInt(11111111111111111111111111111111111111112))
true

проте

selfDivides(BigInt(11111111111111111111111111111111111111113))
false

оскільки

BigInt(11111111111111111111111111111111111111113) %3
1

2

C / C ++, 58 байт (44 в тілі)

Викликає не визначену поведінку (див. Коментарі)

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

trueі false є 1 і 0, але сміливо додайте один символ до підпису, щоб повернути а bool.

Для розваги - рекурсивна версія, яка менша, якщо ви дозволяєте дзвінки форми r(128,128)

Редагувати : тепер заборонено правилами:

C / C ++, 53 байти (33 в корпусі)

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


2
# 1 вмирає з винятком з плаваючою комою для чисел, що містять 0, тому що j% (i% 10) буде незаконним для i% 10 = 0.
SBI

З плаваючою точкою винятком? Дивно. Він прекрасно працює на моєму компіляторі, але ти маєш рацію, це невизначена поведінка. Не впевнений, яка загальна позиція PCG щодо залежного від компілятора UB.
etheranger

Що таке "UB-залежний від компілятора"? Або це UB, або його немає (і ділення на нуль, а точніше за модулем нуль, справді є UB). Не можна допускати УБ, тому що буквально все може статися. Ми можемо припустити, що ваша програма буде працювати на машині, яка підірве і вб'є всіх навколо неї, коли станеться поділ на нуль. Тепер я впевнений, що ви хочете, щоб ми всі жили ... C має концепцію поведінки, визначеної реалізацією, але поділ на нуль не підпадає під це.
Jeroen Mostert

2
@etheranger: Поділ на 0 називається виключення з плаваючою точкою з історичних причин: stackoverflow.com/questions/16928942 / ...
n̴̖̋h̷͉a̷̭̿h̸̡̅ẗ̵̨d̷̰ĥ̷̳

2
@JeroenMostert: Я б сказав, що понад 90% усіх відповідей C на цьому веб-сайті посилаються на UB. Поки вона працює з деяким компілятором на якійсь машині, відповідь вважається вірною.
Денніс

2

R: 72 67 65

Функція

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

Завдяки @AlexA та @plannapus за заощадження

Тестовий запуск

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

Я нараховую 70 байтів у вашому функціональному тілі, а не 72. Але ви можете зменшити його до 67, використовуючи d=as.double(strsplit(toString(a),"")[[1]]);!(anyNA(a%%d)|sum(a%%d)). :)
Олексій А.

@AlexA. Дякую. Одна з моїх перших спроб з Р. обов'язково переглянеться :)
MickyT

@MickyT paste(a)замість того, щоб дати toString(a)той же результат.
планнапус

@plannapus Спасибі, акуратний маленький трюк. Потрібно пам’ятати про це
MickyT

1

GNU Awk: 53 символи

Відлічена частина:

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

Вся функція:

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

    return ! r
}

Оскільки Awk не має булевих значень, повертає 1 tor true та 0 false.


1

JavaScript (ES6) 30

Функція з одним числовим параметром. Використовуючи% і віднімання, немає необхідності в спеціальному регістрі "0", оскільки 0% 0 - це NaN в JavaScript.

Редагувати збережений 1 char thx DocMax

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

Просто для розваги, зловживаючи правилом про неврахування підпису функції, 4

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

Тест в консолі FireFox / FireBug

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

Вихід

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

Я скажу «ні» введенню рядка.
Mathew Kirschbaum

1
Консоль Firefox задоволена заміною, щоб of(t=n+'')просто of t=n+''заощадити 1.
DocMax

1

PHP: 85 байт (64 байти на корпусі)

Щоб ця функція працювала, просто передайте рядок або число.

0 правильно поверне помилкове.

Код:

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

Будь ласка, НЕ встановлюйте 2-й ПАРАМЕТР!

Javascript: 76 байт (61 байт на корпусі)

Це перезапис попередньої функції.

Не сильно змінилося між обома версіями.

Ось код:

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

Поліглот: Javascript + PHP 187 217 байт (76 84 байти без котла):

Чому я зробив це?

Через розум, а може і тому, що я можу!

Просто ігноруйте помилку на PHP: вона все одно працює!
Більше не потрібно, це було виправлено, видаливши 3 байти.

Ось шедевр:

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

Цей код можна запустити як на консолі, так і на інтерпретаторі PHP!


Стара версія:

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

"і передається лише в одному числовому параметрі". Без цього ви можете зрівнятись ($ x) та передати весь код у $ x
abc667

@ abc667 Вибачте, але я не розумію.
Ісмаїл Мігель

1

Octave, 33 (39, включаючи налаштування функції)

Використання цифрового перетворення в матрицю:

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

Розділіть число поелементно за матрицею X, де X робиться перетворенням числа в рядок і відніманням 48, щоб знову перейти від значень ASCII до чисел. Візьміть модуль 1, щоб отримати десяткову частину кожного поділу, підтвердьте, що всі вони дорівнюють нулю (якщо такі є NaN через / 0, сума буде NaN і, отже, не дорівнює нулю).

Зразок введення даних за допомогою 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

Вихід:

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

Як ми можемо це перевірити?
Ісмаїл Мігель

octave-online.net - введіть визначення коду зверху, а потім (наприклад) f (128). Додасть вихід
Jørgen

Я знайшов компілятор і спробував його, перш ніж запитати. Але це, здається, працює добре (за винятком того f(123), що ділиться на 1, 2 і 3). Але це працює для наданих тестових випадків.
Ісмаїл Мігель


1

БАШ - 117 символів

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

тести

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 символів

Гольф:

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

Менш гольф:

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

Результати тесту:

(Код)

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

(Вихід)

128 -> True
12 -> True
120 -> False
122 -> True
13 -> False
32 -> True
22 -> True
42 -> True
212 -> True
213 -> True
162 -> False
204 -> False
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.