Sequências Generalizadas FiveThirtyEight

17

Adaptado deste enigma FiveThirtyEight .

fundo

Examine a seguinte sequência infinita:

3 3 3 2 3 3 3 2 3 3 3 2 3 3 2 3 3 3 2 ...

Digamos que a sequência seja indexada em 1. O inúmero th na sequência determina quantos 3s existem antes do ith 2e após os 2s anteriores . Portanto, como a sequência começa com a, 3a sequência deve começar 3 3 3 2e, como existem três 3s no início da sequência, a subsequência 3 3 3 2deve se repetir três vezes. Depois disso, você alcança 3 3 2porque o quarto número na sequência é 2.

O enigma FiveThirtyEight pede o limite das proporções de três a dois (o que não vou estragar aqui), mas você também pode perguntar qual é a proporção cumulativa após o índice i. Por exemplo, a proporção em i=4é 3/1 = 3e i=15é 11/4 = 2.75.

Vamos nos generalizar

Dados os números ne kpodemos criar uma sequência semelhante que comece com ne, assim como a sequência original descrita, o número no índice idetermina quantos ns aparecem antes do ith ke após os ks anteriores .

Exemplos:

n=2, k=5 dá a sequência 2 2 5 2 2 5 2 2 2 2 2 5 2 2 5 ...

n=3, k=03 3 3 0 3 3 3 0 3 3 3 0 0 3 3 3 0 ...

n=1, k=31 3 1 1 1 3 1 3 1 3 1 3 1 1 1 3 1 ...

O desafio

Escreva uma função / programa e com ela faça o seguinte. Tome como entrada:

  • um número inteiro positivo n
  • um número inteiro não negativo k ≠ n
  • um número inteiro positivo i > n

As duas primeiras entradas ne kdeterminam uma sequência como descrito acima e ié um índice. Estou usando a indexação 1 nos exemplos, mas você tem a liberdade de usar a indexação 0 ou 1. Se indexado em 0, a restrição ié i ≥ n.

Com os três números, imprima a proporção de ns para ks na sequência até e incluindo o número no índice i. O formato da saída pode ser um valor decimal com pelo menos 5 dígitos de precisão ou um valor exato como uma proporção como 3524/837ou 3524:837.

Na forma decimal, o último dígito pode ser arredondado da maneira que desejar. Zeros à direita e espaços em branco são permitidos.

Em qualquer uma das formas de cadeia, os dois números precisam ser normalizados para que sejam coprime. Por exemplo, se a proporção era 22/4 11/2e 11:2é aceitável, mas 22/4não é.

Exemplos

n   k   i      output
2   4   15     2.75     or   11/4
6   0   666    5.1101   or   557:109
50  89  64     63       or   63:1
3   2   1000   2.7453   or   733/267
9   12  345    9.4545   or   104/11

Esse é o código de golfe por idioma; portanto, o código mais curto em cada idioma é o vencedor.

dylnan
fonte
Eu recomendo permitir um par de números inteiros como uma proporção, necessitando de respondedores para separar os números /ou :simplesmente adicionar uma complicação desnecessária ao desafio.
Erik the Outgolfer
@EriktheOutgolfer um número decimal também é permitido
dylnan
Um flutuador padrão é exato o suficiente para a saída decimal?
Reintegrar Monica - notmaynard
@iamnotmaynard Eu não sou rigoroso sobre o formato flutuador Então sim, eu acho que sim
dylnan

Respostas:

5

Casca , 16 bytes

¤/#ωȯ↑⁰J¹`C∞²N¹²

Experimente online!

Recebe entradas na mesma ordem que os casos de teste. Produz um número racional. Sinto que há muitos sobrescritos, mas não sei como me livrar deles ...

Explicação

