È un numero divisibile per ciascuna delle sue cifre?


47

Io e il mio amico stavamo lavorando in un laboratorio nella nostra classe AP Computer Science e abbiamo deciso di programmare il golf uno dei problemi dato che dopo la fine avevamo ancora metà della lezione gratuita. Ecco la domanda:

Dato un numero n, n è divisibile per ciascuna delle sue cifre?

Ad esempio, 128 supererà questo test: è divisibile per 1,2 e 8. Qualsiasi numero con zero esclude automaticamente il numero. Anche se puoi usare altre lingue e pubblicare soluzioni con loro, se lo desideri, siamo più interessati a vedere come le persone compatte possono creare il programma in Java, poiché questa è la lingua che usiamo nella classe. Finora, abbiamo entrambi 51. Ecco il mio codice attuale:

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.

Requisiti

La firma del metodo può essere quella che vuoi. Basta contare il corpo della funzione. Assicurati, tuttavia, che il metodo restituisca un valore booleano e passi solo un parametro numerico (non una stringa).

Il codice deve essere in grado di trasmettere tutti questi casi (al fine di rimanere fedeli alle direzioni della domanda iniziale, solo contano i valori veri e falsi booleani se i supporti linguistici booleani. Se e solo se la lingua non ha variabili booleane voi può rappresentare false con 0 e true con qualsiasi numero intero diverso da zero (preferibilmente 1 o -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

Inoltre, non abbiamo contato gli spazi bianchi, quindi sentiti libero di fare lo stesso, a meno che lo spazio bianco sia essenziale per il funzionamento del programma (quindi le nuove righe in Java non contano, ma un singolo spazio tra inte x=1conta.) Buona fortuna !


18
Benvenuti in PPCG! Alcuni suggerimenti: 1. Non contare gli spazi bianchi funzionali è una cattiva idea. Qualsiasi risposta scritta in Whitespace vincerà automaticamente. 2. Qualora la nostra stampa di presentazione / ritorno truee falseo sono truthy / falsy valori OK pure? 3. Il javatag non si applica qui, poiché la sfida in sé non è correlata a Java.
Dennis,

Va bene. scusa per i problemi. Giusto per chiarire, considereresti funzionale lo spazio in 'int p = n', perché non l'ho fatto in precedenza. Risolverò le altre questioni che hai sottolineato.
Mathew Kirschbaum,

5
Tutto lo spazio richiesto per il funzionamento del codice è funzionale.
FryAmTheEggman,

Va bene, grazie per la risposta!
Mathew Kirschbaum,

1
@RickyDemer: poiché 0 sarebbe un input eccezionale in quel caso (è l'unico numero con 0cifre che è un multiplo di ciascuno di essi), immagino che la maggior parte delle risposte si allungherebbe in modo poco interessante per includere un controllo per esso. Quindi mi piace il problema posto meglio dal titolo (divisibile per le sue cifre, piuttosto che essere un multiplo delle sue cifre, che esclude 0).
Jeroen Mostert,

Risposte:


23

Perl 6, 13

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

Utilizza la variabile implicita $_- $_ %% .comb.allequivale a $_ %% all($_.comb). %%è l'operatore "è divisibile" e combsenza alcun argomento aggiuntivo restituisce un elenco di caratteri in una stringa. Ad esempio, se l'argomento è 123, la funzione viene valutata

123 %% all(123.comb)

che è

123 %% all(1, 2, 3)

junction autothreading lo rende

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

che è

all(True, False, True)

che è falso in un contesto booleano perché è una giunzione "tutto" e chiaramente non tutti i suoi elementi sono veri.

Dovrebbe essere possibile forzare il valore restituito Boole nascondere la giunzione dai chiamanti creando la firma della funzione sub golf($_ --> Bool()), ma le coercizioni nelle firme delle funzioni non funzionano ancora in Rakudo. Il valore restituito è ancora correttamente vero o falso, semplicemente no Trueo False.


Se vuoi farlo restituire un Boolaggiungi semplicemente soall'inizio del codice so$_%%.comb.all.
Brad Gilbert b2gills,

21

C # e System.Linq - 26/40

Secondo le regole, senza contare la dichiarazione del metodo stesso.

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

Dimostrando che ancora una volta, C # è la scelta migliore quando Java è in esame ... Ragazzino, ragazzino!

Sfortunatamente, questa funzione (e molte altre in risposte) non produrrà risultati corretti per input negativi. Possiamo risolvere questo problema, ma la soluzione perde molto del suo fascino (e raggiunge i 46 caratteri di lunghezza):

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

Modifica : rasato un personaggio con il suggerimento di Tim.

Modifica : con l'introduzione dei membri corposi di espressione in C # 6, possiamo ridurlo ulteriormente tagliando return:

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

per un totale di 26 caratteri (a mio avviso, =>non dovrebbero essere inclusi più di quanto sarebbero le parentesi graffe). La versione che gestisce i numeri negativi può essere abbreviata in modo simile.


Perché .0? Non è necessario altro che il modulo intero.
Peter Taylor,

3
@PeterTaylor: C'è se vuoi il programma più breve - i % 0con iun numero intero dà a DivideByZeroException.
Jeroen Mostert,

2
E con un doppio dà NaN! Bello!
Peter Taylor,

2
48dè lo stesso di 48.0, ma un carattere in meno (d per doppio).
Tim S.

1
@StuartLC: i lambda non sono metodi; il loro scopo è diverso, quindi penso che questo stia piegando troppo le regole. Ma poiché C # 6 (che precede questa risposta), abbiamo membri corposi di espressione, che ci permettono di abbreviare la definizione. Per il caso negativo, non possiamo usare &, proprio perché &non cortocircuita - otterrai una divisione per zero eccezione sul %. Possiamo risolverlo trasformandolo in un doppio (con d), ma poi abbiamo perso di nuovo un personaggio.
Jeroen Mostert,

18

APL ( 13 11)

(apparentemente le parentesi non contano)

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

Spiegazione:

  • ⍎¨⍕⍵: valuta ogni carattere nella rappresentazione di stringa di
  • ⍵|⍨: per ognuno di questi, trova il modulo e
  • 0∧.=: vedi se tutti sono uguali a 0

Casi test:

      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 può fare X%0? senza lanciare?
Ottimizzatore,

@Optimizer: si. 0|XX.
Marin il

Dolce. Anche la tua risposta è di 11 byte, non di 13
Optimizer,

9
Solo APL non darebbe un errore su modulo di 0 e si arresterebbe in modo anomalo nel valutare un non bool come bool;)
FryAmTheEggman

3
Un personaggio più corto con un treno invece di dfn:(0∧.=⍎¨∘⍕|⊢)
ngn il

14

Python 2: 43 caratteri

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

Verifica se il numero ha resti diversi da zero nel modulo e ne genera la negazione. Le cifre zero sono gestite in modo strano: poiché il calcolo %0causa un errore, le cifre di 0vengono sostituite con .3, il che sembra dare sempre un risultato diverso da zero a causa di imprecisioni in virgola mobile.

Il corpo della funzione è di 32 caratteri.


14

Perl - 27 byte

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

Senza contare la firma della funzione, come indicato.

Esempio di utilizzo:

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

Uscita campione:

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

Affrontare la specifica del problema: "Conta solo i valori booleani true e false. I valori di verità / false non contano."

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

Uscite:

1
""

'Vero' e 'Falso' sono definiti come 1e "".

Errore:
Come giustamente sottolinea Brad Gilbert , perl definisce true come uno scalare che è sia l'intero 1che la stringa "1"contemporaneamente, e false come uno scalare che è sia l'intero 0che la stringa ""contemporaneamente.


Questo può essere abbreviato non usando $_: pop=~s///ger<1. Non so se l'OP lo concorderà 1e ""saranno risultati validi. In caso contrario, può essere corretto con altri due byte: basta aggiungere |0.
hvd,

perl -pe'$_=s/./!$&||$_%$&/ger<1|0'è di 26 byte incluso il flag |0e -p. Non devi usare una funzione.
hmatt1,

1
In realtà i valori Vero e Falso sono più simili a dualvar(1,'1')e dualvar(0,'').
Brad Gilbert b2gills,

1
@BradGilbert È interessante. Ho ragionevolmente familiarità con i perlgut, ma non ero consapevole del fatto che il vero e il falso fossero speciali. In realtà sono "triple scalars", contrassegnati come SVIV(int), SVNV(double) e SVPV(string).
primo

1
In realtà la prima volta che usi una stringa come numero o un numero come stringa, la variabile viene modificata per contenere quei dati aggiuntivi. È per questo che si ottiene solo un avvertimento la prima volta che si utilizza 'abc'come un numero (ammesso che abbiate use warnings;abilitato.)
Brad Gilbert b2gills

13

CJam, 11 10 byte

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

Questo definisce una funzione denominata Fe scarta il blocco dallo stack.

Provalo online.

Casi test

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

Come funziona

_      " 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 aveva le funzionalità che hai usato per la soluzione a 10 byte quando è stata scritta la domanda?
Lirtosiast

@ThomasKwa: Sì, lo ha fatto. Ho testato il codice nella versione 0.6.2, che è stato rilasciato nel luglio 2014.
Dennis

12

JavaScript ES6, 39 32 28 byte

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

Grazie core1024 per il suggerimento di sostituire (""+v).split("")con [...""+v], e openorclose per suggerire l'uso della everyfunzione.

La risposta attualmente non contiene un bit del mio codice: O

Soluzione precedente

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

==""non è un modo valido per verificare se un array è vuoto, poiché [""]==""restituisce true, ma è garantito che l'array contenga una stringa non vuota, quindi funziona qui.

Il resto è una conversione abbreviata del tipo standard in JavaScript.


1
Puoi salvare alcune caratteristiche sostituendole (""+v).split("")con [...""+v].
core1024,

1
Perché non usare il everymetodo? v=>[...""+v].every(x=>v%x<1);
openorclose il

@openorclose: grazie. Non ho mai avuto la possibilità di usarlo in JS, quindi non ho mai pensato di cercare tale funzione.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

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

@ l4m2 Dal momento che v%0restituisce NaNe NaN == false, quindi, nel tuo caso i numeri che contiene 0, come ad esempio 10, possono restituire true.
Shieru Asakoto il

9

Java 8, 46 byte (corpo del metodo)

Utilizzando la conversione di Jeroen Mostert in doppio trucco.

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

8

Pyth, 12 byte

!f|!vT%vzvTz

Questo filtra i caratteri nella stringa per essere zero ( !vT) o non dividendo l'input ( %vzvT), quindi accetta il logico non dell'elenco risultante.

Provalo qui.


No, sto bene se non viene utilizzata una funzione. Volevo solo far notare a chiunque stesse usando funzioni che non avevano bisogno di contare la dichiarazione, e solo il codice all'interno.
Mathew Kirschbaum,

8

Rubino, 44 ​​byte (corpo della funzione: 37)

Probabilmente ha il potenziale per essere ulteriormente golfato.

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

Ingresso preso attraverso la funzione f. Esempio di utilizzo:

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

1
È possibile passare .to_ia .hex, poiché i numeri a una cifra sono gli stessi nella base 16 e possono cambiare ==0in <1.
istocratico il

8

Python - 59 50 49 47 byte

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

Sono sicuro che c'è un modo più veloce ... vabbè.

Modifica - Grazie a FryAmTheEggman per i suggerimenti sul golf.

Modifica 2 - FryAmTheEggman potrebbe anche averlo scritto a questo punto, oops

Modifica 3 - Alzi la mano se non sapevi nemmeno che il genexps era una cosa. ...Solo io?


Oh grazie mille! Continuo a dimenticare tutte quelle cose. (Inoltre, non mi ero reso conto che in quel modo non avresti potuto fare altro che caratteri.)
Kasran,

Oh, capovolgere la logica sembra anche accorciarla un po ': f=lambda n:all([c>'0'and 0==n%int(c)for c in`n`]). E nessun problema :)
FryAmTheEggman,

Oh, non mi rendevo conto c'è anche stato un allmetodo.
Kasran,

Funzionerebbe 1>n%int(c)?
Sp3000,

3
Perché una comprensione di lista? Utilizzando un genexp: all(c>'0'and 0==n%int(c)for c in`n`)fa esattamente lo stesso, con 2 caratteri in meno e persino salvando l'allocazione della lista.
Bakuriu,

8

Pyth 11

!f%Q|vT.3`Q

Questo combina le risposte di @ isaacg e @ xnor . Filtra le cifre dall'input controllando il valore di input % (eval(current_digit) or .3). Quindi controlla se la stringa risultante è vuota o meno.

Sono imbattuto in un'altra coppia di varianti della stessa lunghezza:

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

Provalo online.


5

Bash + coreutils, 44 byte

La definizione completa della funzione è:

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

Non sono sicuro di come assegnare un punteggio poiché normalmente le funzioni della shell usano un singolo set di {}o ()per contenere il corpo della funzione. Ho trovato qui che potrei anche usare double (())per contenere il corpo della funzione che provoca un'espansione aritmetica che è ciò di cui ho bisogno qui. Quindi per ora sto contando solo una coppia di quelle parentesi - ulteriori discussioni su questo sono benvenute.

Produzione:

$ 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 - non mi è chiaro se 1 e 0 sono accettabili o se devo stampare true/ false?
Trauma digitale,

4

J - 14 caratteri

Il corpo della funzione è la parte dopo il =:. Se vogliamo ridurre al minimo il numero di caratteri per l'intera funzione, questo è il 15 caratteri */@(0=,.&.":|]).

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

,.&.":è il modo più breve in J di espandersi come numero in un elenco delle sue cifre decimali: convertire in stringa, separare le cifre e riconvertire ogni cifra in un numero. ,.&.":|]accetta il numero di input ( ]) modulo ( |) quelle cifre. 0*/@:=restituisce vero se tutti i risultati erano 0, altrimenti dà un falso.

   f 162
1
   f every 204 212 213
0 1 0

3

Java - 121 102 97 79 78 byte

So solo che questo verrà ostruito più tardi. Oh bene.

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

Tornerò.


1
Ora puoi nominare la tua funzione come preferisci. Ho modificato le regole in modo da contare solo i calcoli all'interno della funzione effettiva, ma la funzione deve restituire un tipo booleano. Quindi questo è attualmente a 86 caratteri.
Mathew Kirschbaum,

3

Haskell - 100 54 38

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

Ancora imparando, le critiche sono apprezzate


Ho avuto un commento qui, ma l'ho cancellato per sbaglio in qualche modo ... Comunque, alcuni suggerimenti: 1) Rilascia lengthi messaggi, sono inutili. 2) Sostituisci tcon la sua definizione. 3) elem y snon è necessario. 4) /='0'può essere spostato sul filtro sinistro, al posto di elem y s. 5) In questo caso, /='0'equivale a >'0', poiché ogni lettera è una cifra. 6) Inserisci i modbacktick, quindi diventa infix. 7) Metti tutto su una sola riga.
Zgarb,

1 e 3 provenivano da quando stavo cercando di farlo in un modo diverso e recuperato il codice. Grazie per i suggerimenti
lugubre

1
i miei suggerimenti: invece di utilizzare s==filter(...)sè necessario utilizzare all(...)s. ora, poiché sappare solo una volta nell'espressione, puoi sostituirlo con la sua definizione e rilasciarlo where. inoltre, al posto ==0tuo potresti usare <1.
orgoglioso haskeller il

grande miglioramento rispetto alla prima versione!
orgoglioso haskeller il

Penso che puoi ancora perdere un byte se lo sostituisci all(\y->...)$show xcon and[...|y<-show x].
Zgarb,

2

CJam, 15 byte

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

Questo è un blocco, la cosa più vicina a una funzione in CJam. Sto solo contando il corpo (cioè omettendo le parentesi graffe). Puoi usarlo come segue:

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

O se vuoi testare una serie di input, puoi farlo

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

Il blocco lascia 0(falsa) o 1(verità) in pila per indicare il risultato. (CJam non ha un tipo booleano.)

Provalo qui.

Spiegazione:

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

Alternativa, anche 15 byte

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

Spiegazione

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

{}è la cosa più vicina a una funzione in CJam. Sto solo contando il corpo della funzione

Usalo in questo modo:

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

Per ottenere 1(se il numero è divisibile) o 0(se il numero non è divisibile per le sue cifre).

Provalo online qui

Spiegazione

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

Potrei mancare qualcosa, ma dopo aver letto rapidamente su CJam, alcune cose sembrano non avere senso: come si Abdividono le cifre? Sembra semplicemente convertirlo in base 10. Inoltre, come fa% a sapere di modificare il numero e non solo la cifra successiva, dal momento che sembra che la cifra successiva sarebbe la prossima nello stack?
Mathew Kirschbaum,

Rispondere a tutte le tue domande sarà complicato. Sarebbe molto facile da imparare inserendo dopo ogni carattere nel codice. Prova a eseguire128{ed_edAedbedf{ed_ed{ed%ed}1ed?ed}ed1edbed!ed}~
Optimizer il

1
Risposte a domande particolari: fare la base 10 fornisce una matrice di numeri convertiti in base 10, che sono le cifre stesse in questo caso. %prendi semplicemente gli ultimi due numeri (in questo caso) e calcola la mod. Gli ultimi due numeri qui sono il numero e la cifra effettivi (sempre)
Ottimizzatore del

Ok, grazie per il consiglio!
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 non ha un tipo booleano. Spero che funzioni. Inoltre ho usato un secondo parametro per passare una copia del numero originale attraverso lo stack, ma la definizione può essere qualsiasi cosa. Per ottenere il risultato corretto devi solo chiamare la funzione con lo stesso valore per entrambi i parametri ( d(128, 128)).

EDIT: modifiche suggerite applicate da un utente anonimo


Dai un'occhiata a codegolf.stackexchange.com/review/suggested-edits/17160 , qualcuno ti ha dato alcuni suggerimenti sul golf
Giustino,

In particolare contro le regole. Un parametro.
edc65,

Sì, questo post è in realtà il motivo per cui ho deciso di fare quella regola, in quanto non sembrava giusto che l'utente dovesse fare la duplicazione invece del programma.
Mathew Kirschbaum

Immagino che dovrò aggiungere una funzione wrapper. La dichiarazione di quella funzione si aggiunge al conteggio dei byte?
MarcDefiant,

2

C11 - 44 byte nel corpo della funzione

Un'altra versione C, non ricorsiva e senza eccezioni in virgola mobile.

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

Funzionerà anche in C ++, Java e molti altri linguaggi simili a C.

Modificato per includere il miglioramento del commento di Primo.


1
Una versione che viene compilata in Java (1.7.0_45-b18):, int n=i;for(;i%10>0&&n%(i%10)<1;i/=10);return i<1;un byte più corto del codice dell'OP.
primo

2

Julia 32 25 23

Migliorato utilizzando le cifre

Risolve anche il problema con i numeri negativi

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

Vecchio metodo

Tutte le cifre si dividono se la somma di tutti i resti è 0. Come gli altri, ha un problema con i numeri negativi.

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

Produzione

[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

Il metodo migliorato gestisce anche BigInt

selfDivides(BigInt(11111111111111111111111111111111111111112))
true

però

selfDivides(BigInt(11111111111111111111111111111111111111113))
false

perché

BigInt(11111111111111111111111111111111111111113) %3
1

2

C / C ++, 58 byte (44 nel corpo)

Invoca un comportamento indefinito (vedi commenti)

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

truee false sono 1 e 0, ma sentiti libero di aggiungere un carattere alla firma per restituire a bool.

E per divertimento, una versione ricorsiva che è più piccola se si consentono le chiamate del modulo r(128,128)

Modifica : ora non consentito dalle regole:

C / C ++, 53 byte (33 nel corpo)

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


2
Il numero 1 muore con un'eccezione in virgola mobile per i numeri che contengono 0 perché j% (i% 10) sarà illegale per i% 10 = 0.
SBI,

Una virgola mobile eccezione? Strano. Funziona perfettamente sul mio compilatore ma hai ragione, è un comportamento indefinito. Non sono sicuro di quale sia la posizione generale del PCG sull'UB dipendente dal compilatore.
etheranger,

Che cos'è "UB dipendente dal compilatore"? O è UB o non lo è (e la divisione per zero, o piuttosto modulo zero, è effettivamente UB). UB non dovrebbe essere permesso perché letteralmente potrebbe succedere di tutto. Possiamo presumere che il tuo programma verrà eseguito su una macchina che esploderà e ucciderà tutti quelli che lo circondano quando si verifica una divisione per zero. Ora, sono sicuro che vuoi che tutti viviamo ... C ha un concetto di comportamento definito dall'implementazione, ma la divisione per zero non rientra in questo.
Jeroen Mostert,

2
@etheranger: Divisione per 0 si chiama eccezione virgola mobile per la ragione storica: stackoverflow.com/questions/16928942/...
n̴̖̋h̷͉a̷̭̿h̸̡̅ẗ̵̨d̷̰ĥ̷̳

2
@JeroenMostert: direi che oltre il 90% di tutte le risposte C su questo sito invoca UB. Finché funziona con alcuni compilatori su alcune macchine, la risposta è considerata valida.
Dennis,

2

R: 72 67 65

La funzione

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

Grazie a @AlexA e @plannapus per il risparmio

Prova

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

Conto 70 byte nel tuo corpo di funzione attualmente, non 72. Ma puoi farlo scendere a 67 usando d=as.double(strsplit(toString(a),"")[[1]]);!(anyNA(a%%d)|sum(a%%d)). :)
Alex A.

@AlexA. Grazie. Uno dei miei primi tentativi con R. Sarà sicuramente rivisitato :)
MickyT

@MickyT paste(a)invece di toString(a)dare lo stesso risultato.
plannapus,

@plannapus Grazie, piccolo trucco pulito. Devo ricordare che
MickyT

1

GNU Awk: 53 caratteri

La parte contata:

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

L'intera funzione:

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

    return ! r
}

Poiché Awk non ha valori booleani, restituisce 1 per true e 0 per false.


1

JavaScript (ES6) 30

Funzione con un parametro numerico. Utilizzando% e sottrazione, non è necessario il caso speciale '0' perché 0% 0 è NaN in JavaScript.

Modifica Salvato 1 carattere grazie a DocMax

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

Solo per divertimento, abusando della regola di non contare la firma della funzione, 4

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

Test nella console FireFox / FireBug

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

Produzione

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

Sto per dire di no all'inserimento di una stringa.
Mathew Kirschbaum,

1
La console di Firefox è felice della sostituzione di of(t=n+'')solo of t=n+''per salvare 1.
DocMax,

1

PHP: 85 byte (64 byte sul corpo)

Affinché questa funzione funzioni, è sufficiente passare una stringa o un numero.

0 restituirà correttamente falso.

Il codice:

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

Per favore, NON IMPOSTARE IL 2 ° PARAMETRO!

Javascript: 76 byte (61 byte sul corpo)

Questa è una riscrittura della funzione precedente.

Non è cambiato molto tra le due versioni.

Ecco il codice:

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

Poliglotta: Javascript + PHP 187 217 byte (76 84 byte senza boilerplate):

Perché l'ho fatto?

A causa della ragione e forse perché posso!

Ignora l'errore su PHP: funziona comunque!
Non più necessario, questo problema è stato risolto rimuovendo 3 byte.

Ecco il capolavoro:

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

Puoi eseguire questo codice sia sulla tua console che su un interprete PHP!


Vecchia versione:

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

"e passa solo in un parametro numerico". Senza questo puoi valutare ($ x) e passare l'intero codice in $ x
abc667

@ abc667 Siamo spiacenti, ma non capisco.
Ismael Miguel,

1

Octave, 33 (39 compresa l'impostazione delle funzioni)

Utilizzo della conversione da numerico a matrice:

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

Dividi il numero in modo elementale per matrice X, dove X viene creato convertendo il numero in stringa e sottraendo 48 per passare nuovamente dai valori ASCII ai numeri. Prendi il modulo 1 per ottenere la parte decimale di ogni divisione, conferma che tutti questi sono zero (se uno è NaN a causa di / 0, la somma sarà NaN e quindi non zero).

Input di esempio tramite 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

Produzione:

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

Come possiamo provarlo?
Ismael Miguel,

octave-online.net - inserisci la definizione del codice dall'alto e poi (ad esempio) f (128). Aggiungerà output
Jørgen

Avevo trovato il compilatore e l'ho provato prima di chiedere. Ma sembra funzionare bene (tranne f(123)che, che è divisibile per 1, 2 e 3). Ma funziona per i casi di test forniti.
Ismael Miguel,

1

MATLAB - 39 caratteri

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

1

BASH - 117 caratteri

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

test

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 caratteri

golfed:

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

Meno golfato:

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

Risultati del test:

(Codice)

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

(Produzione)

128 -> True
12 -> True
120 -> False
122 -> True
13 -> False
32 -> True
22 -> True
42 -> True
212 -> True
213 -> True
162 -> False
204 -> False
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.