Der reisende O

26

Die Welt besteht aus fünf mal fünf Zellen. Es wickelt sich nach allen Seiten. Es kann visualisiert werden wie ...

XXXXX
XXXXX
XXOXX
XXXXX
XXXXX

Du bist ein O. Du liebst es, die Welt zu bereisen, und das nach den folgenden Regeln (lass C der aktuelle Tag sein):

  • An den besten Tagen fühlen Sie sich nostalgisch. Kehren Sie dorthin zurück, wo Sie gestern angefangen haben.
  • An ungeraden Tagen haben Sie Heimweh. Wenn möglich, einen horizontalen Schritt näher an den Wohnort und, wenn möglich, einen vertikalen Schritt näher an den Wohnort. Ignorieren Sie das Umbrechen der Welt, um die Nähe zu bestimmen.
  • An geraden Tagen fühlen Sie sich abenteuerlustig. Gehe 2 Schritte nach Süden.
  • An viereckigen Tagen fühlt man sich abenteuerlustig. Gehe zur Ostwand.
  • An Fibonacci- Tagen dehnt sich die Welt um eine Reihe nach Süden aus.
  • An dreieckigen Tagen dehnt sich die Welt um eine Säule nach Osten aus.

Wenn zwei oder mehr der oben genannten Regeln gleichzeitig gelten, wenden Sie sie in der angegebenen Reihenfolge an. Kehren Sie beispielsweise an einem ungeraden Primetag zunächst dorthin zurück, wo Sie gestern begonnen haben, und bewegen Sie sich dann einen Schritt weiter nach Hause.

Sie leben in der Mitte der (ursprünglichen) Welt, dh Position (2,2), nullindiziert von der Nordwestecke. Sie beginnen Ihre Reise dort am ersten Tag.

Eingang

Eine einzelne ganze Zahl, N.

Ausgabe

Ihre X- und Y-Koordinate am N-ten Tag, nullindexiert von der Nordwestecke, getrennt durch ein einzelnes Leerzeichen.

Testfall mit Erklärung

Bei einer Eingabe von 3lautet die korrekte Ausgabe:

2 3

Wir können diesen einen Tag nach dem anderen durcharbeiten. Ab Tag 1 müssen wir die folgenden Schritte ausführen:

  1. Ungerade, quadratisch, Fibonacci und dreieckig
  2. Prime, Even und Fibonacci
  3. Prime, Odd, Fibonacci und Triangular

In visueller Form:

     Tag 1 Tag 2 Tag 3
XXXXX XXXXXX XXXXXX XXXXXXX
XXXXX XXXXXX XXXXXX XXXXXXX
XXOXX -> XXXXOX -> XXXXXX -> XXXOXXX
XXXXX XXXXXX XXOXXX XXXXXXX
XXXXX XXXXXX XXXXXX XXXXXXX
           XXXXXX XXXXXX XXXXXXX
                       XXXXXX XXXXXXX
                                   XXXXXXX

Zusätzliche Testfälle

Mit freundlicher Genehmigung von Martin Büttner ‚s Referenzlösung (bitte beachten Sie, dass Sie nur eine einzige Ausgabe - Koordinaten sollte, nicht alle von ihnen):

Input:  1     2     3     4     5     6     7     8     9     10    11    12    13    14     15    16    17    18    19    20    21    22    23
Output: 4 2   2 3   3 2   6 4   2 2   2 5   2 2   2 6   7 5   7 0   6 4   6 0   5 3   5 10   4 9   9 6   3 8   3 6   2 7   2 6   2 5   2 4   2 4

Das ist Code Golf. Die kürzeste Einsendung gewinnt.

Regenblitz
quelle
6
Ich muss das in O tun!
kirbyfan64sos

Antworten:

4

Pyth, 157 156 153 Bytes

