Інферетні геометричні послідовності


18

Haskell має цю акуратну (-видовий) особливість, де ви можете дати їй три числа, і він може зробити з них арифметичну послідовність. Наприклад, [1, 3..27]еквівалентно [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27].

Це здорово, і всі, крім арифметичних послідовностей, досить обмежуючі. Доповнення, pfft . Множення - це місце. Чи не було б крутіше, якби це робило геометричні послідовності, як [1, 3..27]повернення [1, 3, 9, 27]?

Виклик

Напишіть програму / функцію, яка приймає три натуральних цілих числа a , b і c, і виводить, де x - найбільше ціле число ≤ c, яке може бути представлене як де n - додатне ціле число.[a, b, b × (b ÷ a), b × (b ÷ a)2, ..., x]b × (b ÷ a)n

Тобто вихід повинен бути r таким, щоб:

r0 = a
r1 = b
rn = b × (b ÷ a)n-1
rlast = greatest integer ≤ c that can be represented as b × (b ÷ a)n
         where n is a positive integer

Технічні умови

  • Застосовуються стандартні правила вводу / виводу .
  • Стандартні лазівки будуть заборонені .
  • b завжди буде ділитися на a .
  • a < bc
  • Ця проблема полягає не в пошуку найкоротшого підходу на всіх мовах, а в пошуку найкоротшого підходу в кожній мові .
  • Ваш код буде набраний у байтах , як правило, в кодуванні UTF-8, якщо не вказано інше.
  • Вбудовані функції (у Mathematica може бути одна: P), які обчислюють цю послідовність, дозволені, але включається рішення, яке не покладається на вбудований.
  • Пояснення навіть для "практичних" мов заохочуються .

Тестові справи

a   b   c     r

1   2   11    [1, 2, 4, 8]
2   6   100   [2, 6, 18, 54]
3   12  57    [3, 12, 48]
4   20  253   [4, 20, 100]
5   25  625   [5, 25, 125, 625]
6   42  42    [6, 42]

У кількох кращих форматах:

1 2 11
2 6 100
3 12 57
4 20 253
5 25 625
6 42 42

1, 2, 11
2, 6, 100
3, 12, 57
4, 20, 253
5, 25, 625
6, 42, 42

@ Adám No. (див. Перший тестовий випадок)
user202729

1
Зауважте, що формула просто b ^ n / a ^ n-1 . Починаючи з n = 0
H.PWiz

2
Звичайно, у Mathematica є вбудований ...
Ніл

чи прийнятно, якщо результати є не цілими числами через помилки з плаваючою комою?
Луїс Мендо

@LuisMendo Так.
повністюлюдсько

Відповіді:


6

Лушпиння , 8 байт

~↑≤Ṡ¡o//

Введення в порядку b, c, a . Спробуйте в Інтернеті!

Пояснення

