The Traveling O


26

Il mondo è un array di cinque per cinque celle. Si avvolge su tutti i lati. Può essere visualizzato come ...

XXXXX
XXXXX
XXOXX
XXXXX
XXXXX

Sei una O. Ti piace viaggiare per il mondo e lo fai secondo le seguenti regole (lascia che C sia il giorno corrente):

  • Nei giorni migliori , ti senti nostalgico. Ritorna da dove hai iniziato ieri.
  • Nei giorni dispari , hai nostalgia di casa. Spostare un gradino orizzontale più vicino a casa, se possibile, e un gradino verticale più vicino a casa, se possibile. Ignora l'avvolgimento del mondo allo scopo di determinare la vicinanza.
  • Su persino giorni, vi sentite avventurosi. Sposta C / 2 gradini verso sud.
  • Nei giorni quadrati , ti senti avventuroso. Passa alla parete est.
  • Nei giorni di Fibonacci , il mondo si espande verso sud di una fila.
  • Nei giorni triangolari , il mondo si espande verso est di una colonna.

Se si applicano contemporaneamente due o più delle regole precedenti, applicarle nell'ordine elencato. Ad esempio, in uno strano giorno di prima serata, prima torna da dove hai iniziato ieri, quindi spostati di un passo verso casa.

Vivi al centro del mondo (iniziale), cioè posizione (2,2), indicizzato a zero dall'angolo nord-ovest. Inizi il tuo viaggio lì il primo giorno.

Ingresso

Un singolo intero, N.

Produzione

Le coordinate X e Y dell'ennesimo giorno, indicizzate a zero dall'angolo nord-ovest, separate da un singolo spazio.

Caso di prova con spiegazione

Dato un input di 3, l'output corretto è:

2 3

Possiamo lavorare su questo un giorno alla volta. A partire dal primo giorno, dobbiamo applicare le seguenti mosse:

  1. Dispari, quadrati, Fibonacci e triangolari
  2. Prime, pari e Fibonacci
  3. Prime, dispari, Fibonacci e triangolari

In forma visiva:

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

Casi di prova aggiuntivi

Per gentile concessione di Martin Büttner s' la soluzione di riferimento (si ricorda che si dovrebbe uscita una sola coordinata, non tutti):

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

Questo è il codice golf. Vince l'invio più breve.


6
Devo farlo in O!
Kirbyfan64sos,

Risposte:


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

Puoi provarlo qui.

Questo è stato un problema divertente per il golf! Mi sto ancora abituando a Pyth, ma è un linguaggio davvero eccezionale.


1
Benvenuto in Pyth! Un golf che vedo subito: se vuoi creare un elenco / tupla di 2 elementi, usa ,- ecco a cosa serve.
isaacg,

Ci sono più posto per questo campo da servite tutto il codice - (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

Può sicuramente essere ottimizzato e anche dopo aver verificato rapidamente la correttezza sembra che sto ottenendo risultati diversi da quello pubblicato. Tornerò e controllerò più a fondo il mio codice quando avrò più tempo ^^

Bel problema a proposito!

EDIT: ho modificato la mia soluzione tenendo conto dei preziosi consigli dati da Zgarb . Ora funziona perfettamente!

EDIT2: grazie a nimi ho reso il codice ancora più piccolo. Ora sto anche facendo i controlli di pari e dispari in una funzione invece di due, che nel complesso riduce il conteggio da 446 a 414 byte.

EDIT3: ulteriormente migliorato da 414 a 400 byte. Grazie nimi per altri 2 byte, sei in fiamme! :)

EDIT4: altri 4 byte di nimi :)


2
Benvenuti in PPCG! Un paio di suggerimenti rapidi: 0<1è più breve di otherwisee 0/=mod x ypuò essere abbreviato 0<mod x y. Inoltre, 1==mod(d)2è odd ded 0==mod(d)2è even d.
Zgarb,

@Zgarb bei trucchi, sono davvero abbastanza nuovo in questa faccenda del golf. Ma come funziona 0<1invece otherwise?
basile-henry,

1
Inoltre, penso che la tua definizione di numeri triangolari sia sbagliata (suppongo che sia nella funzione t), poiché elem d[1..div(d*d-d)2]è vera per tutti d > 2.
Zgarb,

otherwiseè solo un altro nome per True.
Zgarb,

Grazie mille, sì hai ragione, ho provato a fare numeri triangolari troppo velocemente ...
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);}

Ci sono parti che potrebbero essere migliorate, ma funziona per i casi di test .


Spiegazione

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 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 byte, più 1 per -Eflag anziché-e

Stesso codice ma con più spazi bianchi, più parentesi e nomi di variabili più lunghi:

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

Sono fiducioso che questo possa essere ulteriormente approfondito.


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}

Il codice usa l' assegnazione di Destructuring . Al momento è supportato solo da Firefox e Safari.

Spiegazione

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}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.