Fizz Buzz para las tortugas

35

Descripción del problema

Imagina que eres una tortuga en una cuadrícula. Te dan dos números f y b , y te enfrentas al este. Realiza una marcha a través de la cuadrícula, contando cada una de las celdas que encuentra, de acuerdo con las siguientes reglas:

  • De forma predeterminada, escribe el recuento en la celda en la que se encuentra y luego camina hacia adelante.
  • Si el recuento es divisible por f , escribe Fen la celda en la que se encuentra, luego gira a la derecha y luego camina hacia adelante.
  • Si el recuento es divisible por b , escribe Ben la celda en la que se encuentra, luego gira a la izquierda y luego camina hacia adelante.
  • Si el recuento es divisible por f y b , escribe FBen la celda en la que se encuentra y luego camina hacia adelante.
  • Si llegas a una plaza en la que ya has estado, te detienes.

Por ejemplo, seguir estas reglas usando f = 3 y b = 5 generará un patrón como este:

    F 28 29 FB  1  2  F
   26                 4
 F  B                 B  F
23                       7
22                       8
 F  B                 B  F
   19                11
    F 17 16 FB 14 13  F

El reto

Escriba un programa o función que acepte dos números como entrada, correspondientes a f y b , y produzca como salida el patrón para estos números dado por las reglas anteriores.

Requisitos de formato:

  • Cada celda tiene dos caracteres de ancho
  • El contenido de la celda está alineado a la derecha dentro de estos dos caracteres
  • Las celdas en la misma fila están delimitadas por un espacio
  • La primera columna de celdas debe contener una celda no vacía
  • Todas las filas deben contener celdas no vacías
  • No se requiere espacio en blanco al final, pero está permitido
  • Sin embargo, el ancho total de cada fila no debe exceder 3 veces el número de columnas no vacías

Su código debe funcionar para los casos de prueba proporcionados.

Las lagunas estándar no están permitidas.

Este es el código de golf; La respuesta más corta en bytes gana.

Casos de prueba

(f = 3, b = 5 caso repetido aquí como una conveniencia de cortesía).

f=3, b=5 ->
    F 28 29 FB  1  2  F
   26                 4
 F  B                 B  F
23                       7
22                       8
 F  B                 B  F
   19                11
    F 17 16 FB 14 13  F

f=4, b=10 ->
 F 25 26 27  F
23          29
22        1  2  3  F
21                 5
FB                 6
19                 7
18           B  9  F
17          11
 F 15 14 13  F

f=3, b=11 ->
 F 16 17  F
14       19
13     1  2  F
 F  B        4
   10        5
    F  8  7  F

f=5, b=9 ->
    F 41 42 43 44  1  2  3  4  F
   39                          6
   38                          7
   37                          8
 F  B                          B  F
34                               11
33                               12
32                               13
31                               14
 F 29 28  B              B 17 16  F
         26             19
          F 24 23 22 21  F

f=5, b=13 ->
    F 31 32 33 34  F
   29             36
   28        1  2  3  4  F
   27                    6
 F  B                    7
24                       8
23                       9
22              B 12 11  F
21             14
 F 19 18 17 16  F
H Walters
fuente
1
¿Estamos garantizados de que la entrada siempre conducirá a una colisión antes de llegar a 100?
Martin Ender el
Sí. En términos más generales, siempre que su código funcione para los casos de prueba proporcionados, estará listo.
H Walters el
1
¿Hay un lugar específico donde tú (la tortuga) comienza?
Kritixi Lithos
@KritixiLithos No. El lado izquierdo / superior / derecho / inferior de la cuadrícula se define por la forma en que viaja la tortuga, que depende de f y b.
H Walters el
¿F y B son siempre enteros?
corvus_192

Respuestas:

1

JavaScript (ES6), 230 240

(f,b)=>(d=>{for(g=[s=x=y=d];!(r=g[y]=g[y]||[])[x];d&1?d&2?y?--y:g=[,...g]:++y:d&2?x?--x:g=g.map(r=>[,...r]):++x)o=++s%f?'':(++d,'F'),s%b||(--d,o+='B'),r[x]=o||s})(0)||g.map(r=>[...r].map(c=>` ${c||' '}`.slice(-2)).join` `).join`
`

Menos golf

(f,b)=>{
  for(g=[s=x=y=d=0]; !(r = g[y]= g[y]||[])[x]; )
  {
    o=++s%f?'':(++d,'F')
    s%b||(--d,o+='B')
    r[x]=o||s,
    d&1
      ? d&2 ? y ? --y : g=[,...g] : ++y
      : d&2 ? x ? --x : g=g.map(r=>[,...r]) : ++x
  }
  return g.map(r=>[...r].map(c=>` ${c||' '}`.slice(-2)).join` `)
          .join`\n`
}

Prueba

