Trova la somma di tutti i numeri sotto n che sono un multiplo di alcuni gruppi di numeri


31

Quasi equivalente alla prima domanda del Project Euler:

Se elenchiamo tutti i numeri naturali al di sotto di 10 che sono multipli di 3 o 5, otteniamo 3, 5, 6 e 9. La somma di questi multipli è 23.

Trova la somma di tutti i multipli di 3 o 5 al di sotto di 1000.

Sfida:

Dato un numero intero positivo Ne un insieme di almeno un numero intero positivo A, genera la somma di tutti i numeri interi positivi inferiore a Nquella dei multipli di almeno un membro di A.

Ad esempio, per il caso di Project Euler, l'input sarebbe:

1000
3
5

Casi test:

Input : 50, [2]
Output: 600

Input : 10, [3, 5]
Output: 23

Input : 28, [4, 2]
Output: 182

Input : 19, [7, 5]
Output: 51

Input : 50, [2, 3, 5]
Output: 857

4
1) Contiamo i numeri che sono multipli di entrambi due volte? 2) Possiamo ottenere solo altri due numeri? o qualsiasi importo dire uno o 3?
Wheat Wizard

3
Puoi dare alcuni casi di test? Ovviamente non pubblicare la risposta a quella PE, ma per quanto riguarda altri esempi?
Rɪᴋᴇʀ

1
@WheatWizard: la parola "o" implica che ogni numero viene conteggiato una sola volta, al massimo. Concordo sul fatto che la domanda debba chiarire quanti argomenti "numeri da verificare per multipli di" debbano essere supportati. Esattamente due? Uno o più? Zero o più?
smls

1
Possiamo prendere " numeri uguali o inferiori a 10 " o prendere 9 come input anziché 10?
Stewie Griffin,

"e un insieme di almeno un intero positivo A" quanto può essere grande l'insieme?
Betseg,

Risposte:


13

Gelatina , 6 byte

ḍþṖḅTS

Provalo online!

Come funziona

ḍþṖḅTS  Main link. Left argument: D (array). Right argument: n (integer)

ḍþ       Divisible table; test each k in [1, ..., n] for divisibility by all
        integers d in D.
  Ṗ     Pop; discard the last Boolean array, which corresponds to n.
   ḅ    Unbase; convert the Boolean arrays of base n to integer. This yields a 
        non-zero value (truthy) and and only if the corresponding integer k is 
        divisible by at least one d in D.
    T   Truth; yield the array of all indices of truthy elements.
     S  Compute their sum.

3
Ovviamente @Dennis deve venire con qualcosa che ti farà meravigliare di quello che stai facendo su ppcg
Grajdeanu Alex.

8

Python, 59 55 byte

lambda n,l:sum(v*any(v%m<1for m in l)for v in range(n))

repl.it

Funzione senza nome che accetta un numero intero ne un elenco di numeri interi l. Attraversa un intervallo di numeri naturali (più zero) fino a ma non includendo ne somma ( sum(...)) quelli che hanno un resto dopo la divisione di zero ( v%m<1) per anyi numeri interi mnell'elenco l. Utilizza la moltiplicazione anziché un condizionale per salvare 3 byte.


8

Ottava, 38 36 33 byte

@(x,y)(1:--x)*~all(mod(1:x,y),1)'

Prendere input come: f(10, [3;5]). Questo sarebbe inferiore di 2 byte se l'input potrebbe essere f(9,[3;5])per lo stesso caso di test.

Verifica qui tutti i casi di test.


Spiegazione:

@(x,y)        % Anonymous function that takes two inputs, x and y
              % x is a scalar and y is a vertical vector with the set of numbers
(1:--x)*      % Pre-decrement x and create a vector 1 2 ... x-1    

Octave può pre-decrementare, quindi l'utilizzo al 1:--xposto di 1:x-1(due volte) consente di risparmiare due byte.

mod(a,b)1 2 0 1 2 0 1 2 0per mod(1:9,3). Se il secondo argomento è un vettore verticale, replicherà verticalmente il primo input e prenderà il modulo per ciascuno dei valori nel secondo argomento di input. Quindi, per input mod(1:9, [3;5])questo dà:

1 2 0 1 2 0 1 2 0
1 2 3 4 0 1 2 3 4

Assumendo ~all(_,1)ciò si ottengono truele colonne in cui almeno un valore è zero e falsedove tutti i valori sono diversi da zero:

~all(mod(1:x,y),1)
0 0 1 0 1 1 0 0 1

