Schliessen Sie geometrische Sequenzen


18

Haskell hat diese nette (-aussehende) Funktion, mit der Sie drei Zahlen eingeben und daraus eine arithmetische Folge ableiten können. Zum Beispiel [1, 3..27]ist äquivalent zu [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27].

Das ist cool und alles andere als arithmetische Sequenzen sind ziemlich einschränkend. Ergänzung pfft . Multiplikation ist da, wo es ist. Wäre es nicht cooler, wenn geometrische Sequenzen [1, 3..27]zurückkehren würden [1, 3, 9, 27]?

Herausforderung

Schreiben Sie ein Programm / eine Funktion , das / die drei positive ganze Zahlen a , b und c annimmt und ausgibt, wobei x die größte ganze Zahl ≤ c ist , die dargestellt werden kann als wobei n eine positive ganze Zahl ist.[a, b, b × (b ÷ a), b × (b ÷ a)2, ..., x]b × (b ÷ a)n

Das heißt, die Ausgabe sollte r sein , so dass:

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

Spezifikationen

  • Standard I / O - Regeln gelten .
  • Standardlücken sind verboten .
  • b wird immer durch teilbar sein ein .
  • a < bc
  • Bei dieser Herausforderung geht es nicht darum, den kürzesten Ansatz in allen Sprachen zu finden, sondern darum, den kürzesten Ansatz in jeder Sprache zu finden .
  • Ihr Code wird in Bytes bewertet , normalerweise in der Codierung UTF-8, sofern nicht anders angegeben.
  • Eingebaute Funktionen (Mathematica hat möglicherweise eins: P), die diese Sequenz berechnen, sind zulässig, es wird jedoch empfohlen, eine Lösung einzuschließen, die nicht auf einer eingebauten basiert.
  • Erklärungen, auch für "praktische" Sprachen, sind erwünscht .

Testfälle

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]

In ein paar besseren Formaten:

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 Nr. (Siehe den ersten Testfall)
user202729

1
Beachten Sie, dass die Formel einfach b ^ n / a ^ n-1 ist . Beginnend bei n = 0
H.PWiz

2
Natürlich hat Mathematica eine eingebaute ...
Neil

Ist es akzeptabel, wenn die Ergebnisse aufgrund von Gleitkommafehlern nicht ganzzahlig sind?
Luis Mendo

@ LuisMendo Ja.
Totalhuman

Antworten:


6

Schale , 8 Bytes

~↑≤Ṡ¡o//

Die Eingabe erfolgt in der Reihenfolge b, c, a . Probieren Sie es online!

Erläuterung

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

