The Travelling O


26

โลกเป็นเซลล์ห้าถึงห้าเซลล์ มันล้อมรอบทุกด้าน สามารถมองเห็นได้เหมือน ...

XXXXX
XXXXX
XXOXX
XXXXX
XXXXX

คุณเป็น O. คุณชอบเดินทางไปทั่วโลกและทำตามกฎต่อไปนี้ (ปล่อยให้ C เป็นวันปัจจุบัน)

  • ในวันสำคัญคุณรู้สึกถึงความคิดถึง กลับไปยังที่ที่คุณเริ่มเมื่อวานนี้
  • ในวันที่แปลกคุณรู้สึกคิดถึงบ้าน ย้ายหนึ่งก้าวเข้าใกล้บ้านถ้าเป็นไปได้และก้าวหนึ่งในแนวตั้งเข้าใกล้บ้านถ้าเป็นไปได้ ไม่สนใจการล้อมรอบโลกเพื่อจุดประสงค์ในการกำหนดความใกล้ชิด
  • เมื่อวันที่แม้กระทั่งวันที่คุณรู้สึกรักการผจญภัย ย้าย C / 2 ขั้นตอนไปทางใต้
  • ในตารางวันคุณรู้สึกถึงการผจญภัย ย้ายไปที่ผนังด้านตะวันออก
  • ในวันที่ฟีโบนัชชีโลกขยายไปทางทิศใต้หนึ่งแถว
  • ในวันที่เป็นรูปสามเหลี่ยมโลกจะขยายออกไปทางทิศตะวันออกหนึ่งคอลัมน์

หากมีกฎสองข้อขึ้นไปที่จะใช้ในเวลาเดียวกันให้ใช้กฎเหล่านี้ตามลำดับที่แสดงไว้ ตัวอย่างเช่นในวันสำคัญ ๆ ให้กลับไปที่จุดเริ่มต้นเมื่อวานนี้ก่อนแล้วค่อยขยับเข้าไปใกล้บ้านคุณหนึ่งก้าว

คุณอาศัยอยู่ที่จุดศูนย์กลางของโลก (เริ่มต้น) เช่นตำแหน่ง (2,2) ซึ่งไม่มีดัชนีจากมุมตะวันตกเฉียงเหนือ คุณเริ่มต้นการเดินทางที่นั่นในวันแรก

อินพุต

จำนวนเต็มเดียว, N

เอาท์พุต

พิกัด X และ Y ของคุณในวันที่ N ซึ่งจัดทำดัชนีเป็นศูนย์จากมุมตะวันตกเฉียงเหนือคั่นด้วยช่องว่างเดียว

กรณีทดสอบพร้อมคำอธิบาย

กำหนดอินพุตของ3เอาต์พุตที่ถูกต้องคือ:

2 3

เราสามารถทำงานได้ตลอดเวลาในแต่ละวัน เริ่มตั้งแต่วันที่ 1 เราต้องใช้การเคลื่อนไหวต่อไปนี้:

  1. คี่สแควร์ฟีโบนักชีและสามเหลี่ยม
  2. นายกแม้แต่และฟีโบนักชี
  3. นายกแปลก Fibonacci และสามเหลี่ยม

ในรูปแบบภาพ:

     วันที่ 1 วันที่ 2 วันที่ 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

กรณีทดสอบเพิ่มเติม

มารยาทของมาร์ตินBüttner 's วิธีการแก้ปัญหาการอ้างอิง (โปรดทราบว่าคุณควรส่งออกเพียงคนเดียวการประสานงานไม่ทั้งหมดของพวกเขา):

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

นี่คือรหัสกอล์ฟ การส่งที่สั้นที่สุดชนะ


6
ฉันต้องทำสิ่งนี้ใน O!
kirbyfan64sos

คำตอบ:


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

คุณสามารถลองได้ที่นี่

นี่เป็นปัญหาที่สนุกสำหรับกอล์ฟ! ฉันยังคงคุ้นเคยกับ Pyth อยู่ แต่มันเป็นภาษาที่ยอดเยี่ยมจริงๆ