Il ,1è necessario nel caso in cui v'è un solo numero in y. Altrimenti agirebbe sull'intero vettore anziché sul numero per numero.

Trasponendolo a una matrice verticale e usando la moltiplicazione della matrice, ci darà la risposta corretta, senza la necessità di un sommario esplicito:


Oh, questo è crudele: ho dovuto aggiungere 2 byte a causa della differenza tra xe x – 1, ma dovevi aggiungere 4 byte, e ora sono in vantaggio di 1 byte> :)
Greg Martin

6

JavaScript (ES6), 40 39 36 byte

Input: intero ne array di numeri interi acon sintassi di curry(n)(a)

n=>F=a=>n--&&!a.every(v=>n%v)*n+F(a)

Casi test


Ho avuto una formulazione leggermente diversa per la stessa lunghezza: f=(n,a)=>n--&&a.some(v=>n%v<1)*n+f(n,a). Il meglio che potevo fare in modo non ricorsivo era di 61 byte.
Neil,

@Neil Il tuo commento mi ha incoraggiato a cercare un'altra formulazione. È interessante notare che la sintassi del curry salva 3 byte.
Arnauld,

5

MATL , 9 byte

q:ti\~*us

Provalo online!


1
Sto solo controllando se ho letto bene (senza controllare i documenti). Stai diminuendo, creando un vettore 1 2 .... Lo duplicate e prendete il modulo l'altro input. Lo annulli e ti moltiplichi con il vettore 1 2 .., usi unico per sbarazzarti dei duplicati e infine riassumendolo ...
Stewie Griffin,

Esattamente! Sono sul cellulare, quindi non ho incluso una spiegazione. Ora non è necessario :-)
Luis Mendo il


4

Python, 67 byte

a,b,c=input()
x=y=0
exec("if x%c<1or 1>x%b:y+=x\nx+=1\n"*a)
print y

Dopo aver scritto questo ho notato che il mio codice era simile alla risposta di Python esistente, tuttavia l'ho inventato in modo indipendente e lo sto pubblicando comunque.


Non è necessario il punto e virgola nel exec, dal momento che dopo un'interruzione di riga si verifica comunque. Sapevo che la mia risposta poteva essere superata!
Theo,

La specifica dice "un insieme di almeno un numero intero positivo"; questo sembra gestire solo il caso in cui l'insieme è di due numeri interi. Anche avere x=y=0su una riga separata risparmierebbe quattro byte.
Jonathan Allan,

@JonathanAllan, grazie mille!
Rɪᴋᴇʀ

4

Mathematica, 37 27 byte

Grazie a Martin Ender per un'osservazione accorta che ha portato a grandi risparmi di byte!

