Получить список результатов функции до результата › x

Я в основном хочу то же самое, что и этот OP: -condition-is-met">Есть ли идиома J для добавления в список до тех пор, пока не будет выполнено определенное условие? Но я не могу получить ответы для работы с функцией OP или моей собственной. Я перефразирую вопрос и напишу об ответах внизу.

Я пытаюсь создать функцию, которая будет возвращать список чисел Фибоначчи менее 2 000 000. (без записи «пока» внутри функции). Вот что я пробовал:

Во-первых, я выбрал способ вычисления чисел Фибоначчи с этого сайта: https://code.jsoftware.com/wiki/Essays/Fibonacci_Sequence

fib =: (i. +/ .! i.@-)"0
        echo fib i.10
        0 1 1 2 3 5 8 13 21 34

Затем я составил произвольный список, который, как я знал, был больше, чем мне нужно. :

fiblist =: (fib i.40)       NB. THIS IS A BAD SOLUTION!

Наконец, я удалил числа, которые были больше, чем мне нужно:

result =: (fiblist < 2e6) # fiblist 
        echo result 
        0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181     6765 10946 17711    28657 46368 75025 121393 196418 317811 514229 832040 1.34627e6

Это дает правильный результат, но есть ли способ избежать использования произвольного числа, например 40, в «fib i.40»?

Я хотел бы написать функцию, чтобы «func 2e6» возвращала список чисел фибоначчи ниже 2 000 000. (без записи «пока» внутри функции).

echo func 2e6
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711    28657 46368 75025 121393 196418 317811 514229 832040 1.34627e6

вот ответы на другой вопрос:

первый ответ:

 2 *^:(100&>@:])^:_"0 (1 3 5 7 9 11)
    128 192 160 112 144 176

второй ответ:

+:^:(100&>)^:(<_) ] 3 
3 6 12 24 48 96 192

Насколько я понимаю, мне просто нужно заменить функции, используемые в ответах, но я не понимаю, как это может работать. Например, если я попытаюсь:

echo (, [: +/ _2&{.)^:(100&>@:])^:_ i.2

Я получаю сообщение об ошибке.


person Arimaafan    schedule 26.08.2018    source источник
comment
Боб забыл о Джей больше, чем я когда-либо узнаю. Хотя он дал правильный ответ на ваш основной вопрос, вот что я в конечном итоге придумал для генерации чисел Фибоначчи в J. Он обрабатывает генерацию x числа Фибоначчи, а также Фибоначчи до x, Трибоначчи и т. д. pastebin.com/fKZFU60P   -  person Gregory Higley    schedule 01.09.2018
comment
Хорошее решение, Грег. Возможно, я забыл о J больше, чем большинство людей, но это только потому, что я, кажется, довольно хорошо забываю. Я желаю нам обоим, чтобы твоя способность знать всегда превосходила мою способность забывать. :-)   -  person bob    schedule 01.09.2018


Ответы (1)


Я подошел к этому так. Во-первых, я хочу иметь способ генерировать n-е число Фибоначчи, и я использовал f0b из вашей ссылки на эссе Jsoftware.

   f0b=: (-&2 +&$: -&1) ^: (1&<) M.

Как только у меня это получилось, я просто хочу поместить его в глагол, который будет проверять, меньше ли результат f0b определенной суммы (я использовал 1000), и если да, то я увеличивал ввод и повторял процесс снова. Это часть ($:@:>:). $: — это ссылка на самого себя. Правильный аргумент 0 является отправной точкой для создания последовательности.

   ($:@:>: ^: (1000 > f0b)) 0
17

Это говорит мне о том, что 17-е число Фибоначчи является самым большим числом меньше моего предела. Я использую эту информацию для генерации чисел Фибоначчи, применяя f0b к каждому элементу в i. ($:@:>: ^: (1000 > f0b)) 0, используя ранг 0 (fob"0).

   f0b"0 i. ($:@:>: ^: (1000 > f0b)) 0
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

В вашем случае вам нужны были под 2000000

   f0b"0 i. ($:@:>: ^: (2000000 > f0b)) 0
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269

... а потом я понял, что вам нужен глагол, чтобы ответить на ваш первоначальный вопрос. Я выбрал dyadic, где левый аргумент является пределом, а правый аргумент генерирует последовательность. Та же идея, но я смог использовать некоторые крючки, когда перешел к неявной форме. (> f0b) проверяет, находится ли результат f0b ниже предела, и ($: >:) увеличивает правый аргумент, позволяя оставить левый аргумент для $:

   2000000 (($: >:) ^: (> f0b)) 0
32
   fnum=: (($: >:) ^: (> f0b)) 
   2000000 fnum 0
32
   f0b"0 i. 2000000 fnum 0
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269

Я почти не сомневаюсь, что другие придумают лучшие решения, но это то, что я собрал сегодня вечером.

person bob    schedule 27.08.2018