F=
(f,b)=>(d=>{for(g=[s=x=y=d];!(r=g[y]=g[y]||[])[x];d&1?d&2?y?--y:g=[,...g]:++y:d&2?x?--x:g=g.map(r=>[,...r]):++x)o=++s%f?'':(++d,'F'),s%b||(--d,o+='B'),r[x]=o||s})(0)||g.map(r=>[...r].map(c=>` ${c||' '}`.slice(-2)).join` `).join`
`


function update()
{
  var i = I.value.match(/\d+/g)||[],f=+i[0],b=+i[1]
  O.textContent = (f>0 & b>0) ? F(f,b) : ''
}  

update()
<input id=I value="3 5" oninput="update()">
<pre id=O></pre>

edc65
fuente
5

Python 2, 379 338 326 bytes

Toma la entrada como dos números, separados por una coma. P.ej. 4,5o(4,5)

d=x=y=i=q=Q=e=E=0
p={}
f,b=input()
while(x,y)not in p:
 i+=1;l,r=i%b<1,i%f<1;d=(d+r-l)%4;p[x,y]=[[`i`,'F'][r],' F'[r]+'B'][l].rjust(2);q=min(q,x);Q=max(Q,x);e=min(e,y);E=max(E,y)
 if d%2:x+=(d==1)*2-1
 else:y+=(d!=2)*2-1
h,w=E-e+1,Q-q+1
A=[h*['  ']for x in' '*w]
for x,y in p:A[x-q][y-e]=p[x,y]
print'\n'.join(map(' '.join,A))

Versión que funciona si la ruta es más larga que 99, 384 343 330 bytes

Muestra 2 dígitos significativos.

d=x=y=i=q=Q=e=E=0
p={}
f,b=input()
while(x,y)not in p:
 i+=1;l,r=i%b<1,i%f<1;d=(d+r-l)%4;p[x,y]=[[`i%100`,'F'][r],' F'[r]+'B'][l].rjust(2);q=min(q,x);Q=max(Q,x);e=min(e,y);E=max(E,y)
 if d%2:x+=(d==1)*2-1
 else:y+=(d!=2)*2-1
h,w=E-e+1,Q-q+1
A=[h*['  ']for x in' '*w]
for x,y in p:A[x-q][y-e]=p[x,y]
print'\n'.join(map(' '.join,A))

Ejemplos:

input=(4,16)

 F 21 22 23  F
19          25
18          26
17          27
FB  1  2  3  F
15           5
14           6
13           7
 F 11 10  9  F

input=(6,7) (versión truncada)

                                              F 63 64 65 66 67 FB  1  2  3  4  5  F                                             
                               F 57 58 59 60  B                                   B  8  9 10 11  F                              
                              55                                                                13                              
                   F 51 52 53  B                                                                 B 15 16 17  F                  
                  49                                                                                        19                  
                  48                                                                                        20                  
          F 45 46  B                                                                                         B 22 23  F         
         43                                                                                                          25         
         42                                                                                                          26         
         41                                                                                                          27         
    F 39  B                                                                                                           B 29  F   
   37                                                                                                                      31   
   36                                                                                                                      32   
   35                                                                                                                      33   
   34                                                                                                                      34   
 F  B                                                                                                                       B  F
31                                                                                                                            37
30                                                                                                                            38
29                                                                                                                            39
28                                                                                                                            40
27                                                                                                                            41
FB                                                                                                                            FB
25                                                                                                                            43
24                                                                                                                            44
23                                                                                                                            45
22                                                                                                                            46
21                                                                                                                            47
 F  B                                                                                                                       B  F
   18                                                                                                                      50   
   17                                                                                                                      51   
   16                                                                                                                      52   
   15                                                                                                                      53   
    F 13  B                                                                                                           B 55  F   
         11                                                                                                          57         
         10                                                                                                          58         
         09                                                                                                          59         
          F 07 06  B                                                                                         B 62 61  F         
                  04                                                                                        64                  
                  03                                                                                        65                  
                   F 01 00 99  B                                                                 B 69 68 67  F                  
                              97                                                                71                              
                               F 95 94 93 92  B                                   B 76 75 74 73  F                              
                                              F 89 88 87 86 85 FB 83 82 81 80 79  F                                             

@Edit: Gracias a Jonathan Allan, Copper y shooqie por ahorrarme un montón de bytes.

