Emette i numeri ALONED


21

Considera la sequenza naturale fino a 6 (ignora 1) :

2,3,4,5,6

Iniziamo la scansione da sinistra (in questo caso da 2), cerchiamo un numero divisibile per 2 (qui 4) e quindi rimuoviamo entrambi i numeri dall'elenco (qui 2 e 4), in modo che l'elenco si riduca a:

3,5,6

Continuiamo lo stesso processo, qui l'estrema sinistra è 3, quindi cerchiamo il numero divisibile per 3. 6 è sicuramente quel numero e quindi 3 e 6 vengono rimossi,

5 

Ora, non è possibile effettuare ulteriori ricerche del genere. Pertanto, questo diventa l'elenco dei numeri ALONED per n = 6.

OBBIETTIVO

  1. Dato un numero n maggiore di 1, stampa tutti i corrispondenti numeri associati.

INGRESSO

2
6
15
20
22

PRODUZIONE

2
5
8,9,11,12,13,15
11,12,13,15,17,19,20
12,13,15,17,19,20,21

ANCORA UN ALTRO ESEMPIO RISOLTO

Per n = 22

=>2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22
=>3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 (remove 2 & 4)
=>5,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 (remove 3 & 6)
=>7,8,9,11,12,13,14,15,16,17,18,19,20,21,22 (remove 5 & 10)
=>8,9,11,12,13,15,16,17,18,19,20,21,22 (remove 7 & 14)
=>9,11,12,13,15,17,18,19,20,21,22 (remove 8 & 16)
=>11,12,13,15,17,19,20,21,22 (remove 9 & 18)
=>12,13,15,17,19,20,21 (remove 11 & 22) (OUTPUT)

Questo è , quindi vince il codice più breve in byte.


7
Solo per questo, abbiamo una sandbox in cui è possibile pubblicare sfide incomplete per il feedback prima di pubblicarlo sul sito principale.
DJMcMayhem

4
Dobbiamo restituire un elenco dei numeri in ordine crescente o sarebbe accettabile anche un elenco non ordinato o un set?
Dennis,

dovrebbe essere in ordine crescente.
officialaimm,

Risposte:


5

05AB1E , 22 17 15 14 byte

L¦¹F¬·©¹›_i¦®K

Provalo online!

Spiegazione

L¦               # push the list [2..input]
  ¹F             # input nr of times do:
          i      # if
    ¬·©          # the first element in the list * 2
       ¹›_       # is less than or equal to input
                 # then
           ¦     # remove first element of list
            ®K   # and remove it's multiple

6

Python 2, 90 79 73 byte

-6 byte grazie a xnor

L=range(2,input()+1)
while L[0]*2<=L[-1]:L.remove(L[0]*2);L=L[1:]
print L

Prende il numero di input su stdin. Ideone esso!

Spiegazione

Costruiamo l'elenco iniziale dal numero di input e lo memorizziamo in L. Quindi, ripetere il ciclo mentre l'ultimo numero è maggiore o uguale a 2 volte il primo numero e rimuovere 2 volte il primo numero dall'elenco. Questo sarà sempre il prossimo numero divisibile per L[0]. L=L[1:]toglie anche il primo numero. Quando la condizione non è più vera, non è possibile effettuare ulteriori rimozioni e l'elenco viene stampato.


In Python 2, rangefornisce già un elenco.
xnor

@xnor Grazie! Dimenticato quello.
DLosc,

5

Python, 61 byte

lambda n:[i+1for i in range(n/2,n)if-~i&~i&4**n/3>>(-~i&i<1)]

È un po 'più facile capire questo codice meno golfato:

lambda n:[i for i in range(n/2+1,n+1)if((i&-i)**.5%1>0)^(i&~-i>0)]

Questo utilizza una caratterizzazione diretta dei numeri solitari:

Un numero iviene solo se, se scomposto come i = a * 2^bcon bdispari, sia

  • a>1ed bè pari, oppure
  • a==1ed bè strano

I numeri assegnati per nsono tutti numeri assegnati inell'intervallo n/2 + 1 <= i <= n.

Perché questo vale? Quando esegui il processo per n, supponiamo di rimuovere un numero dispari anella metà inferiore ( 1a n/2). Quindi, 2*aviene rimosso, indipendentemente da dove sia nell'elenco. Quindi, 4*arimane (se esistesse). Ma se è nella metà inferiore, il processo di eliminazione arriverà e rimuoverà entrambi 4*ae 8*a. Quindi, vediamo che un numero superiore mezzo viene rimosso se è della forma 2*a, 8*a... con strana c, ma i soggiorni se ha forma a, 4*a, 8*a, ...

L'eccezione è per a=1, che non si avvia nell'elenco e quindi non viene rimossa. Di conseguenza, la catena di rimozione inizia con a=2e viene invertita la regola per i poteri di 2.

lambda n:[i for i in range(n/2+1,n+1)if((i&-i)**.5%1>0)^(i&~-i>0)]

