Hexagon-In oder Hexagon-Out?

8

Es gibt eine großartige Geschichte über reguläre Sechsecke, die zum Beispiel in Waben gefunden werden. Aber diese beschäftigte Biene braucht Ihre Hilfe, um ihm zu sagen, welcher Punkt innerhalb oder außerhalb seines Honigtopfs liegt. Bestimmen Sie also bei einem regelmäßigen Sechseck wie unten abgebildet, zentriert am Ursprung und mit der Kantengröße l, ob sich ein Satz von Koordinaten (x, y) innerhalb, genau am Rand oder außerhalb meines regulären Sechsecks befindet.

Sechseck mit Kantenlänge l, zentriert am Ursprung

Eingabe, Ausgabe und Regeln

Die Regeln sind:

  • Eingabe- und Ausgabemethoden folgen den Standardregeln .
  • Die Eingabe besteht aus drei Ganzzahlen : x,y,l.
  • xund yhaben ein beliebiges geeignetes vorzeichenbehaftetes Ganzzahlformat. list positiv (niemals 0).
  • Ihr Programm muss a ausgeben / zurückgeben, 1wenn sich der Punkt (x,y)innerhalb des regulären Sechsecks befindet, -1wenn er außerhalb liegt oder 0wenn er genau am Rand liegt.
  • Dies ist ein Code-Golf, also gewinnt der kürzeste Code. Bei einem Unentschieden gewinnt der früheste Beitrag.
  • Für die Ausgabe an stdout: führende / nachfolgende Leerzeichen oder Zeilenumbrüche in der Ausgabe sind zulässig.
  • Es gelten Standardlücken.

Testfälle

Hier einige Testfälle:

0,0,1        --> 1
0,1,1        --> -1
0,-1,1       --> -1
1,0,1        --> 0
-1,0,1       --> 0
-1,-1,1      --> -1
1,1,1        --> -1
-2,-3,4      --> 1
32,45,58     --> 1
99,97,155    --> -1
123,135,201  --> 1
agtoever
quelle
Ich gehe davon aus, dass dies ein reguläres Sechseck ist, aber Sie sollten dies explizit machen.
Level River St
@ LevelRiverSt ja. Ein Stammkunde. Ich werde das gleich hinzufügen.
Bis zum
1
Können wir x, y als komplexe Zahl x + yi nehmen?
Lirtosiast
@lirtosiast die Frage ist über ein Sechseck in der euklidischen Ebene, nicht in der komplexen Ebene. Aus diesem Grund ist eine komplexe Eingabe nicht zulässig.
Bis zum

Antworten:

2

JavaScript (ES6) 77 83

(a,b,l,h=Math.sqrt(3)*l,x=a<0?-a:a,y=b<0?-b:b)=>y|x!=l?2*y<h&x/l+y/h<1?1:-1:0

Prüfung

f=(a,b,l,h=Math.sqrt(3)*l,x=a<0?-a:a,y=b<0?-b:b)=>y|x!=l?2*y<h&x/l+y/h<1?1:-1:0

// TEST

function go() {
  C.width=400;C.height=300;
  var l=+I.value, x,y, cols={0:'#ff0',1:'#0f0','-1':'#888'},
  ctx = C.getContext("2d")
  ctx.translate(200,150)
  ctx.strokeStyle='#000'
  ctx.lineWidth=1;
  ctx.beginPath();
  ctx.moveTo(0,-150);ctx.lineTo(0,150);ctx.moveTo(-200,0);ctx.lineTo(200,0);
  ctx.stroke();
  ctx.strokeStyle='#f00'
  ctx.beginPath();
  ctx.moveTo(l*10,0);ctx.lineTo(l*5,l*Math.sqrt(3)*5);ctx.lineTo(-l*5,l*Math.sqrt(3)*5)
  ctx.lineTo(-l*10,0);ctx.lineTo(-l*5,-l*Math.sqrt(3)*5);ctx.lineTo(l*5,-l*Math.sqrt(3)*5)
  ctx.closePath();
  ctx.stroke();

  for(y=-14;y<15;y++)
    for(x=-19;x<20;x++) {
      ctx.beginPath();
      ctx.moveTo(x*10,y*10-3);ctx.lineTo(x*10,y*10+3);
      ctx.moveTo(x*10-3,y*10);ctx.lineTo(x*10+3,y*10);
      ctx.strokeStyle=cols[f(x,y,l)]
      ctx.stroke()
    }
}

