Doralità di un numero intero


21

Un numero intero positivo n può essere rappresentato come un rettangolo con lati interi a , b tale che n = a * b . Cioè, l'area rappresenta il numero. In generale, un e b non sono unici per un dato n .

Come è noto, un rettangolo è particolarmente piacevole per l'occhio (o è il cervello?) Quando i suoi lati sono nel rapporto aureo , φ = (sqrt (5) +1) / 2 ≈ 1.6180339887 ...

Combinando questi due fatti, lo scopo di questa sfida è di scomporre un numero intero n nel prodotto di due numeri interi a , b il cui rapporto è il più vicino possibile a φ (con la consueta metrica su ℝ). Il fatto che φ sia irrazionale implica che esiste una coppia unica di soluzione ( a , b ).

La sfida

Dato un numero intero positivo n , produce numeri interi positivi a , b tali che a * b = n e la differenza assoluta tra a / b e φ è ridotta al minimo.

Ad esempio, considera n = 12. Le coppie ( a , b ) che soddisfano a * b = n sono: (1, 12), (2,6), (3,4), (4,3), ( 6,2), (12,1). La coppia il cui rapporto è più vicino a φ è (4,3), che dà 4/3 = 1.333.

Regole

Funzioni o programmi sono accettabili.

Il numeratore ( a ) dovrebbe apparire per primo nell'output e il denominatore ( b ) secondo . Oltre a ciò, i formati di input e output sono flessibili come al solito. Ad esempio, i due numeri possono essere emessi come stringhe con qualsiasi separatore ragionevole o come un array.

Il codice dovrebbe funzionare in teoria per numeri arbitrariamente grandi. In pratica, potrebbe essere limitato da restrizioni relative alla memoria o al tipo di dati.

È sufficiente considerare una versione approssimativa di φ , purché sia ​​accurata fino al terzo decimale o migliore. Cioè, la differenza assoluta tra il vero φ e il valore approssimativo non dovrebbe superare 0.0005. Ad esempio, 1.618 è accettabile.

Quando si utilizza una versione approssimativa e razionale di φ c'è una piccola possibilità che la soluzione non sia unica. In tal caso è possibile generare qualsiasi coppia a , b che soddisfi il criterio di minimizzazione.

Il codice più corto vince.

Casi test

1        ->  1    1
2        ->  2    1 
4        ->  2    2
12       ->  4    3
42       ->  7    6
576      ->  32   18
1234     ->  2    617
10000    ->  125  80
199999   ->  1    199999
9699690  ->  3990 2431

Sicuramente la maggior parte delle risposte utilizzerà una sorta di approssimazione razionale a φ, a meno che non si accetti, ad esempio, che la risposta con il risultato di a / bb / a sia il più vicino possibile a 1.
Neil,

@Neil Non sono sicuro di aver capito il tuo commento. La tua idea di minimizzare |a/b-b/a-1|è promettente, anche se una prova sarebbe in ordine
Luis Mendo l'

Non sono sicuro di poter inserire un'intera prova in un commento, ma il contorno è il seguente: l'intero rettangolo rappresenta a/b. La rimozione del quadrato dell'unità lascia il piccolo rettangolo a destra che rappresenta b/a. Un rettangolo dorato quindi raggiunge una differenza di 1.
Neil,

Se aeb non sono numeri adiacenti nella sequenza di Fibbonacci, c'è qualche punto che li include nel test?
Fragola,

Detto questo, 1618 x 1000 sembra un buon candidato (o, per riferimento, 809 x 500)
Strawberry,

Risposte:


6

Gelatina, 16 15 14 byte

Salvato 1 byte grazie a @miles.

÷/ạØp
ÆDżṚ$ÇÞḢ

Provalo online!

Spiegazione

÷/ạØp         Helper link, calculates abs(a/b - phi). Argument: [a, b]
÷/            Reduce by division to calculate a/b.
  ạØp         Calculate abs(a/b - phi).

ÆDżṚ$ÇÞḢ      Main link. Argument: n
ÆD            Get divisors of n.
  żṚ$         Pair the items of the list with those of its reverse. The reversed
              divisors of a number is the same list as the number divided by each
              of the divisors.
     ÇÞ       Sort by the output of the helper link of each pair.
       Ḣ      Get the first element [a, b] and implicitly print.

