Последовательность плюс-минус


26

Последовательность плюс-минус

Последовательность плюс-минус - та, которая начинается с двух семян, a(0)и b(0). Каждая итерация этой последовательности представляет собой сложение и вычитание двух предыдущих членов последовательности. То есть a(N) = a(N-1) + b(N-1)и b(N) = a(N-1) - b(N-1).

Цель Произведите последовательность плюс-минус, в бесконечности или первых Kшагах K. Вы можете сделать это с помощью бесконечной программы вывода, генератора или функции / программы, которая дает первые Kшаги. Порядок вывода не имеет значения, если он согласован. (Т. Е. b(K) a(K)Или a(K) b(K)с некоторым нечисловым разделителем без перевода строки между ними.) Вывод должен начинаться с ввода.

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

Для входных данных 10 2(из a(0) b(0), это возможный выход для первого подхода K (или подраздела бесконечного подхода):

10     2
12     8
20     4
24     16
40     8
48     32
80     16
96     64
160    32
192    128
320    64
384    256
640    128
768    512
1280   256
1536   1024
2560   512
3072   2048
5120   1024
6144   4096
10240  2048
12288  8192
20480  4096
24576  16384
40960  8192
49152  32768
81920  16384
98304  65536

Для входов 2 20 10( a(0) b(0) k):

2     20
22   -18
4     40
44   -36
8     80
88   -72
16    160
176  -144
32    320
352  -288

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


Я замечаю a (2n) = a (0) · 2ⁿ и b (2n) = n (0) · 2ⁿ, но это, вероятно, здесь бесполезно.
Нейл

Может ли нечисловой разделитель между aи bбыть символом новой строки?
Suever

@ Сувер Нет, не может.
Конор О'Брайен

@ CᴏɴᴏʀO'Bʀɪᴇɴ Спасибо за разъяснения!
Suever

1
Возвращение последовательности в порядке @guifa
Конор О'Брайен

Ответы:


13

Желе , 5 байт

ṄI;Sß

Это рекурсивный подход. Из-за оптимизации хвостовых вызовов единственным ограничением является возможность помещать оба целых числа в память. Выход - один список на строку.

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

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

ṄI;Sß  Main link. Argument: [b[n], a[n]] (n = 0 for original input)

Ṅ      Print [b[n], a[n]] to STDOUT.
 I     Compute the increments of the list, i.e., [a[n] - [b[n]].
   S   Compute the sum of the list, i.e., b[n] + a[n].
  ;    Concatenate the results to the left and to the right.
    ß  Recursively call the main link.

Вау. Это довольно впечатляет.
Конор О'Брайен

Что на Main linkсамом деле означает?
кошка

4
@cat Это как основная функция Си. Каждая строка определяет свою функцию / ссылку, но последняя вызывается автоматически при выполнении программы.
Деннис

> Jelly-программы состоят из 257 символов Unicode. Разве нет 256 бит в байте?
thepiercingarrow

@MarkWright и переводы строк могут использоваться взаимозаменяемо. Вы можете использовать оба в режиме UTF-8, но только \x7fпредставить их в кодовой странице Jelly.
Деннис

5

Python 2, 31 байт

def f(a,b):print a,b;f(a+b,a-b)

Отпечатки навсегда. Ну, в конце концов вы превышаете предел рекурсии, но это системное ограничение.


Как долго, по вашему мнению, это может продолжаться до возникновения ошибки рекурсии?
Р. Кап

@ R.Kap это ~ 1000. Вы можете установить этот предел на то, что вы хотите черезsys.setrecursionlimit
Mathias711

@ R.Kap На моей машине это занимает около 10 секунд.
xnor

За 10 секунд до появления ошибки рекурсии? Вау. В Python 3 я позволил своей работе продолжаться 30 минут подряд, и никаких ошибок не возникло. Мне удалось напечатать более 2000 цифр для одного из номеров! Я думаю, что whileцикл ведет себя иначе, чем то, что вы делаете.
Р. Кап

Я пытался использовать это с лямбда, но это заняло больше байтов ( f=lambda a,b:print(a,b)or f(a+b,a-b))
MilkyWay90

5

MATL , 10 байт

`tDtswPdhT

Эта версия будет выводить бесконечное количество элементов в последовательности плюс-минус.

Попробуйте онлайн! (остановите его после запуска из-за бесконечного цикла)

объяснение

    % Implicitly grab input as a two-element array [a,b]
`   % do...while loop
tD  % Duplicate and display the top of the stack
ts  % Duplicate [a,b] and add them together
w   % Swap the top two elements on the stack
P   % Swap the order of b and a in preparation for diff
d   % Compute the difference between b and a
h   % Horizontally concatenate [a+b, a-b]
T   % Explicit TRUE to make it an infinite loop
    % Implicit end of the do...while loop

Преобразует ли это автоматически все очень большие числа в научную нотацию?
Р. Кап

@ R.Kap Похоже, так и есть. Это, по-видимому, не запрещено в первоначальной постановке задачи.
августа

Вау, это довольно круто. В Python, если у вас очень большие числа, он по-прежнему печатает все цифры, по одной за раз, так что он немного утомительно смотрит на все это. Я просто подумал, что большинство других языков сделали это тоже, но похоже, что Python является уникальным в этом случае.
Р. Кап

Итак, в MATLAB (который MATL использует под капотом) вы можете изменить формат вывода на любой, какой захотите. По умолчанию MATL отображает до 15 чисел перед переключением на научную запись.
августа

Упс, мой плохой, извините, удалил;)
thepiercingarrow

3

Haskell, 19 байтов

a#b=a:b:(a+b)#(a-b)

Создает бесконечную последовательность чисел. Пример использования:

Prelude> take 20 $ 2#20

[2,20,22,-18,4,40,44,-36,8,80,88,-72,16,160,176,-144,32,320,352,-288]

3

Pyth, 10 9 байтов

Спасибо @isaacg за 1 байт.

#=Q,s
Q-F

Печатает бесконечную последовательность пар.

$ pyth plusminus.p <<< "[10,2]" | head -n 15
[10, 2]
[12, 8]
[20, 4]
[24, 16]
[40, 8]
[48, 32]
[80, 16]
[96, 64]
[160, 32]
[192, 128]
[320, 64]
[384, 256]
[640, 128]
[768, 512]
[1280, 256]

1
Первый и последний Qs могут быть удалены - Pyth будет заполнять их неявно.
Исаак

@isaacg Так что же тогда было реализовано? Круто. Я попытался удалить первый, но это не сработало.
PurkkaKoodari

Странно, удаление первого сработало на моей машине.
Исаак


3

05AB1E , 7 байтов

Использует метод first-k . Введите следующее для:

k
[a, b]

Код:

FD=OsƂ

Объяснение:

F        # For N in range(0, k).
 D=      # Duplicate top of the stack and print without popping.
   O     # Sum up the array.
    sÆ   # Swap and perform a reduced subtraction.
      ‚  # Pair the top two elements. a, b --> [a, b]

Использует кодировку CP-1252 . Попробуйте онлайн!


1
Код смутно напоминает название языка ...
Конор О'Брайен,

@ CᴏɴᴏʀO'Bʀɪᴇɴ Хахаха, оба нечитаемы
Аднан


3

APL, 37 символов

{⍺←3⊃3↑⍵⋄⎕←z←2↑⍵⋄⍺=1:⋄(⍺-1)∇(+/,-/)z}

Может использоваться как

    {⍺←3⊃3↑⍵⋄⎕←z←2↑⍵⋄⍺=1:⋄(⍺-1)∇(+/,-/)z} 10 2
10 2
12 8
20 4
24 16
40 8
48 32
80 16
[...]

или

      {⍺←3⊃3↑⍵⋄⎕←z←2↑⍵⋄⍺=1:⋄(⍺-1)∇(+/,-/)z} 10 2 6
10 2
12 8
20 4
24 16
40 8
48 32

3

MathGolf , 8 байт

ô`αp‼+-∟

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

Принимает ввод в обратном порядке, но это просто потому, что именно так они помещаются в стек. В противном случае это было бы на 1 байт длиннее. 2-3 байта приходит с выхода. Без необходимости фактической печати по одной паре на строку программа может быть æ`‼+-∟(заполняет стек элементами последовательности бесконечно) или É‼+-∟(печатает все элементы последовательности, кроме первого для отладки, пока -dфлаг активен) ,

объяснение

ô      ∟   do-while-true
 `         duplicate the top two items
  αp       wrap last two elements in array and print
    ‼      apply next two operators to the top stack elements
     +     pop a, b : push(a+b)
      -    pop a, b : push(a-b)

Привет макс. Не уверен с тех пор, когда, но в настоящее время версия MathGolf на TIO больше не принимает строковый ввод .. Неважно, что я использую встроенным, даже без какого-либо кода для программы, если строковый ввод дан как для Например ABC, я получаю сообщение об ошибке stdin = StdIn(line)в коде Python ..
Кевин Круйссен

1
@KevinCruijssen Привет! Строковый ввод должен быть задан как 'ABC'или "ABC". Внутренне, ast.literal_evalиспользуется для разбора ввода. Есть еще некоторые причуды, которые нужно устранить, но вы должны быть в состоянии сделать это .
максимум

Ах, хорошо, это имеет смысл. Кстати, есть ли встроенная функция для разделения строки / числа на части определенного размера или некоторого количества частей одинакового размера? Т.е. , ABCDEFчтобы [AB, CD, EF]?
Кевин Круйссен

Nvm, очевидно, нет, но я смог найти способ сделать это: 2ô_2<\1>](жестко запрограммирован на длину ввода 6 и разделен на части размера 2, так как это было то, что мне было нужно, но, вероятно, должно быть изменяемый для работы для общих входных размеров и размеров деталей).
Кевин Круйссен

1
/N

2

Python 3.5, 55 байт:

def q(a,b):
 while 1:print(a,b);a,b=a+b,a-b

Распечатывает правильную последовательность, казалось бы, навсегда. Я был в состоянии позволить этому продолжаться в течение приблизительно 30 минут без каких-либо ошибок, и программа напечатала 2301 цифру для первого номера и 1150 цифр для второго! Исходя из этого, я предполагаю, что при наличии достаточного количества оборудования для работы это может продолжаться WAY дольше и печатать WAY больше цифр, а также теоретически не имеет предела рекурсии, любезно предоставлено whileциклом!


Я думаю, что вы должны распечатать текущие значения в начале цикла, так что первый вывод совпадает с вводом. Кроме того, поскольку это кодовый гольф, вы должны оптимизировать скобки и промежуточные переменные. Наконец, я думаю, что вы должны рассмотреть вопрос о присвоении имен переменным aи bсоответствовать этому вопросу.
Нил

@Neil Спасибо за советы. :)
Р. Кап

Я запутался; whileтеперь у вас есть и рекурсивный вызов ...
Нейл

@ Нил Да, я этого не заметил. Теперь это исправлено, и это просто цикл while, теоретически без ограничений.
Р. Кап

2

Reng v.3.2, 9 байт (самоотвечающий, не конкурирующий)

ii¤ææö±2.

Принимает два входа ( a b) и выходы b a. Попробуй это здесь!

iпринимает входные данные дважды, ¤дублирует стек, æпечатает число и пробел (и делает это дважды, если их два), öпечатает новую строку, ±делает то , что вы ожидаете, и 2.пропускает следующие два символа, оборачивая ввод, получая символы.


2
Хмм, не могли бы вы объяснить, что каждый из этих иероглифов делает с таким новичком, как я? :)
Кевин Круйссен

@KevinCruijssen Я объяснил тайну. :)
Конор О'Брайен

2

Python 2.7, 56 , 42 байта:

a,b=input()
while 1:print a,b;a,b=a+b,a-b

Простой цикл, который либо печатает навсегда (иш).


Вы можете использовать один пробел для уровня отступа, чтобы сохранить байты. Кроме того, вам не нужно использовать оба метода, только один или другой, так что вы можете удалить параметр по умолчанию.
Конор О'Брайен,

О черт, не заметил, что блокнот делал мою вкладку на 4 места, и, конечно, я ограничу ее одним, спасибо.
Serdalis

Если вы сделаете это программой, изменив первую строку на a,b=input(), вы можете удалить отступ.
xnor

@xnor Спасибо, спасает только 1 байт, но это уже не страшно!
Serdalis

2

Пакетная, 54 байта

@echo %1 %2
@set/aa=%1+%2
@set/ab=%1-%2
@%0 %a% %b%

Обратите внимание, что CMD.EXE ограничен 32-разрядными знаковыми целыми числами, поэтому он быстро переполняется и печатает сообщения об ошибках и ошибках.


1
Всегда рады видеть ответ партии здесь! : D
Конор О'Брайен

1
@ C'O'Bʀɪᴇɴ Я написал это специально для тебя.
Нейл

2

Юлия, 25 байт

a<|b=[a b]|>show<a+b<|a-b

Максимальное злоупотребление синтаксисом. Джулия странно . Попробуйте онлайн!

Альтернативная версия, 29 байт

Обратите внимание , что выход будет в конечном итоге переполнения , если вы звоните <|в BigInt . К сожалению, showпрефикс каждого массива BigIntв этом случае. За счет еще четырех байтов мы можем сгенерировать разделенный пробелами вывод для всех числовых типов.

a<|b="$a $b
"|>print<a+b<|a-b

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

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

Мы определяем бинарный оператор <|для наших целей. Он не определен в последних версиях Julia, но все еще распознается синтаксическим анализатором как оператор. Хотя \(не определено явно для целых чисел) на один байт короче, его высокий приоритет потребует замены a+b<|a-bна (a+b)\(a-b)(+3 байта) или \(a+b,a-b)(+2 байта).

Когда a<|bвыполняется, он начинается с вызова showпечати [ab] для STDOUT. Затем a+b<|a-bрекурсивно вызывает <|сумму или разницу.

Поскольку рекурсия (предполагается) бесконечна, сравнение <никогда не выполняется; единственная цель - объединение двух частей кода. Это экономит два байта по сравнению с более простой альтернативой ([a b]|>show;a+b<|a-b).


2

Perl 6 , 23 байта (бесконечно)

Изменить: благодаря JoKing, версия последовательности теперь самая короткая (также удалена .sayза разъяснение из OP:

{@_,{.sum,[-] |$_}...*}

TIO: InfiniteSeq

Старый функциональный ответ

->\a,\b {(a,b).say;f(a+b,a -b)}

TIO: InfiniteFunc

Обратите внимание, что Perl 6 не имеет предела рекурсии как такового, он основан исключительно на доступной памяти, поэтому он достигнет миллионов перед бомбардировкой.


23 байта для бесконечности
Джо Кинг

@Joking: Хорошо! Я чувствую себя довольно глупо, что не думаю о .sum. Я думаю, что требования обязывают выводить данные в функции (я попросил разъяснений, но большинство других, кажется, имеют то, что дает 28 с tio.run/##K0gtyjH7n1upoJamYPu/… )
user0721090601

1

Фактор, 62 байта

:: f ( a b -- x ) a b "%s %s" printf a b + a b - f ; recursive

recursiveили же вызов стека заканчивается слишком быстро.


1

Рубин, 25 байт

Основано на решении xnor's Python . Возможно, я сделаю генератор в другом ответе, но это напечатает a, затем b, затем новый a, затем новый b, до бесконечности.

f=->a,b{p a,b;f[a+b,a-b]}

1

Python 3, 42 байта

Я хотел написать генератор для этой функции, и я так и сделал.

def f(a,b):
 while 1:yield a,b;a,b=a+b,a-b

В Python 3 последовательность генерируется следующим образом:

>>> gen = f(2, 20)
>>> next(gen)
(2, 20)
>>> next(gen)
(22, -18)
>>> next(gen)
(4, 40)
>>> next(gen)
(44, -36)
>>> next(gen)
(8, 80)

1

Common Lisp, 57

(lambda(a b)(loop(print`(,a,b))(psetf a(+ a b)b(- a b))))