1
ยินดีต้อนรับสู่ Pyth! หนึ่งกอล์ฟที่ฉันเห็นทันที: ถ้าคุณต้องการสร้างรายการองค์ประกอบ / ทูเพิลให้ใช้,- นั่นคือสิ่งที่มันมีอยู่
isaacg

มีสถานที่มากขึ้นสำหรับกีฬากอล์ฟนี้ thoughout รหัสมี (G%+H/N2b)- (GH), (tZH),
isaacg

12

Haskell ขนาด 394 ไบต์

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

สามารถปรับให้เหมาะสมและแน่นอนหลังจากตรวจสอบความถูกต้องได้อย่างรวดเร็ว ดูเหมือนว่าฉันได้รับผลลัพธ์ที่แตกต่างจากที่โพสต์. ฉันจะกลับมาตรวจสอบรหัสของฉันให้ละเอียดยิ่งขึ้นเมื่อฉันมีเวลามากขึ้น ^^

เป็นปัญหาที่ดีโดยวิธี!

แก้ไข: แก้ไขสละวิธีการแก้ปัญหาของฉันเข้าไปในบัญชีคำแนะนำอันมีค่าที่กำหนดโดยZgarb มันทำงานได้อย่างสมบูรณ์แบบ!

EDIT2: ขอบคุณnimiฉันทำให้รหัสเล็กลง ตอนนี้ฉันกำลังตรวจสอบเลขคี่และคู่ในฟังก์ชั่นหนึ่งแทนที่จะเป็นสองฟังก์ชันซึ่งโดยรวมจะลดจำนวนลงจาก 446 เป็น 414 ไบต์

EDIT3: ปรับปรุงเพิ่มเติมจาก 414 เป็น 400 ไบต์ ขอบคุณnimiสำหรับอีก 2 ไบต์คุณอยู่ในไฟ! :)

EDIT4: อีก 4 ไบต์โดยnimi :)


2
ยินดีต้อนรับสู่ PPCG! คำแนะนำ0<1สั้น ๆ: สั้นกว่าotherwiseและ0/=mod x yสามารถย่อให้สั้นลง0<mod x yได้ นอกจากนี้ยัง1==mod(d)2เป็นodd dและเป็น0==mod(d)2 even d
Zgarb

@Zgarb ลูกเล่นที่ดีจริงๆฉันค่อนข้างใหม่ในเรื่องของกอล์ฟทั้งหมดนี้ แต่0<1แทนที่จะotherwiseทำงานอย่างไร
บาซิลเฮนรี่

1
นอกจากนี้ผมคิดว่าคำนิยามของหมายเลขสามเหลี่ยมที่เป็นธรรม (ฉันสมมติว่าในฟังก์ชั่นt) เนื่องจากเป็นความจริงทั้งหมดelem d[1..div(d*d-d)2] d > 2
Zgarb

otherwiseTrueเป็นเพียงชื่ออีก
Zgarb

ขอบคุณมากครับคุณขวาฉันพยายามทำตัวเลขสามเหลี่ยมเร็วเกินไป ...
Basile-henry

5

C, 425 396 ไบต์

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

มีชิ้นส่วนที่อาจจะดีขึ้นมี แต่การทำงานสำหรับกรณีทดสอบ


คำอธิบาย

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

3

Perl 5, 284 ไบต์

@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 ไบต์บวก 1 สำหรับการ-Eตั้งค่าสถานะแทน-e

รหัสเดียวกัน แต่มีช่องว่างมากขึ้นวงเล็บเพิ่มเติมและชื่อตัวแปรที่ยาวกว่า:

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

ฉันมั่นใจว่าจะสามารถตีกอล์ฟต่อไปได้


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}

การใช้รหัสที่ได้รับมอบหมาย Destructuring รองรับเฉพาะใน Firefox และ Safari เท่านั้น

คำอธิบาย

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}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.