go()
#C {
  border: 1px solid #000
}
<b>L</b> <input id=I value=15><button onclick="go()">GO</button><br>
<canvas id=C width=400 height=300></canvas>

edc65
quelle
2

Ruby, 150 145 137 127 125 106 88 76 76 Bytes

76 Bytes

->(x,y,l){x,y,t=x.abs,y.abs,3**0.5;d=t*l;z=d-t*x-y;2*y>d ?-1:2*x<l ?1:z<=>0}

Dreifacher Vergleich mit einer Rakete geändert.

88 Bytes

->(x,y,l){x,y,t=x.abs,y.abs,3**0.5;d=t*l;z=d-t*x-y;2*y>d ?-1:2*x<l ?1:z==0 ?0:0<z ?1:-1}

Entfernen Sie das y gleich dem Apothem-Test für Punkte auf dem Sechseck, da dies für ganze Zahlen niemals wahr sein kann.

106 Bytes:

->(x,y,l){x,y,t=x.abs,y.abs,3**0.5;d=t*l;z=d-t*x-y;2*y==d&&2*x<=l ?0:2*y>d ?-1:2*x<l ?1:z==0 ?0:0<z ?1:-1}

Das Poster schlug vor, kein Epsilon zu verwenden, ersetzte also Epsilon durch Null und ordnete es neu, entfernte eine Bauchmuskulatur usw.

125 Bytes:

->(x,y,l){x,y,t,e=x.abs,y.abs,3**0.5,1e-9;d=t*l;z=d-t*x-y;(2*y-d).abs<=e&&2*x<=l ?0:2*y>d ?-1:2*x<l ?1:z.abs<=e ?0:0<z ?1:-1}

Integrieren Sie y in die Definition von z und entfernen Sie einige Klammern.

127 Bytes:

->(x,y,l){x,y,t,e=x.abs,y.abs,3**0.5,1e-9;d=t*l;z=d-t*x;(2*y-d).abs<=e&&2*x<=l ?0:2*y>d ?-1:2*x<l ?1:(z-y).abs<=e ?0:y<z ?1:-1}

Neu angeordnete Begriffe, um die Notwendigkeit einer Besetzung zu vermeiden. Verwenden Sie d (doppeltes Apothem) anstelle von a (Apothem). Kombinieren Sie mehrere Aufgaben.

137 Bytes:

->(x,y,l){x=x.abs.to_f;y=y.abs.to_f;a=3**0.5*l/2;e=1e-9;z=2*a*(1-x/l);(y-a).abs<=e&&2*x<=l ?0:y>a ?-1:2*x<l ?1:(z-y).abs<=e ?0:y<z ?1:-1}

Inline 'c'.

150 Bytes:

->(x,y,l){c=l/2.0;x=x.abs.to_f;y=y.abs.to_f;a=3**0.5*l/2;e=1e-10;z=2*a*(1-x/l);(y-a).abs<=e&&x<=c ?0:(y>a ?-1:(x<c ?1:((z-y).abs<=e ?0:(y<z ?1:-1))))}

Dies funktioniert für ganze Zahlen oder Gleitkommazahlen! Der Epsilon-Test ist so, dass Punkte innerhalb des Rundungsfehlers am Rand korrekt identifiziert werden.

Die absoluten Werte verschieben alles in den ersten Quadranten.

Der Wert 'a' ist der Apothemabstand (der y-Achsenabschnitt des Sechsecks).

Der Wert 'c' ist der x-Wert der oberen rechten Ecke des Sechsecks.

Der Wert 'z' gibt an, ob der Punkt über oder unter der schrägen Linie von der Ecke zum x-Achsenabschnitt liegt.

Ungolfed:

hex = ->(x,y,l){ 
    c = l/2.0;
    x = x.abs.to_f;
    y = y.abs.to_f;
    a = 3**0.5 * l / 2;
    e = 1e-10;
    z = 2*a*(1 - x/l);
    if (y-a).abs <= e && x <= c then 0
    elsif (y>a) then -1
    elsif (x<c) then 1
    elsif (z-y).abs <= e then 0
    elsif y < z then 1
    else -1
    end
}

Prüfung

hex = ->(x,y,l){x,y,t=x.abs,y.abs,3**0.5;d=t*l;z=d-t*x-y;2*y>d ?-1:2*x<l ?1:z<=>0}