Использование psetf, которое влияет на значения переменных параллельно, и простой loopсинтаксис.


1

bash + GNU coreutils, 75 байт

a=$1
b=$2
for i in `seq $3`;{ echo -e "$a\t$b";c=$a;a=$((c+b));b=$((c-b));}

Призвание:

./codegolf.sh 2 10 5

1

CP / M 8080, 47 байтов

Мнемоника z80, но ничего, чего нет у 8080, прокомментировал источник, как только я решил посчитать вывод, а не ввод, но краткие имена функций сохранились, собранные вручную, так что простите хх, где я знаю количество байтов, но не сработало выходные адреса или смещения:

# setup
ld c, 2     0e 02

# loop
.s

# update H (temporarily in B)
ld a, h     7c
add l       85
daa         27
ld b, a     46

# update L
ld a, h     7c
sub l       95
daa         27
ld l, a     6f

# copy B back to H, output H
ld h, b     60
call +o     cd xx xx

# output L
ld b, l     45
call +o     cd xx xx

# repeat
jr -s       18 xx

# output a two-digit BCD value followed by a space
.o

# output high digit
ld a, b     78
rra         1f
rra         1f
rra         1f
rra         1f
call +ob    cd xx xx

# output low digit
ld a, b     78
call +ob    cd xx xx

