O Viajante O

26

O mundo é uma matriz de cinco por cinco células. Envolve por todos os lados. Pode ser visualizado como ...

XXXXX
XXXXX
XXOXX
XXXXX
XXXXX

Você é um O. Você gosta de viajar pelo mundo e o faz de acordo com as seguintes regras (seja C o dia atual):

  • Nos dias nobres , você se sente nostálgico. Volte para onde você começou ontem.
  • Em dias ímpares , você sente saudades de casa. Mova um passo horizontal para mais perto de casa, se possível, e um passo vertical para mais perto de casa, se possível. Ignore a quebra do mundo com a finalidade de determinar a proximidade.
  • Em dias pares , você se sente aventureiro. Mova C / 2 passos para o sul.
  • Em dias quadrados , você se sente aventureiro. Mover para a parede leste.
  • Nos dias de Fibonacci , o mundo se expande para o sul em uma linha.
  • Em dias triangulares , o mundo se expande para o leste em uma coluna.

Se duas ou mais das regras acima se aplicarem ao mesmo tempo, aplique-as na ordem listada. Por exemplo, em um dia nobre ímpar, volte primeiro para onde você começou ontem e depois dê um passo mais perto de casa.

Você mora no centro do mundo (inicial), ou seja, posição (2,2), indexada a zero a partir do canto noroeste. Você começa sua jornada lá no primeiro dia.

Entrada

Um único inteiro, N.

Saída

Suas coordenadas X e Y no nono dia, indexadas a zero no canto noroeste, separadas por um único espaço.

Caso de teste com explicação

Dada uma entrada de 3, a saída correta é:

2 3

Podemos trabalhar com isso um dia de cada vez. A partir do dia 1, precisamos aplicar os seguintes movimentos:

  1. Ímpar, quadrado, Fibonacci e triangular
  2. Prime, even e Fibonacci
  3. Prime, ímpar, Fibonacci e triangular

Na forma visual:

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

Casos de teste adicionais

Cortesia de Martin Büttner 's solução de referência (por favor note que você deve saída de apenas uma única coordenada, não todos eles):

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

Isso é código de golfe. A finalização mais curta vence.

Rainbolt
fonte
6
Eu preciso fazer isso em O!
precisa saber é o seguinte

Respostas:

4

Pitão, 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

Você pode experimentá-lo aqui.

Este foi um problema divertido para o golfe! Ainda estou me acostumando com Pyth, mas é realmente uma ótima linguagem.

Rhyzomatic
fonte
1
Bem-vindo ao Pyth! Um golfe que vejo imediatamente: se você quiser fazer uma lista / tupla de 2 elementos, use ,- é para isso que serve.
Isaacg #
Há mais lugar para isso golfe thoughout o código - (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

Definitivamente, pode ser otimizado e também depois de verificar rapidamente a exatidão parece que estou obtendo resultados diferentes dos publicados. Voltarei e verificarei mais detalhadamente meu código quando tiver mais tempo ^^

Belo problema por sinal!

EDIT: editei minha solução levando em consideração os preciosos conselhos dados pelo Zgarb . Agora funciona perfeitamente!

EDIT2: graças ao nimi , tornei o código ainda menor. Agora, também estou fazendo as verificações de pares e ímpares em uma função, em vez de duas, que diminuem a contagem de 446 para 414 bytes.

EDIT3: aprimorado ainda mais de 414 a 400 bytes. Obrigado nimi por mais 2 bytes, você está pegando fogo! :)

EDIT4: mais 4 bytes por nimi :)

basile-henry
fonte
2
Bem-vindo ao PPCG! Algumas dicas rápidas: 0<1é mais curto que otherwisee 0/=mod x ypode ser reduzido para 0<mod x y. Além disso, 1==mod(d)2é odd de 0==mod(d)2é even d.
Zgarb 3/11
@ Zgarb truques agradáveis, eu sou realmente muito novo em toda essa coisa de código de golfe. Como funciona, em 0<1vez de otherwisetrabalhar?
basile-henry
1
Além disso, acho que sua definição de números triangulares está errada (suponho que esteja na função t), pois elem d[1..div(d*d-d)2]é verdade para todos d > 2.
Zgarb
otherwiseé apenas outro nome para True.
Zgarb
Muito obrigado, sim você está certo eu tentei fazer números triangulares muito rápido ...
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);}

Existem partes que podem ser melhoradas, mas funciona para os casos de teste .


Explicação

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
fonte
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, mais 1 para -Esinalizador em vez de-e

Mesmo código, mas com mais espaço em branco, mais parênteses e nomes de variáveis ​​mais longos:

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

Estou confiante de que isso pode ser jogado ainda mais.

msh210
fonte
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}

O código usa a atribuição de Reestruturação . É suportado apenas no Firefox e Safari no momento.

Explicação

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
fonte