TFeld
fuente
Je, esos patrones N, 4N son bastante geniales.
steenbergh el
Buen trabajo. Puedes cambiar while((x,y)not in p.keys()):a while(x,y)not in p:y for x,y in p.keys():para for x,y in p. Puedes cambiar l,r=i%b==0,i%f==0a l,r=i%b<1,i%f<1y d=(d+[0,1][r]-[0,1][l])%4para d=(d+r-l)%4. Puedes cambiar s=[[`i`,'F'][r],' F'[r]+'B'][l].rjust(2);p[(x,y)]=sa p[(x,y)]=[[`i`,'F'][r],' F'[r]+'B'][l].rjust(2). Puede haber más
Jonathan Allan, el
Puede guardar un byte con en h*[' ']for x in rangelugar de [' ']*h for x in range. Además, x+=[-1,1][d==1]se puede reemplazar con x+=(d==1)*2-1y y+=[1,-1][d==2]se puede reemplazar con y+=(d!=2)*2-1. Además, es f,b=inputttun error tipográfico?
Cobre
p[(x,y)]=> p[x,y](aunque no estoy seguro si funciona en Python 2)
shooqie
4

Excel VBA, 347 421 bytes

Nueva versión, para hacer frente a los requisitos de espacios en blanco. No tener esto en mi primera versión fue un descuido de mi parte, pero esto tiene su efecto en el bytecount ... Ahora corta y pega el rango utilizado a la celda A1.

Sub t(f, b)
x=70:y=70:Do:s=s+ 1
If Cells(y,x).Value<>"" Then
ActiveSheet.UsedRange.Select:Selection.Cut:Range("A1").Select:ActiveSheet.Paste:Exit Sub
End If
If s Mod f=0 Then Cells(y,x).Value="F":q=q+1
If s Mod b=0 Then Cells(y,x).Value=Cells(y,x).Value & "B":q=q+3
If Cells(y,x).Value="" Then Cells(y,x).Value=s
Select Case q Mod 4
Case 0:x=x+1
Case 1:y=y+1
Case 2:x=x-1
Case 3:y=y-1
End Select:Loop:End Sub

Aquí está la versión anterior que no movió el resultado final a A1

Sub t(f,b)
x=70:y=70:Do:s=s+1:if Cells(y,x).Value<>"" then exit sub
If s Mod f=0 Then
Cells(y,x).Value="F":q=q+1
End If
If s Mod b=0 Then
Cells(y,x).Value=Cells(y,x).Value & "B":q=q+3
End If
If Cells(y,x).Value="" Then Cells(y,x).Value=s
Select Case q mod 4
Case 0:x=x+1
Case 1:y=y+1
Case 2:x=x-1
Case 3:y=y-1
End Select:Loop:End Sub

Comienza en 70, 70 (o BR70 en Excel) y lo rodea. La función se llama con los parámetros fy bcomo:Call t(4, 16)

@Neil me acaba de salvar un montón de bytes, ¡gracias!

Steenbergh
fuente
1
Si reemplaza q=q-1con q=q+3y Select Case qcon Select Case q Mod 4, puede deshacerse de las dos declaraciones anteriores.
Neil
However, the total width of each row must not exceed 3 times the number of non-empty columnsSupongo que esto se agregó para evitar simplemente configurar una gran cuadrícula y comenzar un poco lejos de la frontera
Karl Napf, el
1
@KarlNapf Fijo.
steenbergh el
3

Excel VBA, 284 278 277 261 259 255 254 253 251 Bytes

Subrutina que toma la entrada como valores, F, By salidas a las células en el Sheets(1)objeto (que se limita a la Sheets(1)objeto para guardar 2 Bytes)

Sub G(F,B)
Set A=Sheet1
R=99:C=R
Do
I=I+1
Y=Cells(R,C)
If Y<>""Then A.UsedRange.Cut:[A1].Select:A.Paste:End
If I Mod F=0Then Y="F":J=J+1
If I Mod B=0Then Y=Y+"B":J=J+3
Cells(R,C)=IIf(Y="",i,Y)
K=J Mod 4
If K Mod 2Then R=R-K+2 Else C=C+1-K
Loop
End Sub

Uso:

Call G(3, 4)
Taylor Scott
fuente
2

C, 349 bytes

Compila con gcc (con muchas advertencias)

#define z strcpy(G[x][y],
char G[99][99][3];d=3,x=49,y=49,i=1,q,s=99,t,u=99,v;F(f,b){for(;!*G[x][y];i++){q=(!(i%f))<<1|!(i%b);q==3&&z"FB");if(q==2)z"F"),d=(d+3)%4;if(q==1)z"B"),d=(d+1)%4;!q&&sprintf(G[x][y],"%d",i);if(d%2)x+=d-2;else y+=d-1;s=s>x?x:s;t=t<x?x:t;u=u>y?y:u;v=v<y?y:v;}for(y=u;y<=v;puts(""),y++)for(x=s;x<=t;x++)printf("%2s ",G[x][y]);}

Una versión ligeramente más sangrada:

#define z strcpy(G[x][y],
char G[99][99][3];
d=3,x=49,y=49,i=1,q,s=99,t,u=99,v;

