Inferir secuencias geométricas

18

Haskell tiene esta característica ordenada (de aspecto) donde puede darle tres números y puede inferir una secuencia aritmética a partir de ellos. Por ejemplo, [1, 3..27]es equivalente a [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27].

Eso es genial y todas las secuencias aritméticas son limitadas. Además, pfft . La multiplicación está donde está. ¿No sería más genial si hiciera secuencias geométricas como [1, 3..27]regresar [1, 3, 9, 27]?

Desafío

Escriba un programa / función que tome tres enteros positivos a , byc y produzca salidas donde x es el mayor entero ≤ c que se puede representar como donde n es un entero positivo.[a, b, b × (b ÷ a), b × (b ÷ a)2, ..., x]b × (b ÷ a)n

Es decir, la salida debe ser r , de modo 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

Especificaciones

  • Normas estándar de E / S se aplican .
  • Las lagunas estándar están prohibidas .
  • b siempre será divisible por a .
  • a < bc
  • Este desafío no se trata de encontrar el enfoque más corto en todos los idiomas, sino de encontrar el enfoque más corto en cada idioma .
  • Su código se puntuará en bytes , generalmente en la codificación UTF-8, a menos que se especifique lo contrario.
  • Las funciones integradas (Mathematica podría tener una: P) que calculan esta secuencia están permitidas, pero se recomienda incluir una solución que no se base en una función integrada.
  • Se alientan las explicaciones, incluso para los idiomas "prácticos" .

Casos de prueba

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]

En algunos formatos mejores:

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
totalmente humano
fuente
@ Adám No. (ver el primer caso de prueba)
usuario202729
1
Tenga en cuenta que la fórmula es simplemente b ^ n / a ^ n-1 . A partir de n = 0
H.PWiz
2
Por supuesto, Mathematica tiene un ...
Neil
¿Es aceptable si los resultados no son enteros debido a errores de coma flotante?
Luis Mendo
@LuisMendo Sí.
Totalmente humano

Respuestas:

6

Casco , 8 bytes

~↑≤Ṡ¡o//

La entrada está en el orden b, c, a . Pruébalo en línea!

Explicación

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

El flujo de control en este programa es un poco difícil de seguir. Primero, b se alimenta a la derecha /, produciendo una función /bque se divide por b . A continuación, ~se divide el programa restante en tres partes: ~(↑)(≤)(Ṡ¡o//b). Esto alimenta c to y a to Ṡ¡o//b, y combina los resultados con . El resultado de ≤ces una función que comprueba si su argumento es como máximo c , y ↑≤ctoma el prefijo más largo de elementos para los que esto es válido.

Queda por mostrar cómo se (Ṡ¡o//b)aevalúa la lista infinita deseada. La parte entre paréntesis se divide en Ṡ(¡)(o//b). Luego alimenta un to o//b, alimenta el resultado ¡ay luego da un a su segundo argumento. La expresión (o//b)ada una función que toma un número y lo divide por a / b , e ¡itera esta función en su segundo argumento, que es a .

Aquí hay una serie de transformaciones que visualizan la explicación:

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

Solución alternativa utilizando variables explícitas en orden a, b, c :

↑≤⁰¡*/⁵²
Zgarb
fuente
4

Protón , 35 bytes

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

Pruébalo en línea!

Sr. Xcoder
fuente
1
la gente realmente recuerda este idioma? : D
HyperNeutrino
1
Me @HyperNeutrino activamente uso que :)
Sr. Xcoder
3
Sé que probablemente no voy a recibir ninguna respuesta, pero ¿por qué el voto negativo?
Sr. Xcoder
3

JavaScript (ES6), 41 37 bytes

Guardado 4 bytes gracias a @Neil

Toma entrada como (b,c)(a).

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

Casos de prueba

Comentado

(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
fuente
1
Reorganizar los argumentos me da (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])

Pruébalo en línea

¡Gracias a Rod y user202729 por ayudarme a reducir algunos bytes!

Manish Kundu
fuente
1
def + return -> lambda. Consejos de Python.
user202729
1
También tu puedes import*.
user202729
1
puedes usar while i<=c:i++(en lugar de lista de comprensión + registro) para guardar muchos bytes
Rod
@ Rod ¿Cómo debo usar el bucle while sin el registro? idk cuánto tiempo iterar
Manish Kundu
1
-1 byte .
user202729
2

Octava , 38 35 bytes

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

Pruébalo en línea!

Resulta que el enfoque MATL de @ LuisMendo también ahorra 3 bytes en Octave, a pesar de repetir logtres veces.

Sanchises
fuente
2

Perl 6 , 26 24 bytes

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

Pruébalo en línea!

El operador de secuencia de Perl 6 ...puede inferir series geométricas de forma nativa.

Actualización: ... Puede , pero en esta situación no inferirlo es un poco más corto.

Sean
fuente
1

05AB1E , 12 bytes

Entrada en el orden c,b,a

ÝmI¹Ý<m/ʒ¹›_

Pruébalo en línea!

Explicación

Ý              # 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
fuente
1

MATL , 17 bytes

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

Pruébalo en línea!

Solo para que la pelota ruede en MATL. No puedo imaginar que no haya una forma menos detallada de resolver esto.

Sanchises
fuente
1
... No hay triple negación por favor.
user202729
2
@ user202729 No veo cómo no podrías haber conseguido que eso no fuera un accidente. :)
Sanchises
No quiere decir "No veo cómo no podría haber conseguido que eso no se haya hecho sin querer": P
HyperNeutrino
@HyperNeutrino No.
Sanchises
1