~↑≤Ṡ¡o//  Implicit inputs.
       /  a/b as exact rational number.
     o/   Divide by a/b (so multiply by b/a).
    ¡     Iterate that function
   Ṡ      on a. Result is the infinite list [a, b, b^2/a, b^3/a^2, ..
 ↑        Take elements from it while
~ ≤       they are at most c.

Контроль потоку в цій програмі трохи важко прослідкувати. Спочатку b подається вправо /, виробляючи функцію, /bяка ділиться на b . Далі, ~розбиває залишилася програму на три частини: ~(↑)(≤)(Ṡ¡o//b). Це підживлює гр в і до і складає результати з . Результатом роботи є функція, яка перевіряє, чи є її аргумент максимумṠ¡o//b≤c c , і ↑≤cприймає найдовший префікс елементів, для яких це справедливо.

Залишилося показати, як (Ṡ¡o//b)aоцінюється до потрібного нескінченного списку. Частина в дужках розділена на Ṡ(¡)(o//b). Потім канали до , подає результат , а потім дає для другого аргументу. Вираз дає функцію, яка приймає число і ділить її на a / b , і повторює цю функцію на другому аргументі, який є a .o//b¡(o//b)a¡

Ось низка перетворень, які візуалізують пояснення:

  (~↑≤Ṡ¡o//) b c a
= (~↑≤Ṡ¡o/(/b)) c a
= ~(↑)(≤)(Ṡ¡o/(/b)) c a
= ↑(≤c)((Ṡ¡o/(/b)) a)
= ↑(≤c)(Ṡ(¡)(o/(/b)) a)
= ↑(≤c)(¡(o/(/b)a) a)
= ↑(≤c)(¡(/(/ba))a)
Last line in English: takeWhile (atMost c) (iterate (divideBy (divideBy b a)) a)

Альтернативне рішення з використанням явних змінних у порядку a, b, c :

↑≤⁰¡*/⁵²



3

JavaScript (ES6), 41 37 байт

Збережено 4 байти завдяки @Neil

Вводиться як " (b,c)(a).

(b,c)=>g=a=>a>c?[]:[a,...g(b,b*=b/a)]

Тестові справи

Прокоментував

(b, c) =>                 // main function taking b and c
  g = a =>                // g = recursive function taking a
    a > c ?               //   if a is greater than c:
      []                  //     stop recursion and return an empty array
    :                     //   else:
      [ a,                //     return an array consisting of a, followed by 
        ...g(             //     the expanded result of a recursive call to g()
          b,              //       with a = b
          b *= b / a      //       and b = b * ratio
        ) ]               //     end of recursive call

1
Перестановка аргументів дає мені (b,c)=>g=a=>a>c?[]:[a,...g(b,b*=b/a)].
Ніл



2

Python 3, 93 90 74 73 байт

x=lambda a,b,c,i=0,q=[]:a*(b/a)**i>c and q or x(a,b,c,i+1,q+[a*(b/a)**i])

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

Дякую Роду та user202729 за те, що допомогли мені зменшити досить багато байт!


1
def + return -> lambda. Підказки Пітона.
користувач202729

1
Також ви можете import*.
користувач202729

1
ви можете використовувати while i<=c:i++(замість розуміння списку + журнал), щоб зберегти багато байтів
стрижень

@Rod Як я повинен використовувати цикл while без журналу? ідк, як довго повторювати
Маніш Кунду



2

Perl 6 , 26 24 байти

{$^a,$^b,$b²/$a...^*>$^c}
{$^a,*×$^b/$a...^*>$^c}

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

Оператор послідовності Perl 6 ... може автоматично виводити геометричні ряди.

Оновлення: ... Це може , але в цій ситуації, не роблячи висновку, це трохи коротше.


1

05AB1E , 12 байт

Введіть у порядку c,b,a

ÝmI¹Ý<m/ʒ¹›_

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

Пояснення

Ý              # push the range [0 ... c]
 m             # raise b to the power of each
  I            # push a
   ¹Ý          # push the range [0 ... c]
     <         # decrement each
      m        # push a to the power of each
       /       # elementwise division of ranges
        ʒ      # filter, keep only elements that are
         ¹›_   # not greater than c

1

MATL , 17 байт

t:,qtiw^w]x/tb>~)

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

Просто для того, щоб м'яч котився в MATL. Я не можу уявити, що існує не менш багатослівний спосіб вирішення цього питання.


1
... Жодного потрійного заперечення, будь ласка.
користувач202729

2
@ user202729 Я не бачу, як ти не міг зрозуміти, що це не випадковість. :)
Sanchises

Ви не маєте на увазі "Я не бачу, як ти не міг зрозуміти, що це було зроблено ненавмисно": P
HyperNeutrino

@HyperNeutrino No.
Санчіз



1

MATL , 12 байт

y/ivZlZ}3$:W

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

y     % Implicitly take two inputs, and duplicate the first onto the top
/     % Divide
i     % Take third input
v     % Vertically concatenate the three numbers into a column vector
Zl    % Binary logarithm, element-wise
Z}    % Split the vector into its three components
3$:   % Three-input range. Arguments are start, step, upper limit
W     % 2 raised to that, element-wise. Implicit display

1
Це справді приємно. Я боровся з повторним використанням aі c(у мене багато спроб починати y/i), але використовуючи цей метод, ви акуратно тримаєте все разом.
Санчіз

1
цей підхід був насправді на 3 байти коротшим і в Октаві.
Санчіз

0

Perl, 38 байт

Включити +3для -n( use 5.10.0розблокувати функції Perl 5.10 безкоштовно)

