Bepergian O

26

Dunia adalah susunan sel lima demi lima. Itu membungkus di semua sisi. Ini dapat divisualisasikan seperti ...

XXXXX
XXXXX
XXOXX
XXXXX
XXXXX

Anda seorang O. Anda suka bepergian ke dunia, dan Anda melakukannya sesuai dengan aturan berikut (misalkan C menjadi hari ini):

  • Pada hari-hari utama , Anda merasa nostalgia. Kembali ke tempat Anda mulai kemarin.
  • Pada hari-hari aneh , Anda merasa rindu. Pindahkan satu langkah horizontal lebih dekat ke rumah, jika memungkinkan, dan satu langkah vertikal lebih dekat ke rumah, jika memungkinkan. Abaikan pembungkus dunia untuk tujuan menentukan kedekatan.
  • Pada bahkan hari, Anda merasa petualang. Pindahkan langkah C / 2 ke selatan.
  • Pada hari-hari persegi , Anda merasa neko. Pindah ke dinding timur.
  • Pada hari-hari Fibonacci , dunia meluas ke selatan dengan satu baris.
  • Pada hari-hari segitiga , dunia mengembang ke arah timur dengan satu kolom.

Jika dua atau lebih dari aturan di atas akan berlaku secara bersamaan, terapkan dalam urutan yang tercantum. Misalnya, pada hari perdana yang aneh, kembalilah ke tempat Anda mulai kemarin, dan kemudian selangkah lebih dekat ke rumah.

Anda tinggal di pusat dunia (awal), yaitu posisi (2,2), diindeks nol dari sudut Northwest. Anda memulai perjalanan Anda di sana pada hari pertama.

Memasukkan

Bilangan bulat tunggal, N.

Keluaran

Koordinat X dan Y Anda pada hari ke-N, diindeks nol dari sudut Northwest, dipisahkan oleh satu spasi.

Test Case Dengan Penjelasan

Diberikan input dari 3, output yang benar adalah:

2 3

Kita dapat mengerjakan ini satu hari pada suatu waktu. Mulai hari 1, kita perlu menerapkan langkah-langkah berikut:

  1. Aneh, kuadrat, Fibonacci, dan segitiga
  2. Perdana, datar, dan Fibonacci
  3. Perdana, ganjil, Fibonacci, dan segitiga

Dalam bentuk visual:

     Hari 1 Hari 2 Hari 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

Kasus Uji Tambahan

Courtesy of Martin Büttner 's solusi referensi (silakan perhatikan bahwa Anda harus keluaran hanya koordinat tunggal, tidak semua dari mereka):

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

Ini kode golf. Pengajuan terpendek menang.

Rainbolt
sumber
6
Saya perlu melakukan ini di O!
kirbyfan64sos

Jawaban:

4

Pyth, 157 156 153 byte

=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

Anda dapat mencobanya di sini.

Ini adalah masalah yang menyenangkan untuk bermain golf! Saya masih terbiasa dengan Pyth, tapi itu bahasa yang sangat bagus.

Berirama
sumber
1
Selamat datang di Pyth! Satu golf yang saya lihat langsung: Jika Anda ingin membuat daftar elemen 2 / tuple, gunakan ,- itulah gunanya .
isaacg
Ada lebih tempat untuk golf ini Sabbatarian kode - (G%+H/N2b), (GH), (tZH).
isaacg
12

Haskell, 394 byte

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

Ini pasti dapat dioptimalkan dan juga setelah dengan cepat memeriksa kebenarannya sepertinya saya mendapatkan hasil yang berbeda dari yang diposting. Saya akan kembali dan memeriksa kode saya secara lebih menyeluruh ketika saya memiliki lebih banyak waktu ^^

Masalah yang bagus!

EDIT: edit solusi saya dengan mempertimbangkan nasihat berharga yang diberikan oleh Zgarb . Sekarang bekerja dengan sempurna!

EDIT2: terima kasih kepada nimi saya telah membuat kode lebih kecil. Saya sekarang juga melakukan pemeriksaan genap dan ganjil dalam satu fungsi alih-alih dua fungsi yang secara keseluruhan menurunkan jumlah dari 446 menjadi 414 byte.

EDIT3: selanjutnya ditingkatkan dari 414 menjadi 400 byte. Terima kasih nimi untuk 2 byte lagi, Anda siap! :)

EDIT4: 4 byte lagi oleh nimi :)

basile-henry
sumber
2
Selamat datang di PPCG! Beberapa petunjuk singkat: 0<1lebih pendek dari otherwise, dan 0/=mod x ydapat disingkat 0<mod x y. Juga, 1==mod(d)2ini odd ddan 0==mod(d)2itu even d.
Zgarb
@Zgarb trik yang bagus, saya memang cukup baru dalam hal kode golf ini. Bagaimana 0<1bukannya otherwisebekerja?
basile-henry
1
Juga, saya pikir definisi Anda tentang angka segitiga salah (saya berasumsi itu ada dalam fungsinya t), karena elem d[1..div(d*d-d)2]berlaku untuk semua d > 2.
Zgarb
otherwisehanyalah nama lain untuk True.
Zgarb
Terima kasih banyak, ya Anda benar, saya mencoba melakukan angka segitiga terlalu cepat ...
basile-henry
5

C, 425 396 byte

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

Ada bagian ini yang bisa diperbaiki, tetapi berfungsi untuk kasus uji .


Penjelasan

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
sumber
3

Perl 5, 284 byte

@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, ditambah 1 untuk -Ebendera bukan-e

Kode yang sama tetapi dengan lebih banyak spasi putih, lebih banyak tanda kurung, dan nama variabel yang lebih panjang:

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

Saya yakin ini bisa di mainkan lebih lanjut.

msh210
sumber
2

Javascript, 361 359 byte

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}

Kode menggunakan tugas Destrukturisasi . Ini hanya didukung di Firefox dan Safari sekarang.

Penjelasan

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
sumber