# output a space
ld e, #$20  1e 20
call 5      cd 00 05

# return
ret         c9

# output a single BCD digit
.ob
and #$f     e6 0f
add #$30    c6 30
ld e, a     5f
call 5      cd 00 05
ret         c9

1

Clojure, 44 байта

#(iterate(fn[[a b]][(+ a b)(- a b)])[%1 %2])

Функция, которая производит бесконечную ленивую последовательность.


1

Perl 5, 40 байт

требует -E(бесплатно)

sub a{say"@_";($c,$d)=@_;a($c+$d,$c-$d)}

или (той же длины)

$_=<>;{say;/ /;$_=$`+$'.$".($`-$');redo}

(Я выбрал последнее, потому что в некоторых итерациях должны быть ошибки округления.)

Шапка-наконечник.

Но я подозреваю, что должно быть более короткое решение Perl 5.


1
Если есть более короткое решение, Тон Хоспел найдет его. : P
Конор О'Брайен

Прошло некоторое время, но я нашел более короткий путь:
Xcali

1

ВОЗВРАТ , 21 байт

[¤.' ,$.'
,¤¤+2ª-F]=F

Try it here.

Рекурсивный оператор-лямбда. Использование:

[¤.' ,$.'
,¤¤+2ª-F]=F10 2F

объяснение

[                 ]=F  declare function F for recursion
 ¤.' ,$.'␊,            output top 2 stack items along with trailing newline
           ¤¤+2ª-      get plus and minus of top 2 stack items
                 F     recurse!

1

> <> , 26 байт

:?!;1-r:n48*o:@@:nao:@+}-$

