Déduire des séquences géométriques

18

Haskell a cette fonctionnalité soignée où vous pouvez lui donner trois nombres et en déduire une séquence arithmétique. Par exemple, [1, 3..27]est équivalent à [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27].

C'est cool et tout sauf les séquences arithmétiques sont assez limitantes. Addition, pfft . La multiplication est là où elle en est. Ne serait-il pas plus cool s'il faisait des séquences géométriques comme le [1, 3..27]retour [1, 3, 9, 27]?

Défi

Écrivez un programme / une fonction qui prend trois entiers positifs a , b et c et produit où x est le plus grand entier ≤ c qui peut être représenté comme où n est un entier positif.[a, b, b × (b ÷ a), b × (b ÷ a)2, ..., x]b × (b ÷ a)n

Autrement dit, la sortie doit être r , telle que:

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

Caractéristiques

  • Les règles d'E / S standard s'appliquent .
  • Les failles standard sont interdites .
  • b sera toujours divisible par a .
  • a < bc
  • Ce défi ne consiste pas à trouver l'approche la plus courte dans toutes les langues, mais plutôt à trouver l' approche la plus courte dans chaque langue .
  • Votre code sera noté en octets , généralement dans le codage UTF-8, sauf indication contraire.
  • Les fonctions intégrées (Mathematica peut en avoir une: P) qui calculent cette séquence sont autorisées, mais il est recommandé d' inclure une solution qui ne repose pas sur une fonction intégrée.
  • Des explications, même pour les langues "pratiques", sont encouragées .

Cas de test

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]

Dans quelques meilleurs formats:

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
totalement humain
la source
@ Adám No. (voir le premier cas de test)
user202729
1
Notez que la formule est simplement b ^ n / a ^ n-1 . À partir de n = 0
H.PWiz
2
Bien sûr, Mathematica a une fonction intégrée ...
Neil
est-il acceptable si les résultats ne sont pas exactement des nombres entiers en raison d'erreurs en virgule flottante?
Luis Mendo
@LuisMendo Oui.
totalement humain le

Réponses:

6

Husk , 8 octets

~↑≤Ṡ¡o//

L'entrée est dans l'ordre b, c, a . Essayez-le en ligne!

Explication

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