=Z=b5aYA,2 2FNtUhQI&!tPN<1NA@Y_2)Iq*2/N2NA,G%+H/N2b)EL-+b<b2<2bAyM,GH)J@N2Iq/NJJA,tZH)=TU2W<hTNIqNeT=hbBE=TX_T1sT))=J0W!<NJIqN/*JhJ2=hZBE=hJ))aY(GH;jd,GH

Sie können es hier ausprobieren.

Das war ein lustiges Problem beim Golfen! Ich gewöhne mich immer noch an Pyth, aber es ist eine wirklich großartige Sprache.

Rhyzomatic
quelle
1
Willkommen bei Pyth! Ein Golf, den ich sofort sehe: Wenn Sie eine Liste mit 2 Elementen / ein Tupel erstellen möchten, verwenden Sie ,- dafür ist es da.
Isaacg
Es gibt mehr Platz für diesen Golf thoughout die Code - (G%+H/N2b), (GH), (tZH).
isaacg
12

Haskell, 394 Bytes

z=0<1
p d y c|all((0<).mod d)[2..d-1]=y|z=c
g x=x-signum(x-2)
e d(x,y)h|odd d=(g x,g y)|z=(x,mod(y+div d 2)h)
s d c@(_,y)w|d==(floor$sqrt$fromIntegral d)^2=(w-1,y)|z=c
f d a b m|b>d=m|b==d=(+1)<$>m|z=f d b(a+b)m
d%m@(w,h)|elem d[div(n*n-n)2|n<-[1..d+1]]=(w+1,h)|z=m
i=fst.c
j=snd.c
c d|d<1=((2,2),(5,5))|z=(s d(e d(p d(i$d-2)$i$d-1)$snd$j$d-1)$fst$j$d-1,d%(f d 1 1$j$d-1))
main=readLn>>=print.i

Es kann definitiv optimiert werden und auch nach einer schnellen Überprüfung auf Richtigkeit anscheinend erhalte ich andere ergebnisse als das gepostete. Ich komme zurück und überprüfe meinen Code gründlicher, wenn ich mehr Zeit habe ^^

Nettes Problem übrigens!

BEARBEITEN: Meine Lösung wurde unter Berücksichtigung der wertvollen Ratschläge von Zgarb bearbeitet . Es funktioniert jetzt perfekt!

EDIT2: dank nimi habe ich den code noch kleiner gemacht. Ich mache jetzt auch die Prüfungen für gerade und ungerade in einer Funktion anstelle von zwei, die insgesamt die Anzahl von 446 auf 414 Bytes verringert.

EDIT3: weiter verbessert von 414 auf 400 Bytes. Danke nimi für weitere 2 Bytes, du bist in Flammen! :)

EDIT4: 4 weitere Bytes von nimi :)

Basilikum-Henry
quelle
2
Willkommen bei PPCG! Ein paar schnelle Tipps: Ist 0<1kürzer als otherwiseund 0/=mod x ykann auf gekürzt werden 0<mod x y. Auch 1==mod(d)2ist odd dund 0==mod(d)2ist even d.
Zgarb
@Zgarb nette Tricks, ich bin in der Tat ziemlich neu in dieser ganzen Code-Golf-Sache. Wie funktioniert das aber 0<1anstatt zu otherwisearbeiten?
basile-henry
1
Außerdem denke ich, dass Ihre Definition von Dreieckszahlen falsch ist (ich gehe davon aus, dass dies in der Funktion liegt t), da elem d[1..div(d*d-d)2]dies für alle gilt d > 2.
Zgarb
otherwiseist nur ein anderer Name für True.
Zgarb
Vielen Dank, ja du hast recht, ich habe versucht, Dreieckszahlen zu schnell zu machen ...
basile-henry
5

C 425 396 Bytes

typedef struct{int x,y,b,r}c;S,p,n;s(d){return(S=sqrt(d))*S==d;}c m(d){if(!d)return(c){2,2,4,4};c q,l=m(d-1);for(p=1,n=d;--n;p=p*n*n%d);if(p&&d>1)q=m(d-2),l.x=q.x,l.y=q.y;if(d%2)l.x-=l.x>2?1:l.x<2?-1:0,l.y-=l.y>2?1:l.y<2?-1:0;else l.y+=d/2,l.y=l.y>l.b?l.y-l.b-1:l.y;if(s(d))l.x=l.r;if(s(5*d*d+4)||s(5*d*d-4))l.b++;if(s(8*d+1))l.r++;return l;}main(i){scanf("%d",&i);printf("%d %d",m(i).x,m(i).y);}

Es gibt Teile, die verbessert werden könnten, aber es funktioniert für die Testfälle .


Erläuterung

typedef struct {
    int x,y,b,r
} c; //c will hold the information for each day

//determines if a number is a perfect square
S,p,n;
s(d) {
    return (S=sqrt(d))*S==d;
}

c m(d) {
    if(!d)
        return (c){2,2,4,4}; //returns the initial information if the day is 0

    c q,l=m(d-1); //gets the information for the previous day
    for (p=1,n=d;--n;p=p*n*n%d); //tests if the number is prime

    if (p&&d>1)
        q=m(d-2),l.x=q.x,l.y=q.y; //changes the position to what it was at the end of the day 2 days ago if the day is prime
    if (d%2)
        l.x-=l.x>2?1:l.x<2?-1:0,l.y-=l.y>2?1:l.y<2?-1:0; //moves the position towards (2,2) if the day is odd
    else
        l.y+=d/2,l.y=l.y>l.b?l.y-l.b-1:l.y; //moves down if the day is even
    if (s(d))
        l.x=l.r; //moves east if the day is a perfect square
    if (s(5*d*d+4)||s(5*d*d-4))
        l.b++; //expands world down if the day is a fibonacci number
    if (s(8*d+1))
        l.r++; //expands world right if the day is a triangular number
    return l;
}

main(i) {
    scanf("%d",&i);
    printf("%d %d",m(i).x,m(i).y);
}
Chris Loonam
quelle
3

Perl 5, 284 Bytes

@s=([2,2]);@n=(2,2);@f=(0,1);$w=$h=5;for(1..<>){$f[$_+1]=$f[$_]+$f[$_-1];$t[$_]=$_*($_+1)/2;$s[$_]=[@n];@n=@{$s[$_-1]}if(1 x$_)!~/^1$|^(11+?)\1+$/;($_%2)&&($n[0]-=($n[0]<=>2),$n[1]-=($n[1]<=>2))or$n[1]=($n[1]+$_/2)%$h;$n[0]=$w-1if(int sqrt$_)**2==$_;$h++if$_~~@f;$w++if$_~~@t}say"@n"

283 Bytes plus 1 für -EFlag anstelle von-e

Gleicher Code, jedoch mit mehr Leerzeichen, mehr Klammern und längeren Variablennamen:

@start=([2,2]);
@now=(2,2);
@fibonacci=(0,1);
$width = ($height=5);
for my $iterator (1 .. <>) {
  $fibonacci[$iterator+1] = $fibonacci[$iterator] + $fibonacci[$iterator-1];
  $triangular[$iterator] = $iterator * ($iterator+1) / 2;
  $start[$iterator] = [@now];
  @now = @{ $start[$iterator-1] } if ((1 x $iterator) !~ /^1$|^(11+?)\1+$/); # prime
  $now[0] -= ($now[0] <=> 2) , $now[1] -= ($now[1] <=> 2) if ($iterator % 2 != 0); # odd
  $now[1] = ($now[1] + $iterator / 2) % $height if ($iterator % 2 == 0); # even
  $now[0] = $width - 1 if ((int sqrt $iterator) ** 2 == $iterator); # square
  $height ++ if $iterator ~~ @fibonacci;
  $width ++ if $iterator ~~ @triangular;
}
say "@now";

Ich bin zuversichtlich, dass dies weiter golfen werden kann.

msh210
quelle
2

Javascript, 361 359 Bytes

N=>{for(c=1,x=y=v=w=j=k=2,h=z=5;c<=N;c++,j=v,k=w,v=x,w=y){m=Math;p=(n,c)=>n%c!=0?c>=n-1?1:p(n,++c):0;[x,y]=c==2||p(c,2)&&c!=1?[j,k]:[x,y];p=x=>x+(x<2?1:x>2?-1:0);c%2?[x,y]=[p(x),p(y)]:y+=c/2;m.sqrt(c)==~~m.sqrt(c)?x=z-1:0;f=(n,c,d)=>d<c?0:d==c?1:f(c,n+c,d);f(1,2,c)||c==1?h++:0;t=(n,c)=>n*++n/2==c?1:--n*n/2>c?0:t(++n,c);t(1,c)?z++:0;x%=z;y%=h}return x+" "+y}

Der Code verwendet Destructuring Assignment . Es wird derzeit nur in Firefox und Safari unterstützt.

Erläuterung

N=>{
// C => the day, x,y => position, v,w => position at the start of the day, 
// j,k => position of yesterday
for(c=1,x=y=v=w=j=k=2,h=z=5;c<=N;c++,j=v,k=w,v=x,w=y){
    m=Math;

    // Prime Function for C > 2. Recursive call to save a loop.
    p=(n,c)=>n%c!=0?c>=n-1?1:p(n,++c):0;
    // Assign x and y to yesterday
    [x,y]=c==2||p(c,2)&&c!=1?[j,k]:[x,y];

    // Function to move closer to home
    p=x=>x+(x<2?1:x>2?-1:0);
    c%2?[x,y]=[p(x),p(y)]:y+=c/2;

    // Square check
    m.sqrt(c)==~~m.sqrt(c)?x=z-1:0;

    // Fibonnacci function for C > 1
    f=(n,c,d)=>d<c?0:d==c?1:f(c,n+c,d);
    f(1,2,c)||c==1?h++:0;

    // Triangle function
    t=(n,c)=>n*++n/2==c?1:--n*n/2>c?0:t(++n,c);
    t(1,c)?z++:0;

    // Stay in bounds
    x%=z;y%=h
}
// Output
return x+" "+y}
Naouak
quelle