Вывести ALONED числа

21

Рассмотрим естественную последовательность до 6 (не учитывая 1) :

2,3,4,5,6

Мы начинаем сканирование слева (в данном случае от 2), ищем число, делимое на 2 (здесь 4), а затем удаляем оба числа из списка (здесь 2 и 4), так что список уменьшается до:

3,5,6

Мы продолжаем тот же процесс, здесь самый левый - 3, поэтому мы ищем число, делимое на 3. 6 - это, несомненно, это число, и, таким образом, 3 и 6 удаляются,

5 

Теперь дальнейший поиск невозможен. Таким образом, это становится списком ALONED номеров для n = 6.

ЗАДАЧА

  1. Если число n больше 1, выведите все соответствующие чисел.

ВХОД

2
6
15
20
22

ВЫХОД

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

ДАЙТЕ ДРУГОЙ РАБОТЫ НА ПРИМЕРЕ

Для 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)

Это , поэтому выигрывает самый короткий код в байтах.

officialaimm
источник
7
Как вы знаете, у нас есть песочница, в которой вы можете оставить неполные заявки для обратной связи, прежде чем публиковать их на главном сайте.
DJMcMayhem
4
Должны ли мы возвращать список чисел в порядке возрастания или же будет приемлемым неупорядоченный список или набор?
Деннис
должен быть в порядке возрастания.
officialaimm

Ответы:

5

05AB1E , 22 17 15 14 байтов

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

Попробуйте онлайн!

объяснение

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
Emigna
источник
6

Python 2, 90 79 73 байта

-6 байт благодаря xnor

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

Принимает входной номер на стандартный ввод. Идео это!

объяснение

Мы строим начальный список из входного номера и сохраняем его в L. Затем выполните цикл, пока последнее число больше или равно 2 разам первого числа и удаляет 2 раза первое число из списка. Это всегда будет следующий номер делится на L[0]. L=L[1:]снимает и первый номер. Когда условие больше не выполняется, дальнейшее удаление невозможно, и список печатается.

DLosc
источник
В Python 2 rangeуже приведен список.
xnor
@xnor Спасибо! Забыли об этом.
DLosc
5

Python, 61 байт

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

Немного проще понять этот менее понятный код:

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

Это использует прямую характеристику aloned номера:

Число iявляется одиночным, если при разложении как i = a * 2^bс bнечетным

  • a>1и bдаже, или
  • a==1и bстранно

Алонированные номера для nвсех являются номерами iв интервале n/2 + 1 <= i <= n.

Почему это так? При выполнении процесса n, скажем, мы удаляем нечетное число aв нижней половине ( 1до n/2). Затем 2*aудаляется независимо от того, где он находится в списке. Итак, 4*aостается (если оно существовало). Но если он находится в нижней половине, процесс удаления дойдет до него и удалит оба 4*aи 8*a. Таким образом, мы видим , что верхняя половина номер получает удален , если это форма 2*a, 8*a... с нечетным c, но остается , если он имеет форму a, 4*a, 8*a, ...

Исключение составляет for a=1, который не запускается в списке и поэтому не удаляется. В результате цепочка удаления начинается с a=2, и правило для степеней 2 переворачивается.

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

В приведенном выше коде (i&-i)**.5%1>0проверяется, iне хватает ли формы i = a * 2^bс bнечетным, с помощью бит-трюка для извлечения коэффициента наибольшей степени двух 2^b = i&-i, а затем проверяется, не является ли результат идеальным квадратом. Затем, i&~-i>0это еще одна хитрость, чтобы проверить, iне является ли идеальная степень 2-й. Эти условия затем xor'ed.

Здесь есть еще несколько улучшений

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

Во- первых, мы переходим индекс диапазона 1 до укоротить до range(n/2,n)от range(n/2+1,n+1), компенсируя путем замены всего iс i+1(или ~-i).

Является ли степень 2 числом, является степенью 4(2 ^ bс bчетным), можно проверить с помощью 2**c/3нескольких больших значений c. Это потому, что 2**c/3имеет двоичное представление 10101...101с единицами в четных позициях битов. Использование c=2*nдостаточно. Чтобы свести на нет результат, когда iесть степень 2, мы делим пополам это число в этом случае, 1вместо этого помещая в нечетные позиции.

XNOR
источник
4

Groovy, 65 58 байт

Идея алгоритма от DSLoc , который заметил, что вам нужно только удалить двойники.

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

