The Traveling O


26

Le monde est composé de cinq cellules sur cinq. Il s'enroule de tous les côtés. Il peut être visualisé comme ...

XXXXX
XXXXX
XXOXX
XXXXX
XXXXX

Vous êtes un O. Vous aimez voyager à travers le monde, et vous le faites selon les règles suivantes (que C soit le jour actuel):

  • Les jours de grande écoute , vous vous sentez nostalgique. Retournez là où vous avez commencé hier.
  • Les jours impairs , vous avez le mal du pays. Si possible, rapprochez-vous d'un pas horizontal de la maison et si possible d'un pas vertical. Ignorez l'emballage du monde dans le but de déterminer la proximité.
  • Les jours pairs , vous vous sentez aventureux. Déplacez C / 2 marches vers le sud.
  • Les jours carrés , vous vous sentez aventureux. Déplacez-vous vers le mur est.
  • Sur Fibonacci jours, le monde se développe vers le sud par une ligne.
  • Les jours triangulaires , le monde se développe vers l'est d'une colonne.

Si deux ou plusieurs des règles ci-dessus s'appliquent en même temps, appliquez-les dans l'ordre indiqué. Par exemple, un jour impair, revenez d'abord à l'endroit où vous avez commencé hier, puis rapprochez-vous de votre domicile.

Vous vivez au centre du monde (initial), c'est-à-dire la position (2,2), indexée zéro à partir du coin nord-ouest. Vous commencez votre voyage là-bas le premier jour.

Contribution

Un seul entier, N.

Sortie

Vos coordonnées X et Y le Nème jour, indexées zéro à partir du coin nord-ouest, séparées par un seul espace.

Cas de test avec explication

Étant donné une entrée de 3, la sortie correcte est:

2 3

Nous pouvons résoudre ce problème un jour à la fois. À partir du jour 1, nous devons appliquer les mouvements suivants:

  1. Impair, carré, Fibonacci et triangulaire
  2. Prime, pair et Fibonacci
  3. Premier, impair, Fibonacci et triangulaire

Sous forme visuelle:

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

Cas de test supplémentaires

Avec l' aimable autorisation de Martin Büttner de solution de référence (s'il vous plaît noter que vous devez sortie une seule coordonnée, pas tous):

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

C'est le golf de code. La soumission la plus courte gagne.


6
Je dois faire ça en O!
kirbyfan64sos

Réponses:


4

Pyth, 157 156 153 octets

=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

Vous pouvez l'essayer ici.

C'était un problème amusant pour le golf! Je m'habitue toujours à Pyth, mais c'est un très bon langage.


1
Bienvenue sur Pyth! Un golf que je vois tout de suite: si vous voulez faire une liste / tuple à 2 éléments, utilisez ,- c'est pour ça qu'il est là.
isaacg

Il y a plus de place pour ce golf thoughout le code - (G%+H/N2b), (GH), (tZH).
isaacg

12

Haskell, 394 octets

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

Il peut certainement être optimisé et également après avoir rapidement vérifié l'exactitude on dirait que j'obtiens des résultats différents de celui affiché. Je reviendrai et vérifierai plus en profondeur mon code quand j'aurai plus de temps ^^

Bon problème d'ailleurs!

EDIT: édité ma solution en tenant compte des précieux conseils donnés par Zgarb . Cela fonctionne maintenant parfaitement!

EDIT2: grâce à nimi, j'ai rendu le code encore plus petit. Je fais maintenant aussi les vérifications de pair et impair dans une fonction au lieu de deux, ce qui diminue globalement le nombre de 446 à 414 octets.

EDIT3: encore amélioré de 414 à 400 octets. Merci nimi pour encore 2 octets, tu es en feu! :)

EDIT4: 4 octets de plus par nimi :)


2
Bienvenue chez PPCG! Quelques conseils rapides: 0<1est plus court que otherwise, et 0/=mod x ypeut être raccourci 0<mod x y. Aussi, 1==mod(d)2est odd det 0==mod(d)2est even d.
Zgarb

@Zgarb nice tricks, je suis en effet assez nouveau dans ce domaine du golf. Comment ça marche 0<1au lieu de ça otherwise?
basile-henry

1
De plus, je pense que votre définition des nombres triangulaires est erronée (je suppose que c'est dans la fonction t), car elem d[1..div(d*d-d)2]c'est vrai pour tous d > 2.
Zgarb

otherwiseest juste un autre nom pour True.
Zgarb

Merci beaucoup, ouais tu as raison j'ai essayé de faire des nombres triangulaires trop vite ...
basile-henry

5

C, 425 396 octets

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

Il y a des parties à cela qui pourraient être améliorées, mais cela fonctionne pour les cas de test .


Explication

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 octets

@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 octets, plus 1 pour l' -Eindicateur au lieu de-e

Même code mais avec plus d'espace, plus de parenthèses et des noms de variables plus longs:

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

Je suis convaincu que cela peut être approfondi.


2

Javascript, 361 359 octets

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}

Le code utilise l' affectation Destructuration . Il n'est actuellement pris en charge que par Firefox et Safari.

Explication

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}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.