Wnioskuj sekwencje geometryczne

18

Haskell ma tę zgrabną (wyglądającą) funkcję, w której możesz nadać jej trzy liczby i może wywnioskować z nich sekwencję arytmetyczną. Na przykład [1, 3..27]jest równoważne z [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27].

To fajne, a wszystkie sekwencje arytmetyczne są dość ograniczone. Dodawanie, pfft . Mnożenie jest tam, gdzie jest. Czy nie byłoby fajniej, gdyby sekwencje geometryczne przypominały [1, 3..27]powrót [1, 3, 9, 27]?

Wyzwanie

Napisz program / funkcję, która przyjmuje trzy dodatnie liczby całkowite a , b i c, i wyprowadza, gdzie x jest największą liczbą całkowitą ≤ c, którą można przedstawić jako gdzie n jest liczbą całkowitą dodatnią.[a, b, b × (b ÷ a), b × (b ÷ a)2, ..., x]b × (b ÷ a)n

Oznacza to, że wynik powinien mieć wartość r , tak aby:

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

Dane techniczne

  • Zasady Standard I / O zastosowania .
  • Standardowe lukizabronione .
  • b zawsze będzie podzielne przez a .
  • a < bc
  • Wyzwanie to nie polega na znalezieniu najkrótszego podejścia we wszystkich językach, chodzi raczej o znalezienie najkrótszego podejścia w każdym języku .
  • Twój kod będzie oceniany w bajtach , zwykle w kodowaniu UTF-8, chyba że określono inaczej.
  • Wbudowane funkcje (Mathematica może mieć jeden: P), które obliczają tę sekwencję są dozwolone, ale zalecane jest uwzględnienie rozwiązania, które nie opiera się na wbudowanej.
  • Zachęca się do wyjaśnień, nawet w przypadku „praktycznych” języków .

Przypadki testowe

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]

W kilku lepszych formatach:

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
całkowicie ludzki
źródło
@ Adám No. (patrz pierwszy przypadek testowy)
202729
1
Zauważ, że formuła jest po prostu b ^ n / a ^ n-1 . Począwszy od n = 0
H.PWiz
2
Oczywiście Mathematica ma wbudowane ...
Neil
czy jest dopuszczalne, jeśli wyniki nie są dokładnie liczbami całkowitymi z powodu błędów zmiennoprzecinkowych?
Luis Mendo,
@LuisMendo Tak.
całkowicie ludzki,

Odpowiedzi:

6

Łuska , 8 bajtów

~↑≤Ṡ¡o//

Dane wejściowe są w kolejności b, c, a . Wypróbuj online!

Wyjaśnienie

~↑≤Ṡ¡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.

Przepływ sterowania w tym programie jest nieco trudny do naśladowania. Po pierwsze, b jest podawane na prawo /, tworząc funkcję, /bktóra dzieli przez b . Następnie ~dzieli pozostałą programu na trzy części: ~(↑)(≤)(Ṡ¡o//b). This pasze c do i się i łączy wyniki z . Wynikiem jest funkcja, która sprawdza, czy jej argument ma co najwyżej c , i przyjmuje najdłuższy prefiks elementów, dla których to się utrzymuje.Ṡ¡o//b≤c↑≤c

Pozostaje pokazać, jak (Ṡ¡o//b)aewaluuje do pożądanej listy nieskończonej. Część w nawiasach jest podzielona na Ṡ(¡)(o//b). Następnie zasila się , podaje wynik , a następnie daje do drugiego argumentu. Wyrażenie podaje funkcję, która przyjmuje liczbę i dzieli ją przez a / b , i iteruje tę funkcję na drugim argumencie, którym jest a .o//b¡(o//b)a¡

Oto seria transformacji, które wizualizują wyjaśnienie:

  (~↑≤Ṡ¡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)

Alternatywne rozwiązanie wykorzystujące zmienne jawne w kolejności a, b, c :

↑≤⁰¡*/⁵²
Zgarb
źródło
5

Python 2 , 42 bajty

a,b,c=input()
x=b/a
while c/a:print a;a*=x

Wypróbuj online!

Podejście rekurencyjne, 42 41 bajtów

-1 bajt dzięki ovs

f=lambda a,b,c:c/a*[a]and[a]+f(b,b*b/a,c)

Wypróbuj online!

Pręt
źródło
4

Proton , 35 bajtów

f=(a,b,c)=>c//a?[a]+f(b,b*b/a,c):[]

Wypróbuj online!

Pan Xcoder
źródło
1
ludzie faktycznie pamiętają ten język? : D
HyperNeutrino
1
@HyperNeutrino Aktywnie go używam :)
Mr. Xcoder
3
Wiem, że prawdopodobnie nie otrzymam żadnej odpowiedzi, ale dlaczego głosowanie negatywne?
Pan Xcoder,
3

JavaScript (ES6), 41 37 bajtów

Zaoszczędź 4 bajty dzięki @Neil

Pobiera dane wejściowe jako (b,c)(a).

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

Przypadki testowe

Skomentował

(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
Arnauld
źródło
1
Ułożenie argumentów daje mi (b,c)=>g=a=>a>c?[]:[a,...g(b,b*=b/a)].
Neil
2

Python 3, 93 90 74 73 bajty

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])

