Was ist der Durchschnitt von n, die nächste Primzahl zu n, das Quadrat von n und die nächste Fibonacci-Zahl zu n?

13

Dies ist ein mathematisches Problem, das ziemlich viele Dinge in Frage stellt und es ziemlich herausfordernd macht, und wie Sie vielleicht vermutet haben, ist es ein Code-Golf, also sollte es so kurz wie möglich sein.

Der Eingang , nist jede ganzzahlige Anzahl (mindestens Unterstützung ganze Zahlen, müssen aber nicht darauf beschränkt zu sein). Die Ausgabe ist der Durchschnitt von:

  • n
  • Das Quadrat von n
  • Die nächste Primzahl zu n
  • Die nächstliegende Zahl nin der Fibonacci-Sequenz

In Kürze sollte das Programm das Ergebnis von auf dem Standardausgangskanal ausgeben .(n+(n*n)+closestPrime(n)+closestFib(n))/4

Sie müssen sich nicht um mögliche Überläufe usw. kümmern. Normale Gleitkomma-Genauigkeit ist ebenfalls in Ordnung.

Die Art und Weise, wie die Eingabe erfolgt, liegt ganz bei Ihnen. Das kürzeste Programm (in Zeichen) gewinnt, wie immer bei Code Golfs.

Wählen Sie eine der folgenden Optionen, falls bei der Suche nach der nächstgelegenen ein Unentschieden auftritt:

  1. Geh hinauf
  2. Gehen
  3. Wähle eine zufällig aus
Anto
quelle
Definieren Sie "am nächsten". Wie werden Krawatten gebrochen?
Peter Taylor
@ Peter Taylor: Bewegen Sie sich nach oben, unten oder wählen Sie eine zufällig.
Anto
Geben Sie einige Beispieleingaben / -ausgaben ein, um die Lösungen zu überprüfen.
Freitag,
Was muss noch unterstützt werden, wenn Sie „darf nicht beschränkt sein auf“ sagen? Oder meintest du vielleicht "muss nicht beschränkt sein auf"?
Timwi
@ Timwi! "brauche nicht", tut mir leid, wird es beheben
Anto

Antworten:

10

Python 160 Zeichen

p=lambda n:any(n%x<1for x in range(2,n))
N=input()
a=0;b=1
while b<N:a,b=b,a+b
c=d=N
while p(c)and p(d):c-=1;d+=1
print (N+N*N+[b,a][2*N-a-b<0]+[c,d][p(c)])/4.0

Eine kleine Erklärung zum nächsten Fib-Teil:

Wenn die while-Schleife endet, ist a kleiner als N und b ist entweder gleich oder größer als N. Jetzt ist der [b,a][2*N-a-b<0]Teil. Betrachten Sie es als [b, a] [(Na) - (bN)]. (Na) ist der Unterschied zwischen N und a und in ähnlicher Weise (bN) der Unterschied zwischen b und N. Wenn der Unterschied zwischen diesen beiden kleiner als 0 ist, bedeutet dies, dass a näher an N liegt und umgekehrt.

fR0DDY
quelle
Können Sie eine Erklärung hinzufügen, warum dies funktioniert?
Quixotic
@Debanjan Irgendetwas Bestimmtes, willst du nicht wissen? Ich fand alles selbsterklärend. :)
fR0DDY
Nur das bisschen vom nächsten Fib-Teil [b,a][2*N-a-b<0]:)
Quixotic
7

GolfScript, 59 Zeichen