Tr[Union@@Range[#,#2-1,#]]&

Funzione senza nome che accetta due argomenti, un elenco #di numeri interi (i divisori desiderati A) e un numero intero #2(il limite superiore N) e che restituisce un numero intero. Range[#,#2-1,#]fornisce, per ciascun elemento ddell'elenco #, tutti i multipli di dminore o uguale a #-1(quindi inferiore a #); l'unione di queste liste viene quindi calcolata e sommataTr .

Versione precedente:

Tr[x=#;Union@@(Range[#,x-1,#]&/@#2)]&

1
Rangeè elencabile: Tr[Union@@Range[#2,#-1,#2]]&(e quindi salvare un altro byte scambiando l'ordine degli ingressi)
Martin Ender

4

Perl 6 , 25 byte

{sum grep *%%@_.any,^$^a}

Un lambda che accetta i numeri di input come argomenti. (Un argomento per N e un numero arbitrario di argomenti per A).

( Provalo online. )

Spiegazione:

  • { ... }: A lambda.
  • $^a: Primo argomento della lambda.
  • @_: Argomenti rimanenti della lambda ("parametro variadico").
  • ^$^a: Intervallo da 0a $^a - 1.
  • * %% @_.any: Un'altra lambda, che verifica la sua argomentazione *usando l'operatore divisibile per %%contro una any- Giunzione dell'elenco @_.
  • grep PREDICATE, RANGE: itera l'intervallo di numeri e restituisce quelli per i quali il predicato è vero.

Penso che l'aggiunta ^per dichiarare un parametro segnaposto sia abbastanza esplicita. Soprattutto perché potresti usarlo più avanti nel blocco come solo $a. Penso che solo $_ @_ %_ selfmai potrà essere considerato implicitamente dichiarato. Penso che avrei letto quella riga " dichiara il primo parametro come segnaposto "
Brad Gilbert b2gills

@ BradGilbertb2gills: intendevo dire che diventa implicitamente parte della firma della lambda, anche se il codice non ha introdotto una firma prima del corpo della lambda. @_e, %_nel caso delle funzioni, non differiscono da questo punto di vista: anch'essi diventano parte della firma solo se compaiono nel corpo. Solo $_ (e selfe %_nei metodi) può diventare parte di una firma per impostazione predefinita.
smls

PS: ora ho rimosso la frase "implicitamente dichiarata", poiché non è necessario per comprendere il codice.
smls

3

R, 67 byte

a=scan();x=c();for(i in a[-1])x=c(x,seq(i,a[1]-1,i));sum(unique(x))

Prende un vettore per STDIN nel seguente formato: [N, a_1, a_2, ...]. Supporta qualsiasi numero di a. Per ciascuna a, crea la sequenza adi N-1con stepsize a. Quindi prende la somma di tutte le voci univoche in quel vettore.


3

Haskell, 42 39 byte

a!b=sum[x|x<-[1..a-1],any((<1).mod x)b]

Uso:

Main> 50![2,3,5]
857

Grazie a @Zgarb per 3 byte


(x`mod`)è lo stesso di mod x.
Zgarb,

@Zgarb whoops :)
Angs

3

05AB1E , 9 byte

FND²%P_*O

Provalo online!

F         For N in [0, ..., input[0]-1]
 ND²%     Evaluate N%input[1]; yields an array of results
     P    Take the total product of the array. Yields 0 only if at least one of the value is 0, in other words if N is multiple of at least one of the specified values
      _   Boolean negation, yields 1 if the last value is 0 and yields 0 otherwise
       *  Multiply by N: yields N if the last value is 0 and yields 0 otherwise
        O Display the total sum

8 byte o 8 byte alternativi usando un filtro . (Il primo 8-byte non è stato possibile quando hai pubblicato la tua risposta, però. Dato che à(massimo) fa apparire la lista ora, ma non prima.)
Kevin Cruijssen,

3

Ottava, 49 37 byte

@(A,N)sum(unique((z=(1:N)'.*A)(z<N)))

la funzione verrà chiamata come f([2 3 4],50)

Supponiamo che A=[2 3 4];abbiamo bisogno di avere la somma dei numeri come

sum(
2,4,6...,50-1 ,
3,6,9...,50-1,
4,8,12,...50-1)

possiamo moltiplicare [2 3 4]per 1:50ottenere matrice(1:N)'.*A

[2 4 6 ... 2*50
3 6 9 ... 3*50
4 8 12 ...4*50]

quindi estrarre dalla matrice quelli che sono più piccoli di 50: z(z<N)

Poiché ci sono elementi ripetuti nella matrice, estraiamo valori unici e li sommiamo.

risposta precedente : (questa soluzione fallirà se N == 1)

@(A,N)sum((k=uint64(1:N-1))(any(k==(k./A').*A')))

La funzione dovrebbe essere chiamata come f(unit64([2 3 4]),uint64(50))


1
Molto bella! Quasi come la risposta dell'altra ottava, ma un approccio completamente diverso. Questo non mi è passato per la testa! Potrei trarre vantaggio dall'avere qualche spiegazione e forse un link a ideone, ma hai già il mio voto :-)
Stewie Griffin

Ho cambiato l'ordine dell'input, ma ecco un link ideone.com/8Bljrl
Stewie Griffin

2

Pyth, 10 byte

s{sm:0hQdt

Spiegazione

s{sm:0hQdtQ   Implicit input
    :0hQd     Get multiples of d below the bound
   m     tQ   ... for each d given
  s           Concatenate results
 {            Remove repeats
s             Take the sum

2

T-SQL, 87 byte

Funzionerà finché @iavrà un valore di 2048 o inferiore

USE master--needed for databases not using master as default
DECLARE @i INT=50
DECLARE @ table(a int)
INSERT @ values(2),(3),(5)

SELECT sum(distinct number)FROM spt_values,@ WHERE number%a=0and abs(number)<@i

Provalo


2

APL (Dyalog Unicode) , 12 byte

+/⊢∘⍳∩∘∊×∘⍳¨

Provalo online!

Funzione tacita anonima. Grazie a @ Adám per avermi aiutato a radere 3 byte di questo. Usi ⎕IO←0.

Come:

+/⊢∘⍳∩∘∊×∘⍳¨  Tacit function. Left and right arguments will be called  and  respectively.

        ×∘⍳¨  Multiply  with each element of [0..⍵-1]
             Enlist (flattens the vector)
     ∩∘       Then, get the intersection of that vector with
  ⊢∘⍳         The vector [0..⍵-1].
+/            Then sum

2

Pip , 43 41 39 35 byte

b^:sFc,a{f:0Fdb{f?0c%d?0(f:i+:c)}}i

Provalo online!

Spiegazione:

Takes inputs like so:

    arg1 1000
    arg2 3 5

b^:s                      ;read rest of inputs as array
                          ;(s is " " and ^ is split into array on char)
F c ,a{                   ;for(c in range(0,a))
  f:0                     ;flag to prevent double counting 15,30,etc.
  F d b {                 ;forEach(d in b)
    f? 0 c%d? 0 (f:i+:c)  ;if flag {continue}elif c%d {f=i+=c}
                          ;      (i will always be truthy so why not)     
  }
}
i                         ;print sum

whoops! Ho letto troppo in fretta
Kenneth Taylor il

Molto meglio. Bella risposta!
mbomb007,

1

Python 2, 80 byte

Questo è molto lungo Può sicuramente essere abbreviato. Prendere i 3 numeri come input separati sta sicuramente danneggiando il punteggio.

i=input
x=i();y=i();z=i();s=c=0
exec("if c%z<1 or c%y<1:s+=c\nc+=1\n"*x)
print s

Puoi fare x,y,z=input()e dare input sotto forma di (1000,3,5).
Skyler,

1

Lisp comune, 77

(lambda(n x)(loop for i below n when(some(lambda(u)(zerop(mod i u)))x)sum i))

Ungolfed

(lambda (limit seeds)
  (loop for i below limit
        when (some (lambda (u) (zerop (mod i u))) seeds)
          sum i))

1

PowerShell , 57 byte

param($a,$b)(1..--$a|?{$i=$_;$b|?{!($i%$_)}})-join'+'|iex

Provalo online!

Soluzione iterativa. Accetta l'input come numero $ae come array letterale $b. Passa da 1uno a uno sotto $a(via --$a), usando un Where-Objectoperatore|?{...} con una clausola per selezionare determinati numeri.

La clausola imposta $iper essere il numero corrente prima di inviare un array di input $bin un altro |?{...}, qui selezionando quegli elementi in cui il numero corrente è uniformemente diviso per almeno uno dei numeri in $b. Questi elementi $bche si dividono uniformemente vengono lasciati sulla tubazione.

Pertanto, se esiste almeno un elemento da $b, la pipeline contiene un elemento, quindi l'esterno Whereè $truee il numero corrente viene lasciato sulla pipeline. Altrimenti, senza elementi dalla $bconduttura, l'esterno Whereè$false , quindi il numero corrente non viene posizionato sulla pipeline.

Quei numeri sono tutti raccolti in parentesi, scritti -joininsieme a +segni e convogliati a |iex(abbreviazione di Invoke-Expressione simili a eval). Il risultato della somma viene lasciato sulla pipeline e l'output è implicito.


1

PHP, 78 76 74 byte

for(;++$i<$argv[$f=$k=1];$s+=$i*!$f)for(;$v=$argv[++$k];)$f*=$i%$v;echo$s;

The outer loop runs $i from 1 to below first argument and adds $i to $s if $f is not set.
The inner loop multiplies $f with ($i modulo argument) for all subsequent arguments, setting $f to 0 if $i is the multiple of any of them.

Run with -r.


1

Scala, 47 bytes

n=>1.to(n(0)-1).filter(i=>n.exists(i%_==0)).sum

n is a List which contains of a first argument N, the rest are elements of A

Works by filtering out numbers where there doesn't exist at least one A of which i is a multiple, then summing. Strictly speaking we should use n.tail.exists inside the closure, but as i is always less than N and therefore never a multiple of N the solution is still complete without this.


1

Java 8, 75 bytes

(N,A)->IntStream.range(1,N).filter(x->A.stream().anyMatch(y->x%y==0)).sum()

The method signature for this is int f(int N, List<Integer> A)


1

Ruby, 52 48 46 bytes

->b{b[s=0].times{|x|b.find{|y|x%y<1&&s+=x}};s}

1

C11, 177 bytes

#include"object.h"
#define S size_t
S g(S m,array_t*d){S s,i,l,j;for(s=i=0;i<m;i++){for(l=1,j=0;j<d->idx+1;l*=i%(S)(*array_get_ref(d,j++,NULL))->fwi->value);s+=l?0:i;}return s;}

Requires this set of headers in the same folder, and the fnv-hash library found there as well. Compile like gcc 1.c ../fnv-hash/libfnv.a -o 1 -DNODEBUG

Test Program:

#include "../calc/object/object.h"
#include <stdio.h>

size_t f (const size_t max, const size_t a, const size_t b);
size_t f2 (const size_t max, const array_t* const divs);
size_t g (size_t max, array_t* divs);

define_array_new_fromctype(size_t);

int main(void) {
  printf("%zu\n", f(10, 3, 5));
  static const size_t a[] = {
    3, 5
  };
  array_t* b = array_new_from_size_t_lit(a, 2, t_realuint);
  printf("%zu\n", f2(10, b));
  printf("%zu\n", g(10, b));
  array_destruct(b);
  return 0;
}

size_t f (const size_t max, const size_t a, const size_t b) {
  size_t sum = 0;
  for (size_t i = 0; i < max; i++) {
    sum += (i % a * i % b) ? 0 : i;
  }
  return sum;
}

size_t f2 (const size_t max, const array_t* const divs) {
  size_t sum = 0;
  const size_t len = array_length(divs);

  for (size_t i = 0; i < max; i++) {
    size_t mul = 1;
    for (size_t j = 0; j < len; j++) {
      object_t** this = array_get_ref(divs, j, NULL);

      fixwid_t*   num = (*this)->fwi;

      mul *= i % (size_t) num->value;
    }
    sum += mul ? 0 : i;
  }
  return sum;
}

#define S size_t
S g(S m,array_t*d){S s,i,l,j;for(s=i=0;i<m;i++){for(l=1,j=0;j<d->idx+1;l*=i%(S)(*array_get_ref(d,j++,NULL))->fwi->value);s+=l?0:i;}return s;}

outputs

23
23
23

1

Japt -x, 9 7 6 bytes

Ç*VøZâ

Try it

           :Implicit input of integer U and array V
Ç          :Map each Z in the range [0,U)
 *         :  Multiply by
  Vø       :  Does V contain
    Zâ     :   Any of the divisors of Z
           :Implicit output of sum of resulting array

1

Whispers v2, 178 bytes

> Input
> Input
> ℕ
>> (1)
>> ∤L
>> {L}
>> L∩2
>> #L
>> L∈3
>> L⋅R
>> Each 5 4
>> Each 6 11
>> Each 7 12
>> Each 8 13
>> Each 9 14
>> Each 10 15 4
>> ∑16
>> Output 17

Try it online!

Structure tree:

struct tree

How it works

Very simply, we put each number (the lines with Each on them) through a series of functions (the lines with L on them), then, based off the results of those functions, we discard some numbers and keep the rest, before finally summing them. In fact, we can define those functions, where α denotes the set of numbers given as input:

f(x)={i|(i|x),iN}i.e. the set of divisors ofxg(x)=f(x)αi.e. the union of the divisors ofxwithαh(x)=|g(x)|>0i.e.g(x)is not empty

This is what lines 5 through to 10 represent. Lines 11 through 16 are simply the application of those three functions. Once we've defined all the functions, we then mutate α to β according to the following rule:

βi={αih(αi)0h(αi)

where αi denotes the ith element of α, and the same for β. Finally, we can simply take the sum of β, as the 0 elements do not affect the sum.


1

K (oK), 15 14 bytes

Solution:

{+/&|/~y!\:!x}

Try it online!

Examples:

{+/&|/~y!\:!x}[50;,2]
600
{+/&|/~y!\:!x}[10;3 5]
23

Explanation:

{+/&|/~y!\:!x} / the solution
{            } / lambda taking implicit x and y
           !x  / range 0..x-1
       y!\:    / modulo (!) x with each-left (\:) item in y
      ~        / not
    |/         / min-over to flatten into single list
   &           / indices where true
 +/            / sum up

0

Actually, 13 bytes

DR∙`i;)%Y*`MΣ

Try it online!

Explanation:

DR∙`i;)%Y*`MΣ
DR             range(1, N)
  ∙            Cartesian product with A
   `i;)%Y*`M   for each pair:
    i;)          flatten, make a copy of the value from the range
       %Y        test if value from range divides value from A
         *       value from range if above is true else 0
            Σ  sum

0

Processing, 88 bytes

int q(int a,int[]b){int s=0,i=0;for(;++i<a;)for(int j:b)if(i%j<1){s+=i;break;}return s;}

Uses the simple for-loop approach, sums all the multiples up and returns it. Input is the format int, int[]array.

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.