¤/#ωȯ↑⁰J¹`C∞²N¹²  Inputs are n, k, i.
             N    Starting with the natural numbers [1,2,3..
   ωȯ             do this until a fixed point is reached:
                    Argument is a list s.
           ∞²       Take the infinite list [n,n,n..
         `C         and split it to the lengths in s.
       J¹           Join the resulting blocks with k.
     ↑⁰             Take the first i elements.
                  Call the result x.
¤             ¹²  For each of n and k,
  #               count their number of occurrences in x
 /                and perform exact division on the results.
Zgarb
fonte
4

Python 3 , 94 92 89 87 bytes

def g(n,k,i):o,t=[n],0;exec('o+=[n]*o[t]+[k];t+=1;'*i);return-1-i/(o[1:i+1].count(n)-i)

Experimente online!

Créditos

  • Reduzido de 94 para 92 bytes: Colera Su .
  • Reduzido de 92 para 89 bytes: dylnan .
  • Reduzido de 89 para 87 bytes: ovs .
Neil
fonte
Não deveria ser .count(n)?
Colera Su
@ColeraSu Thanks. Não sei como eu perdi isso, consertado.
Neil
92 bytes .
Colera Su
@ColeraSu Obrigado, atualizado. Vou tentar começar a usar exec. Isso é bem legal.
Neil
89 bytes
dylnan
4

Gelatina , 22 bytes

³ẋЀ;€⁴Ẏḣ⁵
ẋ`;ÇÐLLƙ`÷/

Experimente online!

Programa completo. Toma argumentos n, k, i.

Há um erro que faz com que essa necessidade seja desnecessariamente maior em 1 byte.

Erik, o Outgolfer
fonte
Usou alguns de seus truques - legal. Perguntando sobre o que a correção correta para o bug deve ser realmente ...
Jonathan Allan
@ JonathanAllan O que mais me impressionou é essa linha , embora não saiba ao certo por que colocar uma `faz funcionar. Ah, e onde sua resposta difere é que eu esqueci de implementar um golfe que encontrei em outro idioma> _>
Erik the Outgolfer
4

Geléia ,  25  16 bytes

-9 bytes ~ 50% atribuível a resposta de Erik the Outgolfer's Jelly (1. usando a tecla new-ish rapidamente, ƙmesmo com um bug no interpretador que atualmente custa um byte; 2. usando uma repetição mapeada para evitar a contagem e a indexação na sequência atual .) Vá dar-lhe algum crédito!

³ẋЀj⁴ṁ⁵µÐLLƙ`÷/

Um programa completo com três argumentos: n , k, ique imprime o resultado.

Experimente online!

Quão?

³ẋЀj⁴ṁ⁵µÐLLƙ`÷/ - Main link
        µ        - monadic chain separation
         ÐL      - apply the monadic chain to the left repeatedly until no change occurs:
³                -   program's 1st argument, n
  Ѐ             -   map across the current sequence (initially just n)
 ẋ               -     repeat (the first run give triangle of n i.e. [[n],[n,n],...,[n]*n]
     ⁴           -     program's 2nd argument, k
    j            -     join
       ⁵         -     program's 3rd argument, i
      ṁ          -     mould like (repeat the list to fill, or cut it, to length i)
            ƙ    - keyed application, map over groups of identical items:
             `   - (this has an arity of 2, make it monadic by repeating the argument)
           L     -   length -> [numberOfNs, numberOfKs]
               / - reduce with:
              ÷  -   division -> [numberOfNs / numberOfKs]
                 - implicit print (a single item list just prints its content)

exemplo de execução com entradas n=2, k=3, i=30:

Start the "loop until no change", ÐL
Note: Initial left argument, n=2, implicitly range-ified by Ѐ to become [1,2]
1. mapped repeat of n: [[2],[2,2]]
          join with k: [2,3,2,2]
         mould like i: [2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3,2,2,2,3]

2. mapped repeat of n: [[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2]]
          join with k: [2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2]
         mould like i: [2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2]
                          ^different to previous result

3. mapped repeat of n: [[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2]]
          join with k: [2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2]
         mould like i: [2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2]
                                  ^different to previous result

4. mapped repeat of n: [[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2]]
          join with k: [2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2]
         mould like i: [2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2]
                                                      ^different to previous result

5. mapped repeat of n: [[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2],[2,2],[2,2,2],[2,2]]
          join with k: [2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2]
         mould like i: [2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,2,3,2,2,3,2,2,3,2,2,3,2]
                       all the same as the previous result; stop loop and yield this.

length applied to equal elements: [length([2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]), length([3,3,3,3,3,3,3,3,3])]
                                = [21,9]
reduce by division              = [21/9] = [2.3333333333333335]
implicit print                  2.3333333333333335
Jonathan Allan
fonte
3

Mathematica, 85 bytes

(s={#};Do[s=Join[s,#~Table~s[[t]],{#2}],{t,#3}];Last@@Ratios@Tally@s[[#+3;;#3+#+2]])&

Experimente online!

J42161217
fonte
2

APL (Dyalog Unicode) , 126 70 bytes

k n i←⎕
j←⍴v←⍬
:While j<i
v,←k,⍨n⍴⍨{v≢⍬:jvn}j+←1
:End
÷/+/¨n k⍷¨⊂jv

Experimente online!

Bem, obrigado a @ Adám por eliminar 56 bytes desta resposta.

Este é um Tradfn niladic ( trad itional f unctio n ) tendo uma entrada, que é uma lista de três elementos.

⎕PP←5não é adicionado à contagem de bytes, porque só é usado para limitar o P rint P recision para 5 dígitos.

∇fe não são adicionados à contagem de bytes porque não fazem parte do código, apenas delimitadores para o tradfn.

Como funciona:

k n i←⎕                    Take input (←⎕) for k, n and i.
j←⍴v←⍬                     Assign (←) an empty vector (⍬) to v, then assign its shape (⍴, which is 0) to j.
:While j<i                 while j<i, do:
v,←k,⍨n⍴⍨{v≢⍬:jvn}j+←1  this:
                     j+←1  increment j (+←1)
          {v≢⍬:     }      if (:) v does not match (≢) 
               jv         return the jth element of v (v[j])
                  n       else (⋄) return n
      n⍴⍨                  shape (⍴) n as the result (repeats n result times)
   k,⍨                     append (,⍨) k
v,←                        append to (,←) v
:End                       End while loop
÷/+/¨n k⍷¨⊂jv             then:
           jv             shape (⍴) v as j (truncates v to j elements)
                          enclose the resulting vector
         ¨                 for each element
                          find (returns a boolean vector)
     n k                   n and k (⍷ will return a boolean vector for each)
  +/¨                      cumulative sum of each vector (returns the number of times n and k appear in v)
÷/                         divide them and implicitly return the result.
J. Sallé
fonte
1

R , 88 bytes

function(n,k,i){s=rep(n,n);for(j in 1:i){s=c(s,k,rep(n,s[j]))};z=sum(s[1:i]==n);z/(i-z)}

Experimente online!

duckmayr
fonte
você pode se livrar dos aparelhos ao redor do forcorpo do loop, pois há apenas uma declaração.
Giuseppe
0

Rápido , 152 bytes

func f(n:Int,k:Int,i:Int){var a=[0];(1...i).map{a+=(0..<(a.count>$0 ?a[$0]:n)).map{_ in n}+[k]};let m=a[1...i].filter{n==$0}.count;print("\(m)/\(i-m)")}

Será mais curto que o Java?

Explicação

func f(n:Int,k:Int,i:Int){
  var a=[0]                                    // Initialize the array (the zero is to
                                               //  define the type of the array and will be
                                               //  ignored by the code)
  (1...i).map{                                 // Repeat i times (more than enough):
    a+=(0..<(a.count>$0 ?a[$0]:n)).map{_ in n} //  Add the right amount of n:s to the array
      +[k]                                     //  Add k to the array
  }                                            // End repeat
  let m=a[1...i].filter{n==$0}.count           // Count the amount of n:s in the first
                                               //  i elements of the array
  print("\(m)/\(i-m)")                         // Print the result
}
Herman L
fonte
0

Ruby , 77 71 70 bytes

->n,k,i{r=[n]
i.times{|c|r+=[n]*r[c]+[k]}
1r*(j=r[1,i].count n)/(i-j)}

Experimente online!

Retorna um Rational, que opera como um número e restringe a fração reduzida exata.

Restabelecer Monica - notmaynard
fonte
0

Pitão , 24 bytes

AEtcH/e.u<sm+*d]QGNH]Q)G

Suíte de teste.

Ponto fixo de [n]sob determinada função da matriz.

Freira Furada
fonte
0

Zephyr , 284 bytes

input n as Integer
input k as Integer
input m as Integer
set s to Array(m)
for i from 1 to n
set s[i]to n
next
set s[i]to k
set N to n
set K to 1
for a from 2 to m
for b from 1 to s[a]
inc i
if i<=m
set s[i]to n
inc N
end if
next
inc i
if i<=m
set s[i]to k
inc K
end if
next
print N/K

Toma os três números de stdin em três linhas separadas. Produz uma proporção exata como 104/11ou 63.

Ungolfed

input n as Integer
input k as Integer
input maxIndex as Integer

set sequence to Array(maxIndex)
for i from 1 to n
    set sequence[i] to n
next
set sequence[i] to k

set nCount to n
set kCount to 1

for a from 2 to maxIndex
    for b from 1 to sequence[a]
        inc i
        if i <= maxIndex
            set sequence[i] to n
            inc nCount
        end if
    next
    inc i
    if i <= maxIndex
        set sequence[i] to k
        inc kCount
    end if
next

print nCount / kCount
DLosc
fonte