Вот разбивка:

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

Включает +1 для -n

Дайте номер ввода на STDIN:

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

aloned.pl:

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

Непосредственно проверка возможных номеров дольше:

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

Это проверяет все числа в верхней половине диапазона. Оставьте числа с четным числом 2 в качестве простых множителей, за исключением случаев, когда число является степенью 2, а затем нечетным (поскольку 1 исключено из исходного ряда). Однако этот метод должен хорошо работать для других языков.

Тон Хоспел
источник
3

MATL , 18 байт

Заимствовал идею «умножить на 2» из ответа @ Emigna's 05AB1E .

q:Qt"t1)tEhym?6MX-

Попробуйте онлайн!

объяснение

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
Луис Мендо
источник
Вам нужно только проверить, является ли k членом, не знаю, экономит ли это вам байты или нет.
Волшебная Урна Осьминога
@carusocomputing Спасибо! Я изначально проверил только 2 * K (если это то, что вы имеете в виду). Затем я добавил k, потому что позже я повторно использую этот массив из двух элементов, чтобы удалить оба из общего массива
Луис Мендо
3

Haskell, 71 69 62 56 байт

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

Пример использования: q 22-> [12,13,15,17,19,20,21].

Если есть кратное первое число a, то это 2*a. Сохранить, aесли 2*aего нет в списке, и добавить рекурсивный вызов с помощью aи 2*aудалить из списка.

Ними
источник
Хе-хе, я собирался сказать вам, что GCD был излишним, но вы получили это сами.
Волшебная Урна Осьминога
2

Руби, 124

Сравнивая оценки с другими ответами, это, очевидно, неправильный подход:

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

Несколько умный бит здесь, a[g[0]]=a[g[1]]=!g[1]который устанавливает значения хэша в true / false по мере необходимости.

Не тот Чарльз
источник
2

PHP, 98 байт

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 байтов сэкономить @Titus Спасибо

Если разрешена запятая, то ее можно сократить на 9 байт (!$a?:print"$a,");вместо(!$a?:print$x?",$a":$x=$a);

Йорг Хюльсерманн
источник
Разве не нужно заданий $aи $bскобок? Злая!
Тит
-1 байт с запятой: (!$a?:print"$a,")-> print$a?"$a,":"". -2 байта для обеих версий, если вы используете подчеркивание в качестве разделителя.
Тит
-2 байта: foreach(... as$v) , $v-2вместо $kи $v*2-2вместо $k*2+2.
Тит
@ Titus Я попробовал это после того, как ваш комментарий $a=&$r[$k]&&$b=&$r[$k*2+2]работает как $a=$r[$k]and$b=$r[$k*2+2]. Прошу прощения за то, что не нашел ни одной страницы, которая объясняет комбинации со ссылками и &&оператором. Но мне нужны ссылки, а не задания. Я не уверен, разрешается ли использовать запятую или другой разделитель.
Йорг Хюльсерманн
@Titus нашел его сейчас php.net/manual/en/language.operators.precedence.php & побитово, и ссылки имеют более высокий приоритет, чем &&оператор
Йорг Хюльсерманн
1

Javascript, 149 байт

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

Вот рабочий пример. Весь HTML и функция wrapper () просто интерактивны.

Этот фрагмент кода без символов содержит некоторые комментарии и позволяет в интерактивном режиме видеть шаги для любого заданного ввода.

Michaels
источник
1

JavaScript (ES6), 92 байта

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

Я думал, что опубликовал это вчера, но, очевидно, нет ...

Вот другая версия:

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
ETHproductions
источник
1

Java 7, 210 байт

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

Определенно можно играть в гольф, используя другой подход, возможно, используя массив с некоторыми хитростями. Из-за приведений, прерываний, типизированных списков и проверок if это немного длиннее, чем ожидалось, но это работает.

Ungolfed & тестовый код:

Попробуй это здесь.

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

Выход:

[2]
[5]
[8, 9, 11, 12, 13, 15]
[11, 12, 13, 15, 17, 19, 20]
[12, 13, 15, 17, 19, 20, 21]
Кевин Круйссен
источник
1

Ракетка 191 байт

(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 (комментарии после ';'):

(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.

Тестирование:

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

Выход:

'(2)
'(5)
'(8 9 11 12 13 15)
'(11 12 13 15 17 19 20)
'(12 13 15 17 19 20 21)
rnso
источник