È possibile salvare un byte intercalando il rovescio dell'elenco dei divisori con se stesso. Usando ÷/ạØp¶ÆDżṚ$ÇÞḢper 14 byte, restituisce un elenco [a, b]fornito ncome argomento.
miglia

@miles Cool! Apparentemente mi mancava completamente /. (Questo è quello che ho fatto nella mia soluzione Pyth.) Modificherò quando salgo sul mio laptop.
PurkkaKoodari,


6

Matlab, 96 81 byte

Golfato (-15byte), oggetti di scena a Luis Mendo

function w(n);a=find(~(mod(n,1:n)));[~,c]=min(abs(a./(n./a)-1.618));[a(c) n/a(c)]

Originale:

function w(n)
a=find(not(mod(n,1:n)));b=abs(a./(n./a)-1.618);c=find(not(b-min(b)));[a(c) n/a(c)]

Questa non è di gran lunga un'ottima soluzione, ma il mio primo tentativo di code-golf. Che divertimento!


2
D'accordo che è divertente! Benvenuti nel sito!
DJMcMayhem

1
È possibile sostituire notcon ~ per salvare alcuni byte. Inoltre, usando la seconda uscita minpuoi sbarazzarti di find:a=find(~(mod(n,1:n)));[~,c]=min(abs(a./(n./a)-1.618));[a(c) n/a(c)]
Luis Mendo,

Ben individuato - questo rade alcuni simboli!
ptev,

1
Si può rendere più breve utilizzando n=input('');al posto di function w(n);allora avete un paio di ()tutto il mod.
flawr


5

Mathematica, 51 byte

#&@@SortBy[{x=Divisors@#,#/x},Abs[#/#2-1.618]&]&

È l'operatore postfix di Mathematica per la trasposizione (visualizzato come apice Tin Mathematica).

Mathematica ha un built-in GoldenRatio, ma 1.618 è molto più breve, soprattutto perché richiede anche il primo N@.


5

Pyth, 21 20 18 byte

hoacFN.n3C_Bf!%QTS

Provalo online. Suite di test.

Spiegazione

  1. Ottieni l' Sintervallo inclusivo da 1 a input.
  2. filter per i numeri che dividono l'input !%QT.
  3. Ottieni [that list, that list reversed] _B. I divisori invertiti di un numero sono la stessa lista del numero diviso per ciascuno dei divisori.
  4. Trasponi l'elenco per ottenere coppie di [numerator, denominator].
  5. S ort le coppie in base alla adifferenza assoluta del rapporto tra la coppia cFNe il rapporto aureo .n3.
  6. Ottieni la prima coppia (più bassa) he stampa.

5

Javascript (ES6), 73 byte

n=>{for(b=0,k=n/.809;n%++b||k>b*b*2&&(a=b););return[b=k-a*a>b*b?b:a,n/b]}

Cerchiamo:

  • a = divisore più alto di n per cui n / φ> a²
  • b = divisore più basso di n per cui n / φ <b²

Quindi, la soluzione è [a, n / a] o [b, n / b] . Confrontiamo n / φ - a² con b² - n / φ per scoprire quale espressione è la più vicina a zero.

La formula effettivamente utilizzato nel codice si basano su φ / 2 che può essere scritto in un modo più breve rispetto φ con la stessa precisione: .809vs 1.618.

Perciò:

n / φ> a² ⇔ n / (φ / 2)> 2a²

e:

n / φ - a²> b² - n / φ ⇔ 2n / φ - a²> b² ⇔ n / (φ / 2) - a²> b²

Complessità

Il numero di iterazioni dipende fortemente dal numero di fattori di n. Il caso peggiore si verifica quando n è primo, perché dobbiamo eseguire tutte le iterazioni da 1 a n per trovare i suoi soli 2 divisori. Questo è ciò che accade con 199999. D'altra parte, 9699690 è 19 liscio e troviamo rapidamente due divisori su entrambi i lati del punto di rottura √ (n / φ) ≈ 2448.

Casi test

let f =
n=>{for(b=0,k=n/.809;n%++b||k>b*b*2&&(a=b););return[b=k-a*a>b*b?b:a,n/b]}