~:N..*.,2>{:P{(.P\%}do(!},{{N-.*}$0=}:C~[1.{.@+.N<}do]C+++4/

Dieses Skript erfüllt einige der Anforderungen nicht:

  • Es funktioniert nur bei Eingaben korrekt n >= 2, sonst stürzt es ab.
  • Die Ausgabe wird auf eine Ganzzahl gekürzt.
  • Schreckliche Leistung für alle mäßig großen n

Eine kurze Anleitung zum Code:

  1. ~:N..*Die Eingabe wird in N gespeichert und wir drücken beide nund das Quadrat n*nsofort.
  2. .,2>Wir werden eine Liste von Primzahlen erzeugen, indem wir das Array filtern [2..n*n]. Wir verwenden unsere vorherige Berechnung von n*nals (sehr schlechte!) Obergrenze, um eine Primzahl zu finden, die größer als n ist.
  3. {:P{(.P\%}do(!},Unser bisheriges Array wird nach Testdivision gefiltert. Jede Ganzzahl P wird gegen jede Ganzzahl [P-1..1] getestet.
  4. {{N-.*}$0=}:C~Sortiert das vorherige Array basierend auf dem Abstand zu nund erfasst das erste Element. Jetzt haben wir die nächste Primzahl.
  5. [1.{.@+.N<}do]CWir erzeugen Fibonnacis, bis wir eins größer als erhalten n. Glücklicherweise verfolgt dieser Algorithmus natürlich die vorherigen Fibonnaci, sodass wir beide in ein Array werfen und unsere frühere Entfernungssortierung verwenden. Jetzt haben wir die nächsten Fibonnaci.
  6. +++4/Durchschnittlich. Beachten Sie, dass GolfScript keine Floats unterstützt, sodass das Ergebnis abgeschnitten wird.

GolfScript, 81 Zeichen

Hier ist eine Variante, die alle Anforderungen erfüllt.

~:N..*2N*,3,|2,^{:P{(.P\%}do(!},{{N-.*}$0=}:C~[0.1{.@+.N<}do]C+++100:E*4/.E/'.'@E%

Um ein einwandfreies Verhalten zu gewährleisten n<2, vermeide ich 2<(stürzt ab, wenn das Array klein ist) und verwende stattdessen 3,|2,^. Dies stellt sicher, dass das Hauptkandidatenarray genau [2]dann ist, wenn n < 2. Ich habe die Obergrenze für die nächste Primzahl von n*nnach 2*n( Bertrands Postulat ) geändert . Auch 0 gilt als Fibonnaci-Zahl. Das Ergebnis wird am Ende in Festkomma-Mathematik berechnet. Interessanterweise scheint das Ergebnis immer in Vierteln zu sein (0, .25, .5, .75), daher hoffe ich, dass 2 Dezimalstellen Genauigkeit ausreichen.

Mein erster Riss bei der Verwendung von GolfScript, ich bin sicher, es gibt Raum für Verbesserungen!

Mike Welsh
quelle
7
Weißt du, wenn du durch 4 teilst, ist es nicht verwunderlich, dass du Vierteln bekommst ;-)
Joey,
...tatsächlich! +1;)
Mike Welsh
3

JavaScript, 190

function n(n)
{z=i(n)?n:0
for(x=y=n;!z;x--,y++)z=i(x)?x:i(y)?y:0
for(a=b=1;b<n;c=a+b,a=b,b=c);
return(n+n*n+(2*n-a-b<0?a:b)+z)/4}
function i(n)
{for(j=2;j<n;j++)
if(!(n%j))return 0
return 1}

[257]

function n(n)
{return(n+n*n+p(n)+f(n))/4}
function p(n)
{if(i(n))return n
for(a=b=n;;a--,b++){if(i(a))return a
if(i(b))return b}}
function i(n)
{for(j=2;j<n;j++)
if(!(n%j))return 0
return 1}
function f(n)
{for(a=b=1;b<n;c=a+b,a=b,b=c);
return 2*n-a-b<0?a:b}

Unkomprimiert:

function closest( a, b, c )
{
  return 2*a-b-c < 0 ? b : c;
}

function closestPrime( n )
{
  a=b=n;
  if (isPrime( n ) ) return n;
  while ( true )
  {
    a-=1;
    b+=1;
    if (isPrime(a))return a;
    if (isPrime(b))return b;
  }
}

function isPrime( n )
{
  for (i=2;i<n;i++)
  {
    if ( !( n % i ) ) return false;
  }
  return true;
}

function closestFib( n )
{
  for(fib1=0,fib2=1;fib2<n;fib3=fib1+fib2,fib1=fib2,fib2=fib3);
  return closest( n, fib1, fib2 );
}

function navg(n)
{
  n2 = n*n;
  np = closestPrime( n );
  nf = closestFib( n );
  return ( n + n2 + np + nf ) / 4;
}
zzzzBov
quelle
Für Ihre engste Hauptfunktion: Ich denke, Sie können Platz sparen, wenn Sie nur verwenden a=0und positiv erhöhen. Anstatt isPrimenach aund zu suchen b, überprüfen Sie einfach isPrime(n+a)und isPrime(n-a). Sie könnten wahrscheinlich alles zu einer verrückten ternären Aussage zusammenfassen, aber ich bin schrecklich mit Javascript.
Mr. Llama
Die folgende scheint zu funktionieren recht gut: function closestPrime(n,o){return isPrime(n+o)?n+o:isPrime(n-o)?n-o:closestPrime(n,o+1);}. Nennen Sie es als closestPrime(n,0)und es wird von selbst funktionieren. Bei Bedarf kürzen.
Mr. Llama
1

Mathematica, 70 69 Bytes

Dank Sp3000 wird ein Byte gespart (manchmal sind integrierte Funktionen nicht der beste Weg).

((n=#)+#^2+(f=#&@@#@Range@Max[1,2n]~Nearest~n&)@Prime+f@Fibonacci)/4&

Dies definiert eine unbenannte Funktion, die eine ganze Zahl verwendet und den exakten Mittelwert als rationale Zahl liefert. Bei Gleichstand wird die kleinere Primzahl / Fibonacci-Zahl gewählt.

Dies ist für große Eingaben sehr ineffizient, da die ersten 2nPrimzahlen und Fibonacci-Zahlen generiert werden, bevor die nächstgelegenen ausgewählt werden.

Martin Ender
quelle
#&@@#.. Huh?
Siehe auch
@Sieg Von rechts beginnend: #ist das Argument einer reinen Funktion (von f). In diesem Fall ist es eigentlich eine Funktion selbst, da fauf Primeund angewendet wird Fibonacci. Damit wird #@Range@...die angegebene Funktion auf jede Ganzzahl im Bereich angewendet. Dann #&@@ist es nur eine gute Möglichkeit , das erste Element einer Liste zu extrahieren. Es funktioniert, indem es #&auf die Liste angewendet wird, eine Funktion, die lediglich das erste Argument zurückgibt.
Martin Ender
0

Q, 119

Nicht die effizienteste.

{%[;4]x+(x*x)+((*:)a(&)b=min b:abs x-a:{x,sum -2#x}/[x-2;1 1])+(*:)d(&)e=min e:x-d:(&)1={(min x mod 2_(!)x)}each(!)x+2}
tmartin
quelle
0

MATLAB 88 Zeichen

C=@(F)(F(abs(F-n)==min(abs(F-n))));(n+n^2+C(primes(n*2))+C(round(1.618.^(1:n)/2.236)))/4

n ist deine ganze Zahl

Funktioniert mit Nicht-Ganzzahlen, soweit ich es getestet habe, funktioniert es auch mit sehr großen Zahlen, läuft auch verdammt schnell.

Greif
quelle
0

Scala 299

object F extends App{type I=Int
def f(n:I,b:I=1,a:I=1):I=if(a>=n)if(a-n>n-b)b else a else f(n,a,b+a)
def p(n:I)=(2 to n-1).exists(n%_==0)
def i(n:I,v:I):Int=if(!p(n+v))n+v else i(n+v,v)
val a=readInt
println(({val p=Seq(-1,1).map(i(math.max(a,3),_))
if(a-p(0)>p(1)-a)p(1)else p(0)}+f(a)+a+a*a)/4.0)}

Test und Aufruf:

a  a² nP(a) nF  ∑   /4.0 
------------------------
-2  4   2   1   5   1.25
-1  1   2   1   3   0.75
0   0   2   1   3   0.75
1   1   2   1   5   1.25
2   4   2   2   10  2.5
3   9   2   3   17  4.25
4   16  3   5   28  7.0
5   25  3   5   38  9.5

Die Frage spricht, any Integeraber das Problem ist für Werte unter 0 nicht so interessant. Doch wie fangen wir an? Bei 0? Um 1? Und was ist die nächste Primzahl für 11? 11 selbst?

Die Idee, im Falle eines Unentschieden das nächstgrößere oder niedrigere zuzulassen, ist schlecht, weil es das Vergleichen unnötig schwierig macht. Wenn Ihre Ergebnisse unterschiedlich sind, können sie die andere Fib, die andere Primzahl, die andere Fib und die andere Primzahl gewählt haben, oder Ihre sind falsch, oder das Ergebnis der anderen Person ist falsch, oder es ist eine Kombination: andere Wahl, aber falsch obwohl, vielleicht beide falsch.

Benutzer unbekannt
quelle