Haskell, 35 bytes

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

Pruébalo en línea!

nimi
fuente
1
34 bytes . (más "en el espíritu del desafío", terrible error de coma flotante)
usuario202729
@ user202729: por favor, publicarlo como una respuesta por separado (pero guardar un byte: exp<$>[...])
Nombre del modelo
1

MATL , 12 bytes

y/ivZlZ}3$:W

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

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
fuente
1
Esto es realmente lindo Estaba luchando con la reutilización ay c(tengo muchos intentos fallidos desde el principio y/i), pero al usar este método, mantienes todo junto.
Sanchises
1
este enfoque fue en realidad 3 bytes más corto en Octave también.
Sanchises
0

Perl, 38 bytes

Incluir +3para -n(el use 5.10.0para desbloquear las características de Perl 5.10 es gratis)

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

Luego corre como:

geosequence.pl <<< "1 3 26"
Ton Hospel
fuente
0

Japt , 14 bytes

ÆWpX zVpXÉÃf§U

Intentalo


Explicación

                    :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
Lanudo
fuente
0

TI-BASIC, 31 bytes

Toma la entrada del usuario y las salidas Ans. Resolví n en c = b n / a n-1 , obteniendo n = 1 + ln (c / b) / ln (b / a). Eso es lo mismo que n = 1 + log b / a (c / b). A los fines del golf, comienzo mi secuencia en -1 y la finalizo en n-1 en lugar de 0 en n.

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

APL (Dyalog Unicode) , 38 bytes

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

Pruébalo en línea!

Prefijo Dfn. Toma de entrada con el fin a b c, y los usos ⎕IO←0( I ndex O rigin)

Gracias a @ErikTheOutgolfer por eliminar 6 bytes de esto incluso antes de publicarlo.

¿Cómo?

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

Stax , 14 bytes CP437

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

16 bytes cuando está desempaquetado,

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

¡Ejecute y depure en línea!

Toma entrada en forma de [b, a, c].

Estoy bastante seguro de que @recursive tiene mejores soluciones.

Explicación

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
fuente
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

Pruébalo en línea!

Leemos los tres números. Calcule la razón común por el segundo número / primero. Luego corremos a través de la serie hasta que somos mayores que el límite superior.

Rohan Jhunjhunwala
fuente
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);}

Pruébalo en línea!

Calcula e imprime r_n = b^n/a^(n-1)hasta r_n > c.

Debe ser compilado con -lm!

vazt
fuente
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 bytes ( SBCS )

Esto toma argumentos ab a la izquierda yc a la derecha,

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

Pruébalo en línea!

Probablemente hay un camino más corto, pero pensé que ÷\ era lindo.

Explicado:

{...}La función anónima ⍺ es a b, es c. Digamosa b c = 2 6 100

⌽⍺Reverso :6 2

⍵⍴Repetir tiempos:6 2 6 2 6 2 6 2 ...

÷\ Reducir por división en prefijos: 6 (6÷2) (6÷(2÷6)) (6÷(2÷(6÷2))).. = 6 3 18 9 54 ..

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

⊣/⍵2⍴ Obtenga todos los demás elementos (más algunas repeticiones finales):

  ⍵2⍴Haga una fila, 2matriz de columna de2 6 6 3 18 9 54 ...

  ⊣/ Obtén la primera columna

⊆⊢ Dividir la matriz en bloques donde

⍵∘≥ es mayor o igual que todos los elementos

Toma el primer bloque

H.PWiz
fuente