cases = [
    [0,0,1,1],
    [0,1,1,-1],
    [0,-1,1,-1],
    [1,0,1,0],
    [-1,0,1,0],
    [-1,-1,1,-1],
    [1,1,1,-1],
    [-2,-3,4,1],
    [32,45,58,1],
    [99,97,155,-1],
    [123,135,201,1]
]

cases.each { |test| 
  expected = test[3]
  actual = hex.call(test[0],test[1],test[2])
  status = expected == actual ? "PASS" : "FAIL";
  p "#{status}. #(x,y) L = (#{test[0]},#{test[1]}) #{test[2]} Expects #{expected}. Actual #{actual}"
}
"Done!"
Paul Chernoch
quelle
Dies könnte kürzer sein, Sie brauchen das Epsilon nicht für ganze Zahlen
edc65
Durch die Einführung der Quadratwurzel von drei bin ich gezwungen, Gleitkomma zu verwenden. Ich könnte die Zahlen vor dem Vergleich runden oder Epsilon-Berechnungen verwenden. Da epsilon zulässt, dass der Code allgemeiner ist und für Floats funktioniert, habe ich das epsilon verlassen. Ich habe Ruby nur kurze Zeit programmiert, bin mir also nicht sicher, wie es mit Rundungsfehlern umgeht.
Paul Chernoch
Die Neigung der linken und rechten Seite ist nicht rational. Das Apothem ist nicht rational. Das sind nur 2 Punkte mit ganzzahligen Koordinaten, die am Umfang liegen: [l, 0] und [-l, 0]
edc65
Sie haben wahrscheinlich Recht, dass es für ganzzahlige Eingaben keine anderen möglichen ganzzahligen Punkte gibt, die sich "auf" dem Sechseck befinden. Es war schwieriger für mich, das zu beweisen, als den Code mit epsilon egal zu machen.
Paul Chernoch
Ja! Habe gerade die Python-Lösung bestanden!
Paul Chernoch
0

Julia, 65 58 Bytes

f(x,l)=(t=maxabs(x/l*[[0 1 1];[2 1 -1]/3^.5]);(t<1)-(t>1))

xist ein Zeilenvektor [x y]. Rufen Sie so an : f([0 0],1).

Rainer P.
quelle
0

Python 2, 89 Bytes

Fast die gleiche Lösung wie Julia, aber wir können die Operation für Vektoren ohne Numpy verwenden

lambda x,y,L,K=3**0.5/2.:cmp(K*L,max([abs(x*i+y*j)for i,j in[[K,1/2.],[0,1],[-K,1/2.]]]))

Ergebnisse

>>> f(0,0,1)
1
>>> f(32,45,58)
1
>>> f(99,97,155)
-1
>>> f(-1,0,1)
0
>>> [f(0,0,1)== 1,f(0,1,1)== -1,f(0,-1,1)== -1,f(1,0,1)== 0,f(-1,0,1)== 0,f(-1,-1,1)== -1,f(1,1,1)== -1,f(-2,-3,4)== 1,f(32,45,58)== 1,f(99,97,155)== -1,f(123,135,201)== 1,f(0,0,1)== 1,f(0,1,1)== -1,f(0,-1,1)== -1,f(1,0,1)== 0,f(-1,0,1)== 0,f(-1,-1,1)== -1,f(1,1,1)== -1,f(-2,-3,4)== 1,f(32,45,58)== 1,f(99,97,155)== -1,f(123,135,201)== 1]
[True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]
Erwan
quelle
0

Pyth, 41 Bytes

?<=d.5K+?>ZJ-c.ahQeQdZJ.acchtQeQ^3d_1s>dK

Testen Sie es hier

Cameron McCluskie
quelle
0

JavaScript (ES6), 67 Byte

with(Math)(a,b,l)=>sign(min(l*l*3-b*b*4,(l-abs(a))*sqrt(3)-abs(b)))

Hinweis: Um dies einer Variablen zuzuweisen, damit Sie sie aufrufen können, setzen Sie das f=nach with(Math).

Ich verwenden l*lund b*bim ersten Parameter zu minvermeiden Anrufe absund sqrtaber ich konnte nicht herausfinden, ob ich einen ähnlichen Trick mit dem zweiten Parameter tun könnte.

Neil
quelle