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.