Вызов с a, b, nв стеке, где nэто число витков или значение отрицательного для бесконечной мощности. Выходы aи bразделены пробелом.

В качестве объяснения, вот как эволюционирует стек во время выполнения:

abn
nba
nbaa
naab
naabb
nabab
nab+
+nab
+n-
+-n

Вы можете попробовать его на онлайн-переводчике с положительным количеством поворотов, но вам нужно будет использовать официальный интерпретатор python для тестирования бесконечного режима.

$ python fish.py -c ':?!;1-r:n48*o:@@:nao:@+}-$' -t 0.01 -v 10 2 -1
10 2
12 8
20 4
24 16
40 8
48 32
80 16
96 64
160 32
192 128
320 64
384 256
640 128
768 512
1280 256
1536 1024
2560 512
3072 2048
5120 1024
6144 4096
10240 2048
12288 8192
20480 4096
24576 16384
40960 8192
49152 32768
81920 16384
98304 65536
163840 32768
196608 131072
327680 65536
393216 262144
655360 131072
786432 524288
1310720 262144
[...]

1

Нечеткое окто гуакамоле , 17 16 байтов

(не конкурирует, использует функции позже, чем вызов)

^^(:C.Zs.aZ.s.-)

Это было трудно сделать из-за ошибок на стороне клиента. Но я понял!

