Fizz Buzz pour les tortues

35

Description du problème

Imagine que tu es une tortue sur une grille. On vous donne deux nombres f et b , et vous faites face à l'est. Vous effectuez une marche à travers la grille, en comptant chacune des cellules rencontrées, selon les règles suivantes:

  • Par défaut, vous écrivez le nombre dans la cellule dans laquelle vous vous trouvez, puis vous avancez.
  • Si le nombre est divisible par f , vous écrivez Fdans la cellule dans laquelle vous vous trouvez, puis tournez à droite puis avancez.
  • Si le nombre est divisible par b , vous écrivez Bdans la cellule dans laquelle vous vous trouvez, puis tournez à gauche et avancez.
  • Si le nombre est divisible par f et b , vous écrivez FBdans la cellule où vous vous trouvez, puis avancez.
  • Si vous atteignez une place où vous êtes déjà allé, vous vous arrêtez.

Par exemple, suivre ces règles en utilisant f = 3 et b = 5 va générer un motif comme celui-ci:

    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

Le défi

Ecrivez un programme ou une fonction qui accepte deux nombres en entrée, correspondant à f et b , et produit en sortie le motif pour ces nombres donné par les règles ci-dessus.

Conditions de formatage:

  • Chaque cellule est large de deux caractères
  • Le contenu de la cellule est aligné à droite entre ces deux caractères.
  • Les cellules de la même ligne sont délimitées par un espace
  • La première colonne de cellules doit contenir une cellule non vide
  • Toutes les lignes doivent contenir des cellules non vides
  • Les espaces de fin ne sont pas obligatoires, mais autorisés
  • Cependant, la largeur totale de chaque ligne ne doit pas dépasser 3 fois le nombre de colonnes non vides

Votre code doit fonctionner pour les cas de test fournis.

Les failles standard sont interdites.

C'est du code golf; réponse la plus courte en octets gagne.

Cas de test

(f = 3, b = 5 cas répété ici à titre gracieux).

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
la source
1
Sommes-nous garantis que l'entrée conduira toujours à une collision avant d'atteindre 100?
Martin Ender
Oui. Plus généralement, tant que votre code fonctionne pour les cas de test fournis, vous pouvez continuer.
H Walters
1
Y a-t-il un endroit spécifique où vous commencez (la tortue)?
Kritixi Lithos
@KritixiLithos No. La gauche / haut / droite / bas de la grille sont définis par la façon dont la tortue se déplace, qui dépend de f et b.
H Walters
Est-ce que f et b sont toujours des entiers?
corvus_192

Réponses:

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`
`

Moins joué au 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`
}

Tester

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
la source
5

Python 2, 379 338 326 octets

Prend la saisie sous forme de deux nombres, séparés par une virgule Par exemple.4,5ou(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))

Version qui fonctionne si le chemin est plus long que 99, 384 343 330 octets

Affiche 2 chiffres significatifs.

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

Exemples:

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) (version tronquée)

                                              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: Merci à Jonathan Allan, Copper, et à shooqie pour m'avoir économisé plusieurs octets.

TFeld
la source
Hé, ces modèles N, 4N sont plutôt cool.
Steenbergh
Bon travail. Vous pouvez passer while((x,y)not in p.keys()):à while(x,y)not in p:et for x,y in p.keys():à for x,y in p. Vous pouvez passer l,r=i%b==0,i%f==0à l,r=i%b<1,i%f<1et d=(d+[0,1][r]-[0,1][l])%4à d=(d+r-l)%4. Vous pouvez changer s=[[`i`,'F'][r],' F'[r]+'B'][l].rjust(2);p[(x,y)]=spour p[(x,y)]=[[`i`,'F'][r],' F'[r]+'B'][l].rjust(2). Il peut y avoir plus
Jonathan Allan
Vous pouvez enregistrer un octet avec h*[' ']for x in rangeau lieu de [' ']*h for x in range. En outre, x+=[-1,1][d==1]peut être remplacé par x+=(d==1)*2-1et y+=[1,-1][d==2]peut être remplacé par y+=(d!=2)*2-1. Aussi, est f,b=inputttune faute de frappe?
Cuivre
p[(x,y)]=> p[x,y](pas sûr que cela fonctionne en Python 2, cependant)
shooqie
4

Excel VBA, 347 421 octets

Nouvelle version, pour répondre aux exigences d'espaces. Ne pas l'avoir dans ma première version était un oubli ou une partie de ma part, mais cela pèse lourdement sur le compte approximatif ... Il coupe et colle maintenant la plage utilisée dans la cellule 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

Voici l'ancienne version qui n'a pas déplacé le résultat final vers 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

Commence à 70, 70 (ou BR70 dans Excel) et marche autour. La fonction est appelée avec le fet bcomme paramètres:Call t(4, 16)

@ Neil vient de me sauver un tas d'octets, merci!

Steenbergh
la source
1
Si vous remplacez q=q-1par q=q+3et Select Case qavec Select Case q Mod 4alors vous pouvez vous débarrasser des deux déclarations précédentes.
Neil
However, the total width of each row must not exceed 3 times the number of non-empty columnsJe suppose que cela a été ajouté pour éviter de simplement installer une grande grille et commencer un peu loin de la frontière
Karl Napf
1
@KarlNapf corrigé.
Steenbergh
3

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

Subroutine qui accepte une entrée en tant que valeurs, F, Bet les sorties des cellules de l' Sheets(1)objet (qui est limitée à l' Sheets(1)objet pour enregistrer 2 octets)

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

Usage:

Call G(3, 4)
Taylor Scott
la source
2

C, 349 octets

Compile avec gcc (avec beaucoup d'avertissements)

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

Une version légèrement plus en retrait:

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

Voici une version de 364 octets qui gère les nombres supérieurs à 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
la source
1

Perl, 275 octets

L'indentation est fournie pour la lisibilité et ne fait pas partie du code.

($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
}

Explication:

Le code fonctionne en gardant une trace du hachage de tous les endroits où la tortue a été et de la valeur appropriée, stockée dans %m. Par exemple 3 5, dans , $m{0,2}contient 2et $m{1,-3}= 26. Il continue ainsi jusqu'à atteindre un endroit déjà défini. De plus, il garde une trace des limites actuelles du chemin de la tortue, en utilisant$a,$b,$c,$d comme maximum et minimum.

Une fois qu'il a atteint un endroit qu'il a déjà été, il imprime le chemin à l'aide des limites, le tout étant rempli d'espaces.

Il n'y a pas de limite à la taille du chemin, ni à la taille des nombres.

Gabriel Benamy
la source
1

PHP , 292 octets

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

Essayez-le en ligne!

Les retraits sont pour la clarté, pas comptés.

Suit à peu près le même algorithme que la réponse Perl. Suivre l'emplacement de la tortue dans un tableau 2D, $asuivre son orientation et $u, $d, $l, $rsuivre les limites pour l'impression. str_padnous permet de nous assurer que chaque entrée a exactement 3 espaces de large pour le formatage de l’impression.

Pour une raison quelconque, je ne peux pas comprendre, PHP ne me dérange pas de ne pas initialiser la moitié des variables à 0, mais gâche la mise en forme si je n'initialise pas les autres, même s'il traite généralement les variables non initialisées à 0 quand elles sont initiales utilisé. D'où le $x=$y=$u=$l=0bit.

Xanderhall
la source
0

Python 2 , 267 262 258 249 245 243 octets

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

Essayez-le en ligne!

Arfie
la source