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

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

↑≤⁰¡*/⁵²



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

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!


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


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.


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.


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

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.


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


1

Haskell, 35 octets

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

Essayez-le en ligne!


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

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"


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


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

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 

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

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.


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!


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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.