Nel codice sopra, (i&-i)**.5%1>0controlla se imanca la forma i = a * 2^bcon bdispari, con il trucco dei bit per estrarre il massimo fattore di potenza di due 2^b = i&-i, quindi controlla se il risultato non è un quadrato perfetto. Quindi, i&~-i>0è un altro piccolo trucco per verificare se inon è un potere perfetto di 2. Queste condizioni vengono quindi fissate.

Ci sono altri miglioramenti qui

lambda n:[i+1for i in range(n/2,n)if-~i&~i&4**n/3>>(-~i&i<1)]

Innanzitutto, spostiamo l'indice della gamma 1 in basso per accorciare a range(n/2,n)da range(n/2+1,n+1), compensando sostituendo tutto icon i+1(o ~-i).

Se una potenza di 2 è numero è una potenza di 4(2 ^ bcon bpari) può essere verificata da e con 2**c/3un grande c. Questo perché 2**c/3ha una rappresentazione binaria 10101...101con quelle nei bit posizionati in modo uniforme. c=2*nBasta usare . Per negare il risultato quando iè una potenza di 2, dimezziamo questo numero in quel caso, mettendo 1invece le posizioni dispari.


4

Groovy, 65 58 byte

Idea dell'algoritmo di DSLoc , che ha notato che è necessario solo rimuovere i doppi.

{n->a=(2..n);(2..(n/2)).each{if(it in a){a-=[it,it*2]}};a}

Ecco una ripartizione:

{
    n->
    a=(2..n);             // Store [2,...,n].
    (2..(n/2)).each {     // From 2 to half of n.
        if(it in a){      // If it's there...
            a-=[it,it*2]  // Remove it and its double, store in a.
        }
    };
    a                     // Return a.
}

4

Perl, 53 49 45 44 byte

Include +1 per -n

Dai il numero di input su STDIN:

perl -M5.010 aloned.pl <<< 22

aloned.pl:

#!/usr/bin/perl -n
@F[$F[$_*2]/2,$_*2,1]=0,$_&&say for@F=0..$_

Il controllo diretto dei possibili numeri è più lungo:

