Наименьшие целые числа после N, кратные 2, 3 и 4


22

Дайте кредит тому, кому это нужно .

Цель Дано целое число N > 0, из самых маленьких целых чисел A, Bи Cтаким образом , чтобы:

  1. Все A, Bи Cстрого больше N;
  2. 2делит A;
  3. 3делит B;
  4. и 4делит C.

Это код-гольф, поэтому выигрывает самый короткий ответ в байтах. Вы можете использовать язык, созданный / обновленный после этого испытания, но он не является конкурирующим.

Контрольные примеры

N => A, B, C
1 => 2, 3, 4
4 => 6, 6, 8
43 => 44, 45, 44
123 => 124, 126, 124
420 => 422, 423, 424
31415 => 31416, 31416, 31416
1081177 => 1081178, 1081179, 1081180

Можем ли мы (последовательно) выводить результаты в другом порядке (например C B A), если это четко указано в ответе?
Мартин Эндер

@ MartinBüttner, что приемлемо
Конор О'Брайен

Ответы:


17

Желе , 8 байт

~%2r4¤+‘

Попробуйте онлайн! или проверьте все контрольные примеры .

Как это работает

~%2r4¤+‘  Main link. Argument: n (integer)

~         Bitwise NOT; yield ~n = -(n + 1).
     ¤    Combine the three links to the left into a niladic chain:
  2         Yield 2.
   r4       Yield the range from 2 to 4, i.e., [2, 3, 4].
 %        Yield the remainder of the division of ~n by 2, 3 and 4.
          In Python/Jelly, -(n + 1) % k = k - (n + 1) % k if n, k > 0.
       ‘  Yield n + 1.
      +   Add each modulus to n + 1.

26

Python 2, 32 байта

lambda n:[n+2&-2,n/3*3+3,n+4&-4]

Битовая арифметика для 2 и 4, модульная арифметика для 3.

Я нашел четыре 7-байтовых выражения для следующего кратного из kприведенных выше, nно ни одно из них не короче:

n-n%k+k
~n%k-~n
n/k*k+k
~n/k*-k

Любой дает 34 байта, когда копии для k=2,3,4, и 33 байта, если объединены:

[n/2*2+2,n/3*3+3,n/4*4+4]
[n/k*k+k for k in 2,3,4]

Но 2 и 4 - это степени 2, которые позволяют битовым трюкам обнулять последние 1 или 2 байта.

n+2&-2
n+4&-4

Это дает 6 байтов (вместо 7) для получения следующего кратного, для всего 32 байта, побеждая for k in 2,3,4.

К сожалению, они выглядят многообещающе, n|1+1и n|3+1добавление выполняется в первую очередь, поэтому при увеличении вывода требуются скобки.


1
Из возможных вариантов я предпочитаю n+k-n%k.
Нейл

Делает n&3+1ли сложение первым тоже?
Тим

@ Тим Да, то же самое со всеми логическими операциями.
xnor


12

MATL, 15 10 9 байт

2:4+t5M\-

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

Объяснение:

2:4          #The array [2, 3, 4]
   +         #Add the input to each element, giving us [12, 13, 14]
    t        #Duplicate this array
     5M      #[2, 3, 4] again
       \     #Modulus on each element, giving us [0, 1, 2]
        -    #Subtract each element, giving us [12, 12, 12]

3
Хороший ответ! Вы можете сохранить байт, используя 5M(автоматический буфер обмена входов функций) вместо второго 2:4.
Дэвид

@ Дэвид Спасибо за совет!
DJMcMayhem

12

MATL, 8 байт

Qt_2:4\+

Использует алгоритм Желе Дениса, я удивлен, что он такой же длины!

Попробуйте онлайн или проверьте все контрольные примеры .