Прохождение:

^^                # Get input twice, pushes it to the stack.
  (               # Start a infinite loop.
   :              # Prints the stack, and since it has [a,b] is just the output.
    C             # Copy the active stack to the inactive stack.
     .            # Shift the active stack.
      Z           # Reverse the stack.
       s          # Move the top item on the active stack to the top of the inactive.
        .         # Switch stacks again.
         a        # Add the top 2 items, giving the first new item.
          Z       # Reverse the stack, so we keep the 'a' safe and prepare for the 'b'.
           .      # Switch stacks.
            s     # Move the top item on the active stack to the top of the inactive stack.
             .    # Switch stacks.
              -   # Minus the top 2 items, giving 'b'.
               )  # End infinite loop.

Я не очень хорошо знаю FOG, но разве вы не можете переместить :начало цикла и избавиться от необходимости печатать дважды?
Конор О'Брайен

оооооо @ CᴏɴᴏʀO'Bʀɪᴇɴ спасибо.
Rɪᴋᴇʀ

Не забудьте обновить объяснение;)
Конор О'Брайен

@ C'O'Bʀɪᴇɴ Что ты имеешь в виду? : P
Rɪᴋᴇʀ

1

Серьезно, 12 байт

,,1WX■@│+)-1

Выводит бесконечный поток, формат - b(n) a(n)одна пара выходов на строку.

