Fizz Buzz для черепах


35

опис проблеми

Уявіть, що ви черепаха на сітці. Вам дано два числа f і b , і ви звернені на схід. Ви здійснюєте марш через сітку, підраховуючи кожну зі стільникових клітин, відповідно до таких правил:

  • За замовчуванням ви записуєте підрахунок до комірки, в якій перебуваєте, а потім йдете вперед.
  • Якщо підрахунок ділиться на f , ви пишете Fв клітинку, в якій перебуваєте, потім поверніть праворуч, а потім підете вперед.
  • Якщо підрахунок ділиться на b , ви записуєте Bв клітинку, в якій ви перебуваєте, потім повертаєте ліворуч і рухаєтесь вперед.
  • Якщо підрахунок ділиться як на f, так і на b , ви записуєте FBв клітинку, в якій ви перебуваєте, а потім йдіть вперед.
  • Якщо ви дістанетесь до площі, на якій ви вже були, ви зупиняєтесь.

Наприклад, дотримуючись цих правил, використовуючи 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 і b , і видає як вихід шаблон для цих чисел, заданий правилами вище.

Вимоги до форматування:

  • Кожна клітинка має два символи
  • Вміст комірок правильно вирівняний у межах цих двох символів
  • Клітини в одному ряду відмежовані пробілом
  • Перший стовпець комірок повинен містити не порожню комірку
  • Усі рядки повинні містити порожні комірки
  • Пробіл пробігу не потрібно, але дозволений
  • Однак загальна ширина кожного ряду не повинна перевищувати 3-кратну кількість стовпців, що не пустують

Ваш код повинен працювати для наданих тестових випадків.

Стандартні лазівки заборонені.

Це кодовий гольф; найкоротша відповідь у байтах виграє.

Тестові справи

(f = 3, b = 5 випадків, повторених тут як зручність ввічливості).

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

1
Чи гарантуємо нам, що вхід завжди призведе до зіткнення, перш ніж ми досягнемо 100?
Мартін Ендер

Так. Загалом, до тих пір, поки ваш код працює для наданих тестових випадків, ви готові йти.
H Walters

1
Чи є певне місце, яке ви (черепаха) починаєте?
Kritixi Lithos

@KritixiLithos. Ні. Лівий / верхній / правий / нижній частині сітки визначається тим, як рухається черепаха, що залежить від f і b.
H Walters

Чи завжди f і b цілі числа?
corvus_192

Відповіді:


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

Менше гольфу

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

Тест

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>


5

Python 2, 379 338 326 байт

Вводиться як два числа, розділені комою. Напр. 4,5або(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))

Версія, яка працює, якщо шлях довший 99, 384 343 330 байт

Показує 2 значущих цифри.

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

Приклади:

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) (обрізна версія)

                                              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: Завдяки Джонатану Аллану, Меді та шокі за економію мені купою байтів.


Хе, ці N, 4N візерунки досить круті.
steenbergh

Хороша робота. Ви можете змінити , while((x,y)not in p.keys()):щоб while(x,y)not in p:і for x,y in p.keys():в for x,y in p. Ви можете змінити , l,r=i%b==0,i%f==0щоб l,r=i%b<1,i%f<1і d=(d+[0,1][r]-[0,1][l])%4в d=(d+r-l)%4. Ви можете змінити s=[[`i`,'F'][r],' F'[r]+'B'][l].rjust(2);p[(x,y)]=sна p[(x,y)]=[[`i`,'F'][r],' F'[r]+'B'][l].rjust(2). Може бути і більше
Джонатан Аллан

Ви можете зберегти байт за допомогою, h*[' ']for x in rangeа не [' ']*h for x in range. Також x+=[-1,1][d==1]можна замінити на x+=(d==1)*2-1, а y+=[1,-1][d==2]можна замінити y+=(d!=2)*2-1. Також, f,b=inputttдрукарська помилка?
Мідь

p[(x,y)]=> p[x,y](не впевнений, чи працює він у Python 2, проте)
shooqie

4

Excel VBA, 347 421 байт

Нова версія для вирішення вимог пробілу. Відсутність цього в моїй першій версії була моїм наглядом, але це спричиняє свою кількість в рахунку ... Тепер він скорочує і вставляє використаний діапазон у комірку 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

Ось стара версія, до якої не змінено кінцевий результат 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

Починається в 70, 70 (або BR70 в Excel) і ходить по ньому. Функція викликається за допомогою параметрів fі bяк:Call t(4, 16)

@Neil щойно врятував мені купу байтів, дякую!


1
Якщо ви заміните q=q-1на q=q+3і Select Case qна, Select Case q Mod 4ви можете позбутися попередніх двох тверджень.
Ніл

However, the total width of each row must not exceed 3 times the number of non-empty columnsЯ думаю, це було додано, щоб просто не встановити велику сітку і почати десь далеко від кордону
Karl Napf

1
@KarlNapf Виправлено.
steenbergh

3

Excel VBA, 284 278 277 261 259 255 254 253 251 байт

Subпідпрограма , яка приймає вхідний сигнал в вигляді значень, F, Bі виходи до клітин на Sheets(1)об'єкт (який обмежується Sheets(1)об'єкта , щоб зберегти 2 байти)

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

Використання:

Call G(3, 4)

2

С, 349 байт

Компілюється з gcc (з великою кількістю попереджень)

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

Трохи більш розрізнена версія:

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

Ось версія з 364 байтами, яка обробляє числа, більші за 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);}

1

Perl, 275 байт

Відступ передбачений для читабельності і не є частиною коду.

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

Пояснення:

Код працює, відслідковуючи хеш усіх місць, де перебувала черепаха, та відповідне значення, яке зберігається в %m. Наприклад: в 3 5, $m{0,2}містить 2і $m{1,-3}= 26. Це продовжується таким чином, поки не досягне місця, яке вже було визначене. Крім того, він відстежує поточні межі шляху черепашки, використовуючи $a,$b,$c,$dяк максимум і мінімум.

Як тільки він дістається до місця, яке вже було, він друкує шлях, використовуючи межі, і все пробіли.

Існує не обмеження ні розміром шляху, ні розміром чисел.


1

PHP , 292 байти

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

Спробуйте в Інтернеті!

Відступи для наочності не враховуються.

Дотримується того ж алгоритму, що і відповідь Perl. Відстежуйте, де черепаха перебуває у двовимірному масиві, $aвідстежуйте, де знаходиться черепаха, і $u, $d, $l, $rвідслідковуйте межі друку. str_padдозволяє нам переконатися, що для формату друку для кожного запису є рівно 3 простори.

Я чомусь не можу зрозуміти, PHP не проти мені не ініціалізувати половину змінних до 0, але виконує форматування, якщо я не ініціалізую інших, хоча зазвичай неініціалізовані змінні трактують як 0, коли вони вперше б / в. Звідси $x=$y=$u=$l=0шматочок.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.