Le flux de contrôle dans ce programme est un peu difficile à suivre. Tout d'abord, b est alimenté à l'extrême droite /, produisant une fonction /bqui se divise par b . Ensuite, ~divise le reste du programme en trois parties: ~(↑)(≤)(Ṡ¡o//b). Cela alimente c to et a to Ṡ¡o//bet combine les résultats avec . Le résultat de ≤cest une fonction qui vérifie si son argument est au plus c , et ↑≤cprend le préfixe le plus long des éléments pour lesquels cela est valable.

Il reste à montrer comment (Ṡ¡o//b)as'évalue à la liste infinie souhaitée. La partie entre parenthèses est divisée en Ṡ(¡)(o//b). Transmet ensuite un à o//b, transmet le résultat à ¡, puis donne un à son deuxième argument. L'expression (o//b)adonne une fonction qui prend un nombre et le divise par a / b , et ¡itère cette fonction sur son deuxième argument, qui est a .

Voici une série de transformations qui visualisent l'explication:

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

Solution alternative utilisant des variables explicites dans l'ordre a, b, c :

↑≤⁰¡*/⁵²
Zgarb
la source
4

Proton , 35 octets

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

Essayez-le en ligne!

M. Xcoder
la source
1
les gens se souviennent réellement de cette langue? : D
HyperNeutrino
1
Je @HyperNeutrino activement utiliser ce :)
M. Xcoder
3
Je sais que je ne vais probablement pas recevoir de réponse, mais pourquoi le downvote?
M. Xcoder
3

JavaScript (ES6), 41 37 octets

4 octets enregistrés grâce à @Neil

Prend l'entrée comme (b,c)(a).

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

Cas de test

Commenté

(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
la source
1
Réorganiser les arguments me donne (b,c)=>g=a=>a>c?[]:[a,...g(b,b*=b/a)].
Neil
2

Python 3, 93 90 74 73 octets

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

Essayez-le en ligne

Merci à Rod et à user202729 de m'avoir aidé à réduire pas mal d'octets!

Manish Kundu
la source
1
def + return -> lambda. Conseils Python.
user202729
1
Vous aussi import*.
user202729
1
vous pouvez utiliser while i<=c:i++(à la place list comprehension + log) pour économiser beaucoup d'octets
Rod
@Rod Comment dois-je utiliser la boucle while sans le journal? idk combien de temps pour itérer
Manish Kundu
1
-1 octet .
user202729
2

Octave , 38 35 octets

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

Essayez-le en ligne!

Il s'avère que l'approche MATL de @ LuisMendo enregistre également 3 octets dans Octave, bien qu'elle se répète logtrois fois.

Sanchises
la source
2

Perl 6 , 26 24 octets

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

Essayez-le en ligne!

Opérateur de séquence de Perl 6 ... peut déduire nativement des séries géométriques.

Mise à jour: ... C'est possible , mais dans cette situation, ne pas en déduire, c'est un peu plus court.

Sean
la source
1

05AB1E , 12 octets

Saisie dans l'ordre c,b,a

ÝmI¹Ý<m/ʒ¹›_

Essayez-le en ligne!

Explication

Ý              # 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
la source
1

MATL , 17 octets

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

Essayez-le en ligne!

Juste pour faire rouler la balle en MATL. Je ne peux pas imaginer qu'il n'y ait pas de manière moins verbeuse de résoudre cela.

Sanchises
la source
1
... Pas de triple négation s'il vous plaît.
user202729
2
@ user202729 Je ne vois pas comment vous n'auriez pas pu obtenir que ce ne soit pas un accident. :)
Sanchises
Ne voulez-vous pas dire "Je ne vois pas comment vous n'auriez pas pu obtenir que cela n'ait pas été fait involontairement": P
HyperNeutrino
@HyperNeutrino No.
Sanchises
Gardez le ballon
Luis Mendo
1

Haskell, 35 octets

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

Essayez-le en ligne!

nimi
la source
1
34 octets . (plus "dans l'esprit du défi", terrible erreur de virgule flottante)
user202729
@ user202729: s'il vous plaît poster comme une réponse séparée (mais enregistrer un octet: exp<$>[...])
Nimi
1

MATL , 12 octets

y/ivZlZ}3$:W

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

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
la source
1
C'est vraiment sympa. J'avais du mal à réutiliser aet c(j'ai de nombreuses tentatives infructueuses en commençant y/i), mais en utilisant cette méthode, vous gardez soigneusement tout ensemble.
Sanchises
1
cette approche était en fait 3 octets plus courte dans Octave aussi.
Sanchises
0

Perl, 38 octets

Inclure +3pour -n(le use 5.10.0déverrouillage des fonctionnalités de Perl 5.10 est gratuit)

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

Exécutez ensuite en tant que:

geosequence.pl <<< "1 3 26"
Ton Hospel
la source
0

Japt , 14 octets

ÆWpX zVpXÉÃf§U

Essayez-le


Explication

                    :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
Hirsute
la source
0

TI-BASIC, 31 octets

Prend l'entrée de l'utilisateur et les sorties Ans. J'ai résolu pour n dans c = b n / a n-1 , obtenant n = 1 + ln (c / b) / ln (b / a). C'est la même chose que n = 1 + log b / a (c / b). Aux fins du golf, je commence ma séquence à -1 et la termine à n-1 plutôt que de 0 à n.

Prompt A,B,C
seq(B(B/A)^N,N,-1,logBASE(C/B,B/A
kamoroso94
la source
0

APL (Dyalog Unicode) , 38 octets

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

Essayez-le en ligne!

Préfixe Dfn. Prend les données en ordre a b cet utilise ⎕IO←0( I ndex O rigin)

Merci à @ErikTheOutgolfer d'avoir rasé 6 octets avant même de l'avoir posté.

Comment?

{(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é
la source
0

Stax , 14 octets CP437

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

16 octets lors du déballage,

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

Exécutez et déboguez en ligne!

Prend entrée sous la forme de [b, a, c].

Je suis sûr que @recursive a de meilleures solutions.

Explication

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
la source
0

SILOS , 73 octets

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

Essayez-le en ligne!

Nous avons lu les trois chiffres. Calculez le rapport commun par le deuxième nombre / premier. Ensuite, nous parcourons la série jusqu'à ce que nous soyons supérieurs à la limite supérieure.

Rohan Jhunjhunwala
la source
0

C (gcc), 82 octets

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

Essayez-le en ligne!

Calcule et imprime r_n = b^n/a^(n-1)jusqu'à r_n > c.

Doit être compilé avec -lm!

vazt
la source
69 octetsn;f(a,b,c){for(float r=n=0;r=pow(b/a,n++)*a,r<=c&&printf("%f ",r););}
Plafond
0

APL (Dyalog) , 23 octets ( SBCS )

Cela prend les arguments ab à gauche et c à droite,

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

Essayez-le en ligne!

Il y a probablement un chemin plus court, mais je pensais que ÷\ c'était mignon.

Expliqué:

{...}La fonction autonome ⍺ est a b, est c. Disonsa b c = 2 6 100

⌽⍺Inverse :6 2

⍵⍴Répétez fois:6 2 6 2 6 2 6 2 ...

÷\ Réduire par division sur les préfixes: 6 (6÷2) (6÷(2÷6)) (6÷(2÷(6÷2))).. = 6 3 18 9 54 ..

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

⊣/⍵2⍴ Obtenez tous les autres éléments (plus quelques répétitions de fin):

  ⍵2⍴Créer une matrice de lignes et de 2colonnes à partir de2 6 6 3 18 9 54 ...

  ⊣/ Obtenez la première colonne

⊆⊢ Divisez le tableau en blocs où

⍵∘≥ est supérieur ou égal à tous les éléments

Prenez le premier bloc

H.PWiz
la source