Calcola A (N) / B (N) con cifre C (N)


15

Consideriamo tre sequenze di numeri, A, Be C:

  • A: Una sequenza basata sulle relazioni di ricorrenza f(n) = f(n-1)+f(n-2), a partire da f(1) = 3, f(2) = 4. Quindi, la sequenza inizia in questo modo:3 4 7 11 18 29 47 76 ...
  • B: I numeri compositi , ovvero tutti i numeri interi che non sono numeri primi (o 1):4 6 8 9 10 12 14 15 16 ...
  • C: Le cifre di Pi: 3 1 4 1 5 9 2 6 5 ...

Dato un numero intero positivo N < 50, come argomento della funzione o STDIN, restituisce il valore decimale della frazione A(N)/B(N)con C(N)cifre dopo il punto decimale. Si applicano le normali regole di arrotondamento (arrotondare per eccesso se la N + 1a cifra è 5 o superiore). Se l'ennesima cifra di piè zero, dovrebbe essere stampato un numero intero. notazione scientifica / Modulo standard accettato per numeri superiori a 1000.

Questo è il golf del codice, quindi vince la risposta più breve in byte.

Qualche esempio:

N = 1: 0.750
N = 2: 0.7
N = 3: 0.8750
N = 4: 1.2
N = 6: 2.416666667
N = 10: 11.056
N = 20: 764.8750

Naturalmente, si applicano le regole standard per il golf del codice.

La funzione deve terminare in meno di due minuti su qualsiasi laptop moderno.


Quando dici C(n)cifre, dobbiamo includere 0 finali?
Maltysen,

A quale input si applica il limite di tempo?
Dennis,

@Dennis, vuoi dire con quale N? In tal caso, fino a N = 49. O qualcos'altro?
Stewie Griffin,

JavaScript ha una precisione in virgola mobile limitata di 16. Passando a ciò, inizierai a ottenere risultati imprecisi. Va bene?
Downgoat,

1
@vihan La mia soluzione (ATM non pubblicato) memorizza le prime 49 cifre di pi in una stringa. E non hai bisogno di più di 9 cifre di precisione nel risultato, se sei preoccupato per questo.
ETHproductions

Risposte:


9

Pyth, 60 57 58 byte