Wypróbuj online

Podziękowania dla Rod i user202729 za pomoc w zmniejszeniu całkiem sporo bajtów!

Manish Kundu
źródło
1
def + return -> lambda. Wskazówki dotyczące Pythona.
user202729,
1
Ty też możesz import*.
user202729,
1
możesz użyć while i<=c:i++(zamiast listowania + dziennika), aby zaoszczędzić dużo bajtów
Rod
@Rod Jak korzystać z pętli while bez dziennika? idk, jak długo iterować
Manish Kundu
1
-1 bajt .
user202729,
2

Oktawa , 38 35 bajtów

@(a,b,c)exp(log(a):log(b/a):log(c))

Wypróbuj online!

Okazuje się, że podejście MATL @ LuisMendo pozwala również zaoszczędzić 3 bajty w Octave, pomimo logtrzykrotnego powtórzenia .

Sanchises
źródło
2

Perl 6 , 26 24 bajtów

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

Wypróbuj online!

Operator sekwencji w Perlu 6 ...może natywnie wnioskować o szeregach geometrycznych.

Aktualizacja: ... Może , ale w tej sytuacji nie wnioskowanie jest nieco krótsze.

Sean
źródło
1

05AB1E , 12 bajtów

Wprowadź w kolejności c,b,a

ÝmI¹Ý<m/ʒ¹›_

Wypróbuj online!

Wyjaśnienie

Ý              # 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
Emigna
źródło
1

MATL , 17 bajtów

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

Wypróbuj online!

Tylko po to, żeby piłka toczyła się w MATL. Nie mogę sobie wyobrazić, że nie ma mniej pełnego sposobu rozwiązania tego problemu.

Sanchises
źródło
1
... Proszę nie potrójną negację.
user202729,
2
@ user202729 Nie rozumiem, jak mogłeś nie dojść do wniosku, że to nie był wypadek. :)
Sanchises
Nie masz na myśli „Nie rozumiem, jak mógłbyś nie dojść do wniosku, że nie zostało to zrobione przypadkowo”: P
HyperNeutrino
@HyperNeutrino Nie.
Sanchises
Trzymaj piłkę
Luis Mendo,
1

Haskell, 35 bajtów

(a#b)c|a>c=[]|d<-div b a*b=a:(b#d)c

Wypróbuj online!

nimi
źródło
1
34 bajty . (więcej „w duchu wyzwania”, straszny błąd zmiennoprzecinkowy)
user202729
@ user202729: proszę umieszczać je jako oddzielny odpowiedź (ale zapisać bajt: exp<$>[...])
Nimi
1

MATL , 12 bajtów

y/ivZlZ}3$:W

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie

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
Luis Mendo
źródło
1
To jest naprawdę miłe. Walczyłem z ponownym użyciem ai c(mam wiele nieudanych prób, zaczynając od y/i), ale stosując tę ​​metodę, starannie utrzymujesz wszystko razem.
Sanchises
1
takie podejście było w rzeczywistości również o 3 bajty krótsze w Octave.
Sanchises
0