#!/usr/bin/perl -n
use 5.10.0;
/ \d+/;say,$_*=$&/$`until($_+=0)>$'

Потім запустіть як:

geosequence.pl <<< "1 3 26"


0

Japt , 14 байт

ÆWpX zVpXÉÃf§U

Спробуй це


Пояснення

                    :Implicit input of integers U=c, V=a & W=b
Æ         Ã         :Range [0,U) and pass each X through a function
 WpX                :  W to the power of X
     z              :  Floor divide by
      VpXÉ          :  V to the power of X-1
           f§U      :Filter elements less than or equal to U


0

TI-BASIC, 31 байт

Здійснює введення даних від користувача та виводить в Ans. Я вирішив для n в c = b n / a n-1 , отримуючи n = 1 + ln (c / b) / ln (b / a). Це те саме, що n = 1 + log b / a (c / b). Для цілей гольфу я починаю свою послідовність на -1 і закінчую її на n-1, а не на 0 до n.

Prompt A,B,C
seq(B(B/A)^N,N,-1,logBASE(C/B,B/A

0

APL (Dyalog Unicode) , 38 байт

{(g≤⊃⌽⍵)⊆gf,(⍵[1]*p+1)÷(f←⊃⍵)*p←⍳⊃⌽⍵}

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

Префікс Dfn. Вводить порядок a b cі використовує ⎕IO←0( I ndex O rigin)

Завдяки @ErikTheOutgolfer за те, що голив 6 байтів з цього, перш ніж я навіть розмістив його.

Як?

{(g≤⊃⌽⍵)⊆gf,(⍵[1]*p+1)÷(f←⊃⍵)*p←⍳⊃⌽⍵}  Prefix Dfn. Input  is a vector
                                    ⌽⍵   Reverse ⍵. Yields c b a
                                        Pick the first element (c)
                                        Index. Yields the integers 0..c-1
                                p       Assign to the variable p
                               *         Exponentiate
                         (f←⊃⍵)          Pick the first element of  (a) and assign to f
                                         This yields the vector (a^0, a^1, ..., a^c-1)
                        ÷                Element-wise division
                    p+1)                 The vector 1..c
                   *                     Exponentiate
              (⍵[1]                      Second element (because of IO0) of  (b)
                                         This yields the vector (b^1, b^2, ..., b^c)
            f,                           Prepend f (a). This yields the vector 
                                         (a, b^1/a^0, b^2/a^1, ...)
          g                             Assign the vector to g
                                        Partition. This takes a boolean vector as left
                                         argument and drops falsy elements of the right argument.
     ⊃⌽⍵)                                Pick the last element of  (c)
  (g                                    Check if each element of gc. Yields the boolean
                                         vector that is the left argument for 

0

Stax , 14 байт CP437

ü╞¥ß¥║/,5å╘⌂åº

16 байт при розпакуванні,

E~Y/y{;^<}{[*gfm

Запуск та налагодження в Інтернеті!

Вводиться у вигляді [b, a, c] .

Досить впевнений, що @recursive має кращі рішення.

Пояснення

E~                              Parse  input, put `c` on input stack
  Y/                            Store `a` in register `y` and calculate `b`/`a`
    y                           Put `y` back to main stack, stack now (from top to bottom): [`a`, `b`/`a`]
     {   }{  gf                 generator
      ;^<                       Condition: if the generated number is smaller than the top of input stack (i.e. `c`)
           [*                   duplicate the second item in main stack and multiply it with the item at the top
                                   i.e. multiply last generated value by `b/a` and generate the value
              m                 Output array, one element on each line



0

APL (Dyalog) , 23 байти ( SBCS) )

Це бере аргументи ab зліва і c праворуч,

{⊃(⍵∘≥⊆⊢)⊣/⍵2⍴⍺,÷\⍵⍴⌽⍺}

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

Мабуть, коротший шлях, але я подумав, що ÷\ це мило.

Пояснили:

{...}Анономічна функція ⍺ є a b, є c. Скажімоa b c = 2 6 100

⌽⍺Реверс :6 2

⍵⍴Повторення разів:6 2 6 2 6 2 6 2 ...

÷\ Зменшити поділом на префікси: 6 (6÷2) (6÷(2÷6)) (6÷(2÷(6÷2))).. = 6 3 18 9 54 ..

⍺,Доплатити :2 6 6 3 18 9 54 27 162 81 ...

⊣/⍵2⍴ Отримайте кожен інший елемент (плюс кілька останніх повторів):

  ⍵2⍴Створіть рядок, 2матрицю стовпців із2 6 6 3 18 9 54 ...

  ⊣/ Отримайте перший стовпець

⊆⊢ Розділіть масив на блоки, де

⍵∘≥ більший або рівний всім елементам

Візьміть перший такий блок

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.