F(f,b)
{
    for(;!*G[x][y];i++)
    {
        q=(!(i%f))<<1|!(i%b);
        q==3&&z"FB");
        if(q==2)z"F"),d=(d+3)%4;
        if(q==1)z"B"),d=(d+1)%4;
        !q&&sprintf(G[x][y],"%d",i);
        if(d%2)x+=d-2;else y+=d-1;
        s=s>x?x:s;t=t<x?x:t;u=u>y?y:u;v=v<y?y:v;
    }
    for(y=u;y<=v;puts(""),y++)for(x=s;x<=t;x++)printf("%2s ",G[x][y]);
}

Aquí hay una versión de 364 bytes que maneja números mayores que 100

#define g G[x][y]
#define z strcpy(g,
char G[99][99][9];d=3,x=49,y=49,i=1,q,s=99,t,u=99,v;F(f,b){for(;!*g;i++){q=(!(i%f))<<1|!(i%b);q==3&&z"FB");if(q==2)z" F"),d=(d+3)%4;if(q==1)z" B"),d=(d+1)%4;!q&&sprintf(G[x][y],"%2d",i);if(d%2)x+=d-2;else y+=d-1;s=s>x?x:s;t=t<x?x:t;u=u>y?y:u;v=v<y?y:v;}for(y=u;y<=v;puts(""),y++)for(x=s;x<=t;x++)printf("%2s ",g+strlen(g)-2);}
Jerry Jeremiah
fuente
1

Perl, 275 bytes

La sangría se proporciona para facilitar la lectura y no forma parte del código.

($f,$e)=@ARGV;
for($i=$x=1,$y=0;!$m{"$x,$y"};$i++){
    ($g,$m{"$x,$y"})=$i%$e&&$i%$f?($g,$i):$i%$f?($g+1,B):$i%$e?($g-1,F):($g,FB);
    ($g%=4)%2?($y+=$g-2):($x+=1-$g);
    ($a>$x?$a:$b<$x?$b:$x)=$x;
    ($c>$y?$c:$d<$y?$d:$y)=$y
}
for$k($c..$d){
    printf("%*s",1+length$i,$m{"$_,$k"})for$a..$b;
    say
}

Explicación:

El código funciona al realizar un seguimiento de un hash de todos los lugares donde ha estado la tortuga y el valor apropiado almacenado %m. Por ejemplo: en 3 5, $m{0,2}contiene 2, y $m{1,-3}= 26. Continúa de esta manera hasta que alcanza un lugar que ya ha sido definido. Además, realiza un seguimiento de los límites actuales del camino de la tortuga, utilizando $a,$b,$c,$dcomo máximos y mínimos.

Una vez que llega a un lugar donde ya ha estado, imprime el camino utilizando los límites, todo relleno de espacios.

No hay límite para el tamaño de la ruta, ni el tamaño de los números.

Gabriel Benamy
fuente
1

PHP , 292 bytes

for($x=$y=$u=$l=0;!$q[$x][$y];$s="") {
    ++$i%$argv[1]?:$a-=1+$s="F";
    $i%$argv[2]?:$a+=1+$s.="B";
    $q[$x][$y]=$s?:$i;
    $z=[1,-2,-1,2][$a=($a+4)%4];
    $y+=$z%2;
    $x+=~-$z%2;
    $u>$y?$u=$y:$d>$y?:$d=$y;
    $l>$x?$l=$x:$r>$x?:$r=$x;
}
for(;$l++<=$r;print"\n")for($j=$u-1;$j++<=$d;)echo str_pad($q[$l-1][$j],3," ",0);

Pruébalo en línea!

Las sangrías son para mayor claridad, no cuentan.

Sigue el mismo algoritmo que la respuesta de Perl. Rastree dónde ha estado la tortuga en una matriz 2D, $arastrea hacia dónde se enfrenta la tortuga y $u, $d, $l, $rrastree los límites para imprimir. str_padnos permite asegurarnos de que cada entrada tenga exactamente 3 espacios de ancho para el formato de impresión.

Por alguna razón no puedo entender, a PHP no le importa que no inicialice la mitad de las variables a 0, pero arruina el formato si no inicializo otras, aunque generalmente trata las variables no inicializadas como 0 cuando son las primeras usado. De ahí el $x=$y=$u=$l=0bit.

Xanderhall
fuente
0

Python 2 , 267 262 258 249 245 243 bytes

f,b=input()
X=x=Y=y=i=p=0
g={}
S=sorted
while(p in g)<1:i+=1;g[p]='F'[i%f:]+'B'[i%b:]or`i`;p+=1j**(i/f-i/b);X,_,x=S([X,x,int(p.real)]);Y,_,y=S([Y,y,int(p.imag)])
j=Y
while j<=y:print' '.join(g.get(i+j*1j,'').rjust(2)for i in range(X,x+1));j+=1

Pruébalo en línea!

Arfie
fuente