Perl, 38 bajtów

Dołącz +3do -n( use 5.10.0aby odblokować funkcje Perla 5.10 jest bezpłatne)

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

Następnie uruchom jako:

geosequence.pl <<< "1 3 26"
Ton Hospel
źródło
0

Japt , 14 bajtów

ÆWpX zVpXÉÃf§U

Spróbuj


Wyjaśnienie

                    :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
Kudłaty
źródło
0

TI-BASIC, 31 bajtów

Pobiera dane wejściowe od użytkownika i dane wyjściowe w Ans. Rozwiązałem dla nw c = b n / a n-1 , otrzymując n = 1 + ln (c / b) / ln (b / a). To to samo co n = 1 + log b / a (c / b). Na potrzeby gry w golfa rozpoczynam sekwencję od -1, a kończę od n-1 zamiast od 0 do n.

Prompt A,B,C
seq(B(B/A)^N,N,-1,logBASE(C/B,B/A
kamoroso94
źródło
0

APL (Dyalog Unicode) , 38 bajtów

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

Wypróbuj online!

Prefiks Dfn. Pobiera dane wejściowe w kolejności a b ci używa ⎕IO←0( I ndex O rigin)

Dzięki @ErikTheOutgolfer za golenie 6 bajtów z tego, zanim jeszcze opublikowałem.

W jaki sposób?

{(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 
J. Sallé
źródło
0

Stax , 14 bajtów CP437

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

16 bajtów po rozpakowaniu,

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

Uruchom i debuguj online!

Pobiera dane wejściowe w postaci [b, a, c].

Jestem pewien, że @recursive ma lepsze rozwiązania.

Wyjaśnienie

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
Weijun Zhou
źródło
0

SILOS , 73 bajty

readIO
k=i
readIO
j=i
readIO
r=j/k
a=k
lbla
printInt a
a*r
b=i-a+1
if b a

Wypróbuj online!

Czytamy trzy liczby. Obliczyć wspólny współczynnik przez drugą liczbę / pierwszą. Następnie przeglądamy serię, aż osiągniemy wartość wyższą niż górna granica.

Rohan Jhunjhunwala
źródło
0

C (gcc), 82 bajty

n;f(a,b,c){float r=0;for(n=0;r<=c;)(r=pow(b,n)/pow(a,n++-1))<=c&&printf("%f ",r);}

Wypróbuj online!

Oblicza i drukuje r_n = b^n/a^(n-1)do r_n > c.

Musi zostać skompilowany -lm!

Vazt
źródło
69 bajtówn;f(a,b,c){for(float r=n=0;r=pow(b/a,n++)*a,r<=c&&printf("%f ",r););}
ceilingcat
0

APL (Dyalog) , 23 bajty ( SBCS )

To bierze argumenty ab po lewej i c po prawej,

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

Wypróbuj online!

Prawdopodobnie jest krótsza droga, ale tak myślałem ÷\ to urocze.

Wyjaśniono:

{...}Anonimowa funkcja ⍺ jest a b, jest c. Powiedzmya b c = 2 6 100

⌽⍺Rewers :6 2

⍵⍴Powtórz czasy:6 2 6 2 6 2 6 2 ...

÷\ Zmniejsz przez podział na prefiksy: 6 (6÷2) (6÷(2÷6)) (6÷(2÷(6÷2))).. = 6 3 18 9 54 ..

⍺,Przygotuj :2 6 6 3 18 9 54 27 162 81 ...

⊣/⍵2⍴ Uzyskaj co drugi element (plus kilka powtórzeń końcowych):

  ⍵2⍴Zrób wiersz, 2macierz kolumny z2 6 6 3 18 9 54 ...

  ⊣/ Zdobądź pierwszą kolumnę

⊆⊢ Podziel tablicę na bloki gdzie

⍵∘≥ jest większy lub równy wszystkim elementom

Weź pierwszy taki blok

H.PWiz
źródło