Der Kontrollfluss in diesem Programm ist etwas schwer zu verfolgen. Zunächst wird b ganz rechts eingespeist /, wodurch eine Funktion erzeugt wird /b, die durch b dividiert wird . Als nächstes ~teilt den verbleibenden Programm in drei Teile: ~(↑)(≤)(Ṡ¡o//b). Dies speist c zu und a zu Ṡ¡o//bund kombiniert die Ergebnisse mit . Das Ergebnis von ≤cist eine Funktion, die prüft, ob ihr Argument höchstens c ist , und ↑≤cdas längste Präfix von Elementen verwendet, für die dies gilt.

Es bleibt zu zeigen, wie (Ṡ¡o//b)adie gewünschte unendliche Liste ausgewertet wird. Der Teil in Klammern ist unterteilt in Ṡ(¡)(o//b). Dann speist ein an o//b, führt das Ergebnis zu ¡, und gibt dann ein in seine zweite Argument. Der Ausdruck (o//b)agibt eine Funktion an, die eine Zahl annimmt und durch a / b dividiert , und ¡iteriert diese Funktion bei ihrem zweiten Argument, nämlich a .

Hier ist eine Reihe von Transformationen, die die Erklärung veranschaulichen:

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

Alternative Lösung unter Verwendung expliziter Variablen in der Reihenfolge a, b, c :

↑≤⁰¡*/⁵²



3

JavaScript (ES6), 41 37 Byte

4 Bytes dank @Neil gespeichert

Übernimmt die Eingabe als (b,c)(a).

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

Testfälle

Kommentiert

(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
Neuordnung der Argumente gibt mir (b,c)=>g=a=>a>c?[]:[a,...g(b,b*=b/a)].
Neil



2

Python 3, 93 90 74 73 Bytes

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

Probieren Sie es online

Vielen Dank an Rod und user202729, die mir geholfen haben, einige Bytes zu reduzieren!


1
def + return -> lambda. Python-Tipps.
user202729

1
Auch du kannst import*.
user202729

1
Sie können while i<=c:i++(stattdessen Liste Verständnis + Protokoll) verwenden, um eine Menge von Bytes zu speichern
Rod

@ Rod Wie soll ich die while-Schleife ohne das Protokoll verwenden? idk wie lange zu iterieren
Manish Kundu



2

Perl 6 , 26 24 Bytes

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

Probieren Sie es online!

Der Sequenzoperator von Perl 6 ...kann geometrische Reihen nativ ableiten.

Update: ... kann es , ist aber in dieser Situation nicht schlussfolgernd etwas kürzer.


1

05AB1E , 12 Bytes

Eingabe in der Reihenfolge c,b,a

ÝmI¹Ý<m/ʒ¹›_

Probieren Sie es online!

Erläuterung

Ý              # 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 , 12 Bytes

y/ivZlZ}3$:W

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erläuterung

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
Das ist wirklich nett. Ich hatte Probleme mit der Wiederverwendung von aund c(ich habe mit vielen fehlgeschlagenen Versuchen angefangen y/i), aber mit dieser Methode halten Sie alles sauber zusammen.
Sanchises

1
Dieser Ansatz war auch in Octave 3 Bytes kürzer.
Sanchises

0

Perl, 38 Bytes

Include +3for -n(das use 5.10.0Freischalten der Perl 5.10 Features ist kostenlos)

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

Führen Sie dann Folgendes aus:

geosequence.pl <<< "1 3 26"


0

Japt , 14 Bytes

ÆWpX zVpXÉÃf§U

Versuch es


Erläuterung

                    :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 Bytes

Nimmt Eingaben vom Benutzer auf und gibt sie aus Ans. Ich habe nach n in c = b n / a n-1 aufgelöst und n = 1 + ln (c / b) / ln (b / a) erhalten. Das ist das Gleiche wie n = 1 + log b / a (c / b). Zum Golfen beginne ich meine Sequenz bei -1 und beende sie bei n-1 anstatt bei 0 bis n.

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

0

APL (Dyalog Unicode) , 38 Byte

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

Probieren Sie es online!

Präfix Dfn. Nimmt die Eingabe in die richtige Reihenfolge a b cund verwendet ⎕IO←0( I ndex O rigin)

Vielen Dank an @ErikTheOutgolfer für das Rasieren von 6 Bytes, bevor ich es überhaupt gepostet habe.

Wie?

{(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 Bytes CP437

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

16 Bytes beim Auspacken,

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

Online ausführen und debuggen!

Nimmt Eingaben in Form von [b, a, c].

Ich bin mir ziemlich sicher, dass @recursive bessere Lösungen bietet.

Erläuterung

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

SILOS , 73 Bytes

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

Probieren Sie es online!

Wir lesen die drei Zahlen. Berechnen Sie das gemeinsame Verhältnis aus der zweiten und der ersten Zahl. Dann durchlaufen wir die Reihe, bis wir größer als die Obergrenze sind.


0

C (gcc), 82 Bytes

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);}

Probieren Sie es online!

Berechnet und druckt r_n = b^n/a^(n-1)bis r_n > c.

Muss mit kompiliert werden -lm!


69 Bytesn;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 Byte ( SBCS )

Dies nimmt Argumente ab links und c rechts,

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

Probieren Sie es online!

Es gibt wahrscheinlich einen kürzeren Weg, aber ich fand das ÷\süß.

Erklärt:

{...}Anonome Funktion ⍺ ist a b, ist c. Sagen wira b c = 2 6 100

⌽⍺Reverse :6 2

⍵⍴Wiederholen Sie die Zeiten:6 2 6 2 6 2 6 2 ...

÷\ Reduzieren Sie durch Unterteilung nach Präfixen: 6 (6÷2) (6÷(2÷6)) (6÷(2÷(6÷2))).. = 6 3 18 9 54 ..

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

⊣/⍵2⍴ Holen Sie sich jedes andere Element (plus einige nachfolgende Wiederholungen):

  ⍵2⍴Erstellen Sie eine Zeilen- / 2Spaltenmatrix aus2 6 6 3 18 9 54 ...

  ⊣/ Holen Sie sich die erste Spalte

⊆⊢ Teilen Sie das Array in Blöcke wo

⍵∘≥ ist größer oder gleich allen Elementen

Nehmen Sie den ersten solchen Block

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.