Послідовність плюс-мінус


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 2a(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

@Suever Ні, не може.
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Дякую за роз’яснення!
Suever

1
Повернення послідовності добре @guifa
Conor O'Brien

Відповіді:


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.

Ого. Це дуже вражає.
Conor O'Brien

Що Main linkнасправді означає?
кіт

4
@cat Це як основна функція C. Кожен рядок визначає іншу функцію / посилання, але останній викликається автоматично при виконанні програми.
Денніс

> Програми желе містять до 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 Схоже, це і є. Це не видається явно забороненим у початковій заяві проблеми.
Suever

Ого, це досить круто. У Python, якщо у вас дуже велика кількість, він все одно виводить усі цифри, одна за одною, тому він стає трохи стомлюючим на це все. Я просто подумав, що це зробив і більшість інших мов, але схоже, що Python є унікальним у цьому випадку.
Р. Кап

Так що в MATLAB (який MATL використовує під кришкою), ви можете змінити вихідний формат таким, яким ви хочете. За замовчуванням MATL - відображення до 15 чисел перед переходом на наукову нотацію.
Suever

OOPS мій поганий, вибачте, видалений;)
thepiercingarrow

3

Хаскелл, 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
Перший і останній Qможна видалити - Pyth заповнить їх неявно.
isaacg

@isaacg Так що тоді реалізували? Класно. Я спробував видалити перший, але це не вийшло.
PurkkaKoodari

Це дивно, видалення першого працювало на моїй машині.
isaacg

3

C, 81 байт

a,b;main(c){for(scanf("%d%d%d",&a,&b,&c);c--;a+=b,b=a-b-b)printf("%d %d\n",a,b);}

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
Код невиразно нагадує назву мови ...
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Hahaha, обидва нечитані
Аднан


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використовується для розбору вхідних даних. Є ще деякі химерності, які потрібно прасувати, але ви повинні зробити це .
maxb

Ну добре, це має сенс. Btw, чи є вбудований файл, щоб розділити рядок / число на частини певного розміру або деяку кількість частин однакового розміру? Тобто , ABCDEFщоб [AB, CD, EF]?
Кевін Круїссен

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

1
/н

2

Python 3.5, 55 43 байт:

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

Видає правильну послідовність, здавалося б, назавжди. Я міг дозволити це тривати близько 30 хвилин без жодної помилки, і програма надрукувала 2301 цифру для першого номера та 1150 цифр для другого! Виходячи з цього, я здогадуюсь, що, забезпечивши достатньо обладнання для роботи, це може тривати довше і надрукувати WAY більше цифр, а також теоретично не має рекурсійного обмеження, люб’язність whileциклу!


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

@Neil Дякую за поради. :)
Р. Кап

Я збентежений; зараз у вас є whileі рекурсивний дзвінок ...
Ніл

@Neil Так, я цього не помічав. Тепер це виправлено, і лише певний час, теоретично ніяких обмежень.
Р. Кап

2

Reng v.3.2, 9 байт (самовідповідь, неконкуренція)

ii¤ææö±2.

Бере два входи ( a b) та виходи b a. Спробуйте тут!

iприймає введення двічі, ¤дублює стек, æдрукує число і пробіл (і робить це двічі, їх два), öдрукує новий рядок, ±робить те, що ви могли очікувати, і 2.пропускає наступні два символи, обертаючись навколо введення, отримуючи символи.


2
Хм, чи не проти ви пояснити, що кожен з цих ієрогліфів робить новонародженому, як я? :)
Kevin Cruijssen

@KevinCruijssen Я пояснив таємницю. :)
Conor O'Brien

2

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

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

Простий цикл, який або друкується назавжди (ish).


Ви можете використовувати один пробіл для рівня відступу для збереження байтів. Крім того, вам не доведеться виконувати обидва способи, лише той чи інший, щоб ви могли видалити параметр за замовчуванням.
Conor O'Brien

О чорт не помітив, блокнот робив мою вкладку на 4 пробіли, і впевнений, я обмежу її одним, спасибі
Сердаліс

Якщо ви зробите цю програму, змінивши перший рядок на a,b=input(), ви можете видалити відступ.
xnor

@xnor Спасибі, зберігається лише 1 байт, але це вже не негарно!
Сердаліс

2

Пакет, 54 байти

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

Зауважте, що CMD.EXE обмежений 32-бітовими цілими числами, тому він швидко переповнює та друкує сміття та повідомлення про помилки.


1
Завжди люблю бачити тут відповідь! : D
Conor O'Brien

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

Спробуйте в Інтернеті!

Як це працює

Ми визначаємо двійковий оператор <|для зовнішніх цілей. Він не визначений в останніх версіях Джулії, але все ще визнаний аналізатором парсером. Хоча \(не визначено явно для цілих чисел) на один байт коротше, його високий пріоритет потребує заміни 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за уточненням з ОП:

{@_,{.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 байт

На основі рішення Python xnor . Можливо, я зроблю генератор в іншій відповіді, але це надрукує a, то b, то нове a, то нове b, ad infinitum.

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 немає, коментує джерело, як тільки я вирішив порахувати вихід, а не вхід, але збережені короткі назви функцій, зібрані вручну, тож пробачте xx, де я знаю кількість байтів, але не працювали вихідні адреси або компенсації:

# 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
Conor O'Brien

Минув час, але я знайшов коротший шлях:
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 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 все так добре, але хіба ви не можете перенести :на початок циклу і усунути необхідність друку двічі?
Conor O'Brien

oooooh @ CᴏɴᴏʀO'Bʀɪᴇɴ дякую.
Rɪᴋᴇʀ

Не забудьте оновити пояснення;)
Conor O'Brien

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