console.log(JSON.stringify(f(12)));       // [ 3, 4 ]
console.log(JSON.stringify(f(42)));       // [ 6, 7 ]
console.log(JSON.stringify(f(576)));      // [ 18, 32 ]
console.log(JSON.stringify(f(1234)));     // [ 2, 617 ]
console.log(JSON.stringify(f(10000)));    // [ 80, 125 ]
console.log(JSON.stringify(f(199999)));   // [ 1, 199999 ]
console.log(JSON.stringify(f(9699690)));  // [ 2431, 3990 ]


4

JavaScript (ES6), 83 byte

f=
n=>{p=r=>Math.abs(r/n-n/r-1);for(r=i=n;--i;)r=n%i||p(i*i)>p(r*r)?r:i;return[r,n/r]}
;
<input type=number min=1 oninput=[a.value,b.value]=f(+this.value)><input readonly id=a><input readonly id=b>

Restituisce effettivamente la coppia ( a , b ) che minimizza il valore assoluto di a / b - b / a -1, ma questo funziona almeno per tutti i casi di test, anche se immagino di poter salvare 4 byte usando invece il test 1.618 .


3

Brachylog , 41 byte

:1fL:2a:Lzoht
,A:B#>.*?!,.=
:3a/:$A-$|
//

Provalo online!

Spiegazione

  • Predicato principale:

    :1fL           L is the list of all couples [A:B] such that A*B = Input (see Pred. 1)
        :2a        Compute the distance between all As/Bs and φ (see Pred. 2)
           :Lz     Zip those distances to L
              o    Sort the zip on the distances
               ht  Take the couple [A:B] of the first element of the sorted list
    
  • Predicato 1: L'output è un paio [A:B]tale cheA*B = Input

    ,A:B           The list [A:B]
        #>         Both A and B are strictly positive
          .        Output = [A:B]
           *?      A*B = Input
             !,    Discard other choice points
               .=  Assign a value to A and B that satisfy the constraints
    
  • Predicato 2: calcola la distanza tra A/Be φ.

    :3a            Convert A and B to floats
       /           Divide A by B
        :$A-       Subtract φ
            $|     Absolute value
    
  • Predicato 3: converti un int in un float invertendolo

    /              1/Input
     /             Output = 1/(1/Input)
    

Per curiosità: φun letterale predefinito in Brachylog? O dove è definito nel codice?
Luis Mendo,

1
Oh, ho appena visto:$A
Luis Mendo,

2
@LuisMendo Aper Au;)
Fatalizza il

Aaah, molto carino!
Luis Mendo,

2

Haskell (Lambdabot), 86 byte

f(x,y)=abs$(x/y)-1.618
q n=minimumBy((.f).compare.f)[(x,y)|x<-[1..n],y<-[1..n],x*y==n]

2

php, 103 byte

<?php for($s=$a=$argv[1];++$i<$a;)if($a%$i==0&&$s>$t=abs($i*$i/$a-1.618)){$n=$i;$s=$t;}echo"$n ".$a/$n;

Produce un avviso (ciò non interrompe l'esecuzione) sui $ i non assegnati, quindi dovrebbe essere eseguito in un ambiente che silenzia le notifiche.


Il conteggio del tag aperto PHP non è necessario quando il codice può essere eseguito come php -r '…'(dove -rè gratuito). E sicuramente non è necessario per la forma lunga, come short_open_tagè di default.
arte

Per quanto ne so $ argv non funziona con -r, quindi non può essere eseguito in questo modo. Detto questo, cambiarlo in readline () o fgets (STDIN) se sei su Windows e in esecuzione senza il tag è probabilmente più breve.
user59178

-re $argvstanno lavorando bene insieme: pastebin.com/vcgb5pT2
manatwork

Huh. Beh, non funziona per me, ricevo solo avvisi variabili non definiti, mi chiedo se è un'impostazione o se è solo Windows come al solito.
user59178

È ancora possibile sostituire <?phpcon <?per salvare tre byte.
Paul Schmitz,

1

Python 3, 96 byte

Soluzione abbastanza semplice. Utilizza questa risposta SO .

lambda n:min([((i,n//i),abs(1.618-i/(n//i)))for i in range(1,n+1)if n%i<1],key=lambda x:x[1])[0]

Provalo online

La stessa soluzione in Python 2 è più lunga di un byte.

lambda n:min([((i,n/i),abs(1.618-1.*i/(n/i)))for i in range(1,n+1)if n%i<1],key=lambda x:x[1])[0]
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.