.[K`.Rchu,eGsGQjT7e.ftPZQ)Je/u+/*GHhyHy^TQr^T3ZZT\0+xK\.hJ

Collaudare l'imbragatura

È abbastanza semplice: calcolare pi, la serie di fibonacci e i composti, arrotondare a C (n) cifre, pad a C (n) cifre più la posizione delle cifre dei punti decimali, fatto.

Un): hu,eGsGQjT7

B (n): e.ftPZQ)

C (n): e/u+/*GHhyHy^TQr99ZZT

60 -> 57: risolto il caso speciale n = 1 nel calcolo pi.

57 -> 58: non utilizzava una precisione abbastanza elevata per pi per l'intero intervallo di input - aumentava 99 iterazioni a 1000 iterazioni.

Nota sull'arrotondamento: utilizza il sistema di arrotondamento "più vicino" di Python, piuttosto che il sistema "verso l'infinito" specificato dall'OP. Tuttavia, la differenza è importante solo se le cifre immediatamente successive al punto di arrotondamento sono 5000..., ad esempio, 1,25 arrotondate a 1 cifra. Ho controllato l'intervallo di input e questo non accade mai, quindi viene sempre restituito il risultato corretto.


2

PowerShell, 420 byte (ayyyyyyyy) 378 byte

param($n);[int[]]$p="03141592653589793238462643383279502884197169399375"-Split'';$a=@(0,3,4);for($i=3;$i-lt50;$i++){$a+=$a[$i-1]+$a[$i-2]};$c=[char[]]"00001010111010111010111011111010111110111010111011111011111010111110111";$b=@(0);for($i=4;$i-le70;$i++){if($c[$i]-eq'1'){$b+=$i}};[double]$r=$a[$n]/$b[$n];$q=$p[$n+1];$s="";(0..($q-1))|%{$s+="0"};([math]::Round($r,$q,[MidpointRounding]::AwayFromZero)).ToString("0.$s")

Grazie a isaacg per il salvataggio di 41 byte, per il calcolo dell'arrotondamento della domanda. Significa che non ho dovuto includere l'orrendo [MidpointRounding]::AwayFromZeroe non avevo bisogno di lanciare esplicitamente come [double].

Questo è stato molto divertente!

Allargato:

# Take input N
param($n)

# First digits of pi, stored as integer array
[int[]]$p="03141592653589793238462643383279502884197169399375"-Split''

# Fibonacci sequence A(N)
$a=@(0,3,4)
for($i=3;$i-lt50;$i++){
  $a+=$a[$i-1]+$a[$i-2]
}

# Zero-indexed bitmask for if the n-th integer is composite (1) or not (0)
$c=[char[]]"00001010111010111010111011111010111110111010111011111011111010111110111"

# Populate B(N) as an array using the $c mask
$b=@(0)
for($i=4;$i-le70;$i++){
  if($c[$i]-eq'1'){
    $b+=$i
  }
}

# Calculation Time!
$r=(a($n))/$b[$n]

# A small golf, as $p[$n+1] gets used a couple times
$q=$p[$n+1]

# Need to generate a string of zeroes for padding
$s=""
(0..($q-1))|%{$s+="0"}

# Round the number, then send it to a string so we get the necessary number of zeroes
([math]::Round($r,$q)).ToString("0.$s")

La ricorsione in PowerShell è ... lenta, dovremmo dire, quindi dobbiamo costruire A(N)l'altra direzione e memorizzarla in un array, quindi indicizzarla.


VECCHIO

Inoltre, vacca sacra, i requisiti di produzione hanno ucciso questo. Per impostazione predefinita, PowerShell esegue l'arrotondamento all'arrotondamento del banchiere a / k / a più vicino, il che richiede l'utilizzo dello straordinario dettaglio [MidpointRounding]::AwayFromZeroper cambiare gli stili di arrotondamento . Inoltre, dobbiamo quindi eliminare gli zero finali, se presenti. Questi due requisiti combinati per trasformare l'ultima coppia di righe da 20 byte [math]::Round($r,$q) a 102 byte (da $s=""a +$s)) ... wow.


Ottima descrizione / commento! 32 caratteri per [MidpointRounding]::AwayFromZerosolo è quasi troppo bello / cattivo per essere vero ... =)
Stewie Griffin

1
Vedi la mia nota sull'arrotondamento nella mia risposta. L'arrotondamento predefinito di PowerShell dovrebbe andare bene.
Isaacg,

1

Javascript (ES6), 302 byte

Una sola parola: incompiuta.

x=>{a=[0,3,4],b=[0],c='03141592653589793238462643383279502884197169399375';for(i=1;i<x;a[i+2]=a[i]+a[++i]);for(i=1,p=[];++i<70;v=p.every(x=>i%x),(v?p:b).push(i));r=''+Math.round(a[x]/b[x]*(l=Math.pow(10,c[x])))/l;if(x==33)return r;r.indexOf`.`<0&&(r+='.');while(!r[r.indexOf`.`+ +c[x]])r+='0';return r}

Le prime 49 cifre di pi sono memorizzate in una stringa e le altre due sequenze sono generate automaticamente. Questo è stato golfato a metà strada; Sono (quasi) sicuro di poterne estrarre altri 50 byte.

Funziona per tutti i casi di test e dovrebbe funzionare per il resto. Si blocca su qualcosa di più di 49 o inferiore a 0 (non dovrebbe mai incontrare queste situazioni comunque). Mi piace soprattutto il risultato per 0:

NaN.

Perché questo è incompiuto?
Decadimento beta

@BetaDecay Volevo dire che non ho ancora finito di giocare a golf. Lo farò non appena avrò il tempo.
ETHproductions

1

Ottava, 276 236 byte

Prima di tutto ho pensato che sarebbe stato bello fare uso di una precisione illimitata in questi strumenti matematici (e aggiornare alcune conoscenze a riguardo), quindi ho iniziato a scrivere alcuni algoritmi e alla fine ho scoperto che il pivalore non è così preciso che io dovrà usare nuovamente l'array. Quindi di nuovo, nessun grande successo:

function c(A)p="3141592653589793238462643383279502884197169399375";f=ones (1,50);f(1)=3;f(2)=4;for i=3:53f(i)=f(i-1)+f(i-2);end
i=0;x=1;while i<A
x++;for j=2:x/2
if mod(x,j)==0 i++;break;end end end
printf(["%." p(A) "f\n"],f(A)/x);end

Ancora abbastanza leggibile, no?

uso

funzione copia-incolla in ottava, chiamata funzione ccon argomento del valore richiesto:

>>> c(1)
0.750
>>> c(49)
407880480.04348

ottimizzazioni:

  • Substitute endif, endfore simili con endcui funziona allo stesso modo
  • variabile decrescente idi un salvataggio di un byte
  • rimuovere num2str(str2num(p(A)))sciocchezze :)

Mi piace che tu abbia pubblicato una soluzione Octave (io stesso sono un ragazzo MATLAB!). Nota che questo codice è solo Octave, non MATLAB. MATLAB utilizza end, non endif, così tanti byte salvati. Se anche vi capita di avere il Symbolic Toolbox per MATLAB, è possibile utilizzare vpaper ottenere punti decimali sufficiente per pi: vpa(sym(pi),49). Non ce l'ho su questo laptop, quindi non sono sicuro che symsia necessario lì, ma dovrei comunque risparmiare abbastanza byte =) E la lettura non è necessariamente una buona cosa nel codice golf =)
Stewie Griffin

Anche x ++ non è un comando MATLAB. Non sapevo che ci fossero differenze così grandi tra i due ... IMO, non dovrebbe esserlo. Penso che tutto il codice scritto in Octave dovrebbe essere portabile su MATLAB (ma non necessariamente viceversa poiché MATLAB ha più opzioni).
Stewie Griffin,

Approvata la tua modifica. Non ho matlab da queste parti, quindi non sono stato in grado di provarlo. Stavo cercando una soluzione per ottenere più decimali in ottava, ma purtroppo nulla era più breve del solo array. Ma ommiting whileda endwhilee simili funziona bene, quindi sto aggiornando la risposta con pochi caratteri in meno :)
Jakuje,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.