Q    % takes implicit input and increments by one
t_   % duplicate, and negate top of stack (so it's -(n+1))
2:4  % push vector [2 3 4]
\    % mod(-(n+1),[2 3 4])
+    % add result to input+1
     % implicit display

Ну, черт возьми. Я действительно гордился своим 10-байтовым решением, но я не могу победить это. Кроме того, забавные мелочи: это точно мой 300-й голос. = D
DJMcMayhem

Ааа, но это был просто алгоритм Агавы / Денниса, это не моя собственная идея.
Дэвид

1
иногда я продолжаю смотреть на этих элементарных символов мандарино в юникоде, пока чешу голову, и говорю: «Ради всего, что читается, это разветвленный исполняемый код»? LOL, хорошая вещь, есть мой upvote + я присоединюсь к Matl Train Sooon.
Abr001am

@ Agawa001 Вы должны! Если вы хорошо разбираетесь в Matlab, вы должны найти его достаточно простым, большая разница в том, что MATL основан на стеке. Также есть чат MATL, если вам нужна помощь!
Дэвид

@ Давид, что основанный на блинах характер matl делает еще более страшным злое знание того, что сам matlab сам по себе является языком, подходящим для игры в гольф с точки зрения его взаимодействия на высоком уровне, так что представьте себе ...
Abr001am

6

Matlab, 33 байта

Еще один немного другой подход

@(a)feval(@(x)a+1+mod(-a-1,x),2:4)

6

05AB1E , 8 байтов

Код:

>D(3L>%+

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


Ах, не заметил, что уже был ответ 05AB1E, который довольно похож на мой ответ. Я удалил его и вместо этого предложу использовать его как «-1»: ±D2xŸ%α( 2xŸэто просто альтернатива для вас 3L>; и две другие равноправные альтернативы могут быть Ƶ…Sили 4L¦).
Кевин Круйссен




4

Mathematica, 21 байт

Ceiling[#+1,{2,3,4}]&

Это безымянная функция, которая принимает одно целое число в качестве входных данных и возвращает список кратных чисел.

CeilingФункция принимает необязательный второй параметр , который говорит ему , чтобы округлить до следующего кратного заданного числа. К счастью, он также автоматически перебирает второй аргумент, так что мы можем дать ему список значений, и, в свою очередь, мы получим округленные кратные для всех них.


4

Октава, 20 байт

@(n)n-mod(n,d=2:4)+d

Примеры:

octave:60> f(123)
ans =

   124   126   124

octave:61> f(1081177)
ans =

   1081178   1081179   1081180

octave:62> f(420)
ans =

   422   423   424

Стоит отметить, что мы можем сделать это до 9 без добавления дополнительных байтов:

@(n)n-mod(n,d=2:9)+d

Выходные данные (2520 - наименьшее положительное целое число, равномерно делимое на все однозначные числа):

octave:83> f(2520)
ans =

   2522   2523   2524   2525   2526   2527   2528   2529


4

Лабиринт , 19 байт

:?
:
#/)
\ #
!"*@
"

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

Это выводит результаты в порядке, C, B, Aразделенном переводом строки.

объяснение

Как обычно, короткий лабиринтный праймер:

  • Лабиринт имеет два набора целых чисел произвольной точности, main и aux (ily), которые изначально заполнены (неявным) бесконечным количеством нулей. Мы будем использовать только основной для этого ответа.
  • Исходный код напоминает лабиринт, где указатель инструкций (IP) следует за коридорами, когда это возможно (даже за углами). Код начинается с первого действительного символа в порядке чтения, то есть в этом случае в верхнем левом углу. Когда IP-адрес достигает какой-либо формы соединения (т. Е. Нескольких соседних ячеек в дополнение к той, из которой он получен), он выбирает направление на основе вершины основного стека. Основные правила: поверните налево при отрицательном значении, продолжайте движение вперед при нулевом, поверните направо при положительном. И когда один из них невозможен из-за наличия стены, тогда IP будет идти в противоположном направлении. IP также оборачивается при попадании в тупик.

Несмотря на два no-ops ( "), которые делают макет немного расточительным, я вполне доволен этим решением, потому что поток управления на самом деле довольно тонкий.

IP начинается в верхнем левом углу :справа. Он сразу же попадет в тупик ?и развернется, так что программа фактически запустится с этим линейным фрагментом кода:

:   Duplicate top of main stack. This will duplicate one of the implicit zeros
    at the bottom. While this may seem like a no-op it actually increases
    the stack depth to 1, because the duplicated zero is *explicit*.
?   Read n and push it onto main.
:   Duplicate.
:   Duplicate.

Это означает, что у нас теперь есть три копии nв главном стеке, но его глубина равна 4. Это удобно, потому что это означает, что мы можем получить глубину стека, чтобы извлечь текущий множитель при работе с копиями ввода.

IP теперь входит в (по часовой стрелке) цикл 3х3. Обратите внимание, что #, увеличивая глубину стека, мы всегда получим положительное значение, так что мы знаем, что IP будет всегда поворачиваться на восток в этой точке.

Тело цикла выглядит так:

#   Push the stack depth, i.e. the current multiplier k.
/   Compute n / k (rounding down).
)   Increment.
#   Push the stack depth again (this is still k).
*   Multiply. So we've now computed (n/k+1)*k, which is the number
    we're looking for. Note that this number is always positive so
    we're guaranteed that the IP turns west to continue the loop.
"   No-op.
!   Print result. If we've still got copies of n left, the top of the 
    stack is positive, so the IP turns north and does another round.
    Otherwise, see below...
\   Print a linefeed.
    Then we enter the next loop iteration.

После того, как цикл был пройден (до !) три раза, все копии nизрасходованы и ноль внизу обнаружен. Из- "за нижней части (которая в противном случае кажется довольно бесполезной) эта позиция является перекрестком. Это означает, что с нулем на вершине стека IP пытается идти прямо вперед (на запад), но, поскольку есть стена, он на самом деле делает поворот на 180 градусов и движется обратно на восток, как если бы он зашел в тупик.

В результате теперь выполняется следующий бит:

"   No-op.
*   Multiply two zeros on top of the stack, i.e. also a no-op.
    The top of the stack is now still zero, so the IP keeps moving east.
@   Terminate the program.

3

Matlab, 50 байтов

@(a)arrayfun(@(k)find(~rem(a+1:a+k,k))+a,[2 3 4])

По крайней мере, вы можете использовать 2:4вместо [2 3 4].
Suever


3

JavaScript (ES6), 26 байт

Интересно, что портирование либо ответа @ KevinLau's Ruby, либо ответа @ xnor's Python приводит к одинаковой длине:

n=>[2,3,4].map(d=>n+d-n%d)
n=>[n+2&-2,n+3-n%3,n+4&-4]

Я немного предпочитаю порт ответа Ruby, так как он работает до 2 53 -3, в то время как порт ответа Python работает только до 2 31 -5.


)-> ]Как я думаю
Qwertiy

@Qwertiy Ой, простите за опечатку.
Нейл

3

C, 50 46 байтов

i;f(int*a,int n){for(i=1;++i<5;*a++=n+i-n%i);}

Спасибо Нейлу и nwellnhof за сохранение 4 байта!

Неутешительно долго. Я чувствую, что здесь есть какой-то взломанный хак, о котором я не знаю, но пока не могу его найти. Возвращает указатель на массив, содержащий три элемента. Полная программа:

i;f(int*a,int n){for(i=1;++i<5;*a++=n+i-n%i);}

int main()
{
    int array[3];
    int n=10;
    f(array, n);
    printf("A:%d\tB:%d\tC:%d\n",array[0],array[1],array[2]);
    return 0;
}

Я посмотрел на хитрость @ xnor, но вам нужно развернуть цикл для того, что в итоге обойдется вам в байт.
Нил

Не n + i - n % i++приводит к неопределенному поведению?
nwellnhof

Также, s/a[i-2]/*a++/чтобы сохранить два байта.
nwellnhof

@nwellnhof Бах, я подумал об этом, когда развернул его петлю, но мне не пришло в голову, что он все равно может использовать его.
Нейл

2
@Neil Но неопределенное поведение можно обойти без увеличения кода. Вот еще более короткая версия с использованием объявлений функций K & R:f(a,n,i)int*a;{for(i=1;++i<5;)*a++=n+i-n%i;}
nwellnhof

3

Reng, 40 байт

i1+#i2341ø>(1+)31j
i(2[¤,  q!^$]æl0eq!~

1: init

i1+#i2341ø

i1+#iустанавливает вход в 1 + input; это потому, что мы должны работать над числами, строго превышающими входные. 234инициализирует ленту с нашими значениями итерации и переходит к началу следующей строки.

2а: петля

i(2[¤,  q!^$]æl0eq!~

i(помещает ввод в STOS и 2[создает новый стек с двумя верхними элементами. ¤дублирует стек и ,выполняет модуль. Если есть остаток, q!^вырывается из цикла, чтобы перейти к (b). В противном случае мы можем печатать. $удаляет лишнюю штуковину, ]закрывает стопку и æкрасиво печатает. l0wq!~завершается, если в стеке нет нулевых элементов.

2b: этот другой цикл

          >(1+)31j
        q!^

(1+)добавляет 1 к STOS и 31jпереходит к той части цикла, которая не берет вещи из стека. И прибыль.


Этот лишний пробел действительно беспокоит меня. Возьми GIF.

REENNNNNGGG


3

Retina, 62 43 26 байт

17 байт благодаря @Martin Büttner .

^
1111:
! M & `(11 +): (\ 1 *)
:

(Обратите внимание на завершающий символ новой строки.)

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

Ввод в унарном виде 1, вывод в унарном виде 1через пробел.

Предыдущая 43-байтовая версия:

.+
11:$&;111:$&;1111:$&
\b(1+):(\1*)1*
$1$2

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

Ввод в унарном виде, вывод в унарном виде через точку с запятой ( ;).

Предыдущая 62-байтовая версия:

.+
$&11;$&111;$&1111
((11)+)1*;((111)+)1*;((1111)+)1*
$1;$3;$5

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

Ввод в унарном виде, вывод в унарном виде через точку с запятой ( ;).


26, если разрешен вывод в обратном порядке: retina.tryitonline.net/… ... В противном случае 33, хотя я думаю, что должен быть более короткий путь, избегающий обратной сортировки: retina.tryitonline.net/…
Martin Ender,

Этого достаточно, чтобы квалифицироваться как отдельный ответ?
Лаки Монахиня

Я не знаю, это все та же идея, я просто заменил создание списка вручную с использованием перекрывающихся совпадений.
Мартин Эндер

Конор подтвердил, что 26-байтовое решение является действительным.
Мартин Эндер

3

Октава, 27 22 20 байт

MATLAB и Octave:

f=2:4;@(x)f.*ceil((x+1)./f)

Лучше (решения эквивалентны, но одно может превзойти другое, если дальше играть в гольф), MATLAB и Octave:

@(x)x-rem(x,2:4)+(2:4)
f=2:4;@(x)x+f-rem(x,f)

Только в Октаве:

@(x)x-rem(x,h=2:4)+h

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


Мой окончательный ответ, в основном , что один здесь :( codegolf.stackexchange.com/a/80028/52795
Берс



2

Mathematica 28 байтов

f@n_:=n-n~Mod~#+#&/@{2,3,4}

f[1]
f[4]
f[43]
f[123]
f[420]
f[31415]
f[1081177]

{2, 3, 4}

{6, 6, 8}

{44, 45, 44}

{124, 126, 124}

{422, 423, 424}

{31416, 31416, 31416}

{1081178, 1081179, 1081180}


Общий случай дает общий ответ:

f[r]

{2 + r - Mod [r, 2], 3 + r - Mod [r, 3], 4 + r - Mod [r, 4]}


2

R, 30 26 байт

(Уменьшено на 4 байта благодаря @Neil)

N=scan();cat(N+2:4-N%%2:4)

Это (аналогично остальным ответам, я думаю) добавляет 2: 4 к входу и уменьшает остаток после выполнения по модулю на тех же числах.


1
Поскольку я не знаю язык, есть ли причина, по которой вы не используете N+2:4-N%%2:4?
Нейл

@Neil Потому что я не думал об этом, я думаю. Спасибо хоть.
Дэвид Аренбург

2

UGL , 51 31 25 24 байта

icu$l_u^^/%_u^*ocO$dddd:

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

Предыдущая 25-байтовая версия:

iRcu$l_u$r^/%_u*ocO$dddd:

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

Предыдущая 31-байтовая версия:

iRcuuulu$cuuuuuu%-r^/%_u*oddcO:

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

Предыдущая 51-байтовая версия:

i$$cuuu/%_ucuuu*@cuuuu/%_ucuuuu*@cuu/%_ucuu*ocOocOo

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




1

На самом деле, 22 байта

╗52x"╝1`;╛@%Y@╜<*`╓"£M

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

Интересный факт: 3 ошибки в интерпретаторе Actual были найдены и исправлены при написании этой программы.

Не очень забавный факт: эти 3 ошибки помешали этому решению стать намного короче.

Объяснение:

╗52x"╝1`;╛@%Y@╜<*`╓"£M
╗                       push input to reg0
 52x                    push range(2,5) ([2,3,4])
    "╝1`;╛@%Y@╜<*`╓"£M  map (for n in [2,3,4]):
     ╝                    push n to reg1
      1`;╛@%Y@╜<*`╓       find the smallest integer k where:
        ;╛@%Y               k is divisible by n and...
             @╜<*           is greater than the input

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.