The Travelling O

26

Świat to tablica komórek pięć na pięć. Zawija się ze wszystkich stron. Można to wizualizować jak ...

XXXXX
XXXXX
XXOXX
XXXXX
XXXXX

Jesteś O. Uwielbiasz podróżować po świecie i robisz to zgodnie z następującymi zasadami (niech C będzie dniem bieżącym):

  • W pierwszorzędne dni czujesz nostalgię. Wróć do miejsca, w którym zacząłeś wczoraj.
  • W dziwne dni tęsknisz za domem. Przesuń jeden poziomy poziom bliżej domu, jeśli to możliwe i jeden pionowy krok bliżej domu, jeśli to możliwe. Zignoruj ​​zawijanie świata w celu określenia bliskości.
  • W parzyste dni masz ochotę na przygodę. Przesuń C / 2 kroki na południe.
  • W kwadratowe dni masz ochotę na przygodę. Przejdź do wschodniej ściany.
  • W dni Fibonacciego świat rozszerza się na południe o jeden rząd.
  • W dni trójkątne świat rozszerza się na wschód o jedną kolumnę.

Jeśli dwie lub więcej z powyższych zasad miałoby zastosowanie jednocześnie, zastosuj je w podanej kolejności. Na przykład, w dziwny pierwszy dzień, najpierw wróć do miejsca, w którym zacząłeś wczoraj, a następnie przejdź o krok bliżej domu.

Żyjesz w centrum (początkowego) świata, tj. W pozycji (2,2), zerowo indeksowanej od północno-zachodniego rogu. Podróż rozpoczyna się tam pierwszego dnia.

Wkład

Pojedyncza liczba całkowita, N.

Wydajność

Twoja współrzędna X i Y N-tego dnia, indeksowana zerowo od rogu północno-zachodniego, oddzielona pojedynczym odstępem.

Przypadek testowy z objaśnieniem

Biorąc pod uwagę 3, poprawny wynik to:

2 3

Możemy pracować nad tym jeden dzień na raz. Począwszy od pierwszego dnia musimy zastosować następujące ruchy:

  1. Dziwne, kwadratowe, Fibonacciego i trójkątne
  2. Prime, a nawet Fibonacci
  3. Prime, nieparzyste, Fibonacciego i trójkątne

W formie wizualnej:

     Dzień 1 Dzień 2 Dzień 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

Dodatkowe przypadki testowe

Dzięki uprzejmości Martin Büttner „s roztworu odniesienia (Należy pamiętać, że należy tylko jedno wyjście koordynować, nie wszystkie z nich):

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

To jest kod golfowy. Najkrótsze zgłoszenie wygrywa.

Rainbolt
źródło
6
Muszę to zrobić w O!
kirbyfan64sos

Odpowiedzi:

4

Pyth, 157 156 153 bajtów

=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

Możesz to wypróbować tutaj.

To był fajny problem dla golfa! Nadal przyzwyczajam się do Pytha, ale to naprawdę świetny język.

Rhyzomatic
źródło
1
Witamy w Pyth! Jeden golf, który widzę od razu: jeśli chcesz stworzyć 2-elementową listę / krotkę, użyj ,- właśnie po to jest.
isaacg
Jest więcej miejsca dla tego golfa thoughout kodu - (G%+H/N2b), (GH), (tZH).
isaacg,
12

Haskell, 394 bajty

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

Można go zdecydowanie zoptymalizować, a także po szybkim sprawdzeniu poprawności wygląda na to, że otrzymuję inne wyniki niż ten opublikowany. Wrócę i sprawdzę dokładniej mój kod, gdy będę miał więcej czasu ^^

Przy okazji niezły problem!

EDYCJA: zredagowałem moje rozwiązanie, biorąc pod uwagę cenne rady udzielone przez Zgarba . Teraz działa idealnie!

EDIT2: dzięki Nimi Zrobiłem kod jeszcze mniejsze. Teraz sprawdzam również parzyste i nieparzyste w jednej funkcji zamiast dwóch, co ogólnie zmniejsza liczbę z 446 do 414 bajtów.

EDYCJA 3: poprawiona z 414 do 400 bajtów. Dzięki nimi przez kolejne 2 bajtów, jesteś w ogniu! :)

EDIT4: 4 dodatkowych bajtów przez Nimi :)

basile-henry
źródło
2
Witamy w PPCG! Kilka szybkich wskazówek: 0<1jest krótszy niż otherwisei 0/=mod x ymożna go skrócić 0<mod x y. Również 1==mod(d)2jest odd di 0==mod(d)2jest even d.
Zgarb
@Zgarb fajne sztuczki, jestem naprawdę całkiem nowy w tym całym golfie. Jak jednak działa 0<1zamiast otherwisepracy?
basile-henry
1
Ponadto uważam, że twoja definicja liczb trójkątnych jest błędna (zakładam, że jest to funkcja t), ponieważ elem d[1..div(d*d-d)2]jest prawdziwa dla wszystkich d > 2.
Zgarb
otherwiseto po prostu inna nazwa dla True.
Zgarb
Dziękuję bardzo, tak, masz rację Próbowałem zbyt szybko wykonać liczby trójkątne ...
Basile-Henry
5

C, 425 396 bajtów

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);}

Istnieją pewne elementy, które można ulepszyć, ale działa to w przypadkach testowych .


Wyjaśnienie

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
źródło
3

Perl 5, 284 bajtów

@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 bajty plus 1 dla -Eflagi zamiast-e

Ten sam kod, ale z większą ilością białych znaków, więcej nawiasów i dłuższymi nazwami zmiennych:

@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";

Jestem przekonany, że można to jeszcze pograć w golfa.

msh210
źródło
2

JavaScript, 361 359 bajtów

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}

Kod używa przypisania Destrukturyzacja . Obecnie jest obsługiwany tylko w Firefoksie i Safari.

Wyjaśnienie

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
źródło