map{/$/;$_/=4until$_%4;$_%2^$_<3&&say$`}$_/2+1..$_

Questo controlla tutti i numeri nella metà superiore dell'intervallo. Mantieni numeri che hanno un numero pari di 2 come fattori primi, tranne se il numero è una potenza di 2, quindi dispari (perché 1 è escluso dalla serie originale). Questo metodo dovrebbe comunque funzionare bene per altre lingue.


3

MATL , 18 byte

Preso in prestito l'idea "moltiplica per 2" dalla risposta 05AB1E di @ Emigna .

q:Qt"t1)tEhym?6MX-

Provalo online!

Spiegazione

q:Q        % Input n implicitly. Push [2 3 ... n]
t"         % Duplicate. For each: repeat n-1 times
  t1)      %   Duplicate. Get first element from current array, say k
  tEh      %   Append twice that value: gives array [k 2*k]
  y        %   Push another copy of current array
  m?       %   If both k and 2*k are members of the array 
    6M     %     Push [k 2*k] again
     X-    %     Set difference: remove from current array
           %   End if implicitly
           % End for each implicitly
           % Display implicitly

Devi solo controllare se k è un membro, non so se questo ti fa risparmiare byte o meno.
Magic Octopus Urn,

@carusocomputing Grazie! Inizialmente ho controllato solo 2 * k (se è quello che vuoi dire). Poi ho aggiunto k lì perché in seguito riutilizzo quell'array di due elementi per rimuoverli entrambi dall'array generale
Luis Mendo,

3

Haskell, 71 69 62 56 byte

g(a:b)|s<-filter(/=2*a)b=[a|s==b]++g s
g x=x
q n=g[2..n]

Esempio di utilizzo: q 22-> [12,13,15,17,19,20,21].

Se c'è un multiplo del primo numero a, lo è 2*a. Mantieni ase 2*anon è nell'elenco e aggiungi una chiamata ricorsiva con ae 2*arimossa dall'elenco.


Hehe, stavo per dirti che GCD era eccessivo, ma ce l'hai fatta da solo.
Magic Octopus Urn,


2

Ruby, 124

Confrontando i punteggi con altre risposte, questo è ovviamente l'approccio sbagliato:

->n{a={};b=[*2..n].each{|k|a[k]=7}
b.map{|i|g=b.select{|x|a[i]&&a[x]&&x%i<1}
a[g[0]]=a[g[1]]=!g[1]}
a.select{|k,v|v&k}.keys}

Il bit un po 'intelligente qui è a[g[0]]=a[g[1]]=!g[1]che imposta i valori dell'hash su vero / falso, se necessario.


2

PHP, 98 byte

foreach($r=range(2,$argv[1])as$v)$a=&$r[$v-2]&&$b=&$r[$v*2-2]?$b=$a="":(!$a?:print$x?",$a":$x=$a);

8 byte salvati da @Titus Grazie

Se è consentita una virgola finale, è possibile accorciare 9 byte (!$a?:print"$a,");anziché(!$a?:print$x?",$a":$x=$a);


Non hai i compiti $ae $bhai bisogno di parentesi? Wicked!
Tito,

-1 byte con la virgola finale: (!$a?:print"$a,")-> print$a?"$a,":"". -2 byte per entrambe le versioni se si utilizza il trattino basso come separatore.
Tito,

-2 byte: foreach(... as$v), $v-2anziché $ke $v*2-2invece di $k*2+2.
Tito,

@Titus L'ho provato dopo che il tuo commento ha $a=&$r[$k]&&$b=&$r[$k*2+2]funzionato come $a=$r[$k]and$b=$r[$k*2+2]. Mi dispiace di non aver trovato alcuna pagina che spieghi le combinazioni con i riferimenti e l' &&operatore. Ma ho bisogno di riferimenti non di incarichi. Non sono sicuro che sia consentita una virgola finale o un altro separatore.
Jörg Hülsermann,

@Titus lo ha trovato ora php.net/manual/en/language.operators.precedence.php & bit a bit e riferimenti hanno una precedenza più alta rispetto &&all'operatore
Jörg Hülsermann

1

Javascript, 149 byte

function a(n){o=Array.from(Array((n+1)).keys());o.shift();o.shift();for(i=1;i<o.length;i++){if(o[i]%o[0]==0){o.splice(i,1);o.shift();i=0;}}return o;}

Ecco un esempio funzionante. Tutto l'HTML e la funzione wrapper () è proprio così è effettivamente interattivo.

Questo frammento di codice non memorizzato contiene alcuni commenti e ti consente di vedere in modo interattivo i passaggi per ogni dato input.


1

JavaScript (ES6), 92 byte

f=(n,R=[...Array(n-1)].map((_,i)=>i+2),[i,...r]=R)=>~r.indexOf(i*=2)?f(n,r.filter(x=>x-i)):R

Pensavo di averlo pubblicato ieri, ma ovviamente non ...

Ecco un'altra versione:

f=(n,R=[...Array(n-1)].map((_,i)=>i+2),[i,...r]=R,q=r.filter(x=>x-i*2))=>q+""!=r+""?f(n,q):R

1

Java 7, 210 byte

import java.util.*;List c(int n){List<Integer>l=new ArrayList();int i=1;for(;i++<n;l.add(i));for(i=1;i++<n;)for(int x:l)if(i!=x&x%i<1&l.indexOf(i)>=0){l.remove((Integer)i);l.remove((Integer)x);break;}return l;}

Si può sicuramente giocare a golf un po 'di più usando un approccio diverso, probabilmente usando un array con alcuni trucchi. A causa del cast, break, typed-list e if-checks è un po 'più lungo del previsto, ma funziona.

Codice non testato e test:

Provalo qui.

import java.util.*;
class M{
  static List c(int n){
    List<Integer> l = new ArrayList();
    int i = 1;
    for(; i++ < n; l.add(i));
    for(i = 1; i++ < n;){
      for(int x : l){
        if(i != x & x%i < 1 & l.indexOf(i) >= 0){
          l.remove((Integer)i);
          l.remove((Integer)x);
          break;
        }
      }
    }
    return l;
  }

  public static void main(String[] a){
    System.out.println(Arrays.toString(c(2).toArray()));
    System.out.println(Arrays.toString(c(6).toArray()));
    System.out.println(Arrays.toString(c(15).toArray()));
    System.out.println(Arrays.toString(c(20).toArray()));
    System.out.println(Arrays.toString(c(22).toArray()));
  }
}

Produzione:

[2]
[5]
[8, 9, 11, 12, 13, 15]
[11, 12, 13, 15, 17, 19, 20]
[12, 13, 15, 17, 19, 20, 21]

1

Racchetta 191 byte

(let loop((fl(range 2(add1 n)))(fg #f))(define i(first fl))(for((j(rest fl))
#:when(= 0(modulo j i))#:final(= 0(modulo j i)))
(set! fl(remove*(list i j)fl))(set! fg #t))(if fg(loop fl #f)fl))

Ungolfed (commenti dopo ';'):

(define (f n)
  (let loop ((fl (range 2 (add1 n)))  ; create a full list of numbers
             (fg #f))                 ; flag to show if main list is modified
    (define i (first fl))
    (for ((j (rest fl)) #:when (= 0 (modulo j i))  ; test divisibility
                        #:final (= 0 (modulo j i)))
      (set! fl (remove* (list i j) fl))  ; remove these from main list
      (set! fg #t))
    (if fg (loop fl #f)              ; if main list modified, check again,
        fl)))                         ; else print modified list.

test:

(f 2)
(f 6)
(f 15)
(f 20)
(f 22)

Produzione:

'(2)
'(5)
'(8 9 11 12 13 15)
'(11 12 13 15 17 19 20)
'(12 13 15 17 19 20 21)
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.