Нет онлайн-ссылки, потому что TryItOnline не очень хорошо справляется с бесконечными циклами.

Объяснение:

,,1WX■@│+)-1
,,1           push a(0), push b(0), push 1
   W          while loop:
    X           discard the 1 (only used to make sure the while loop always runs)
     ■          print all stack elements, separated by spaces, without popping
      @│        swap, duplicate entire stack
        +)      push a(n) + b(n) (a(n+1)) and move it to the bottom of the stack
          -     push a(n) - b(n) (b(n+1))
           1    push 1 to make sure the loop continues

1

J, 16 12 байт

0&(]+/,-/)~<

Производит только первые значения k для последовательности на основе заданных начальных чисел.

Сохранено 4 байта с использованием трюка (или синтаксического сахара), показанного @randomra в этом комментарии .

использование

   f =: 0&(]+/,-/)~<
   2 20 f 10
  2   20
 22  _18
  4   40
 44  _36
  8   80
 88  _72
 16  160
176 _144
 32  320
352 _288

1

C #, 50 байтов

f=(a,b)=>{Console.WriteLine(a+" "+b);f(a+b,a-b);};

Полный исходный код, включая контрольный пример:

using System;
using System.Numerics;

namespace PlusMinusSequence
{
    class Program
    {
        static void Main(string[] args)
        {
            Action<BigInteger,BigInteger>f=null;
            f=(a,b)=>{Console.WriteLine(a+" "+b);f(a+b,a-b);};
            BigInteger x=10, y=2;
            f(x,y);
        }
    }
}

Тип данных BigInteger используется, чтобы числа не переполнялись и не становились равными 0. Однако, поскольку это рекурсивное решение, следует ожидать переполнения стека.

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