Лицар на Римі - Грим


48

Вступ

Арон Німзович був провідним майстром шахів та впливовим шаховим письменником.

У своїй книзі «Моя система» в першій главі йдеться про важливість центру та про те, чому слід домінувати над ним. Проста причина полягає в тому, що у ваших фігур більше можливих прямих наступних рухів, перебуваючи в центрі, що знову дає гравцеві більше сили.

Це стає дуже зрозумілим при перегляді різних позицій лицаря та його потенційних наступних рухів (показаних рожевим кольором) на порожній дошці:

введіть тут опис зображення

Об'єктивна

Оцініть кількість потенційних прямих наступних рухів лицаря на порожній дошці, виходячи з його положення.

Вхідні характеристики

Позиція лицаря.

Спочатку х (стовпець), а потім у (рядок). 0 0- лівий нижній кут.

Для простоти я змінив ярлики шахової дошки лише на цифри. У наших прикладах та тестових випадках ми використовуємо індекс на основі 0, але ви можете вільно використовувати індекс на основі 1.

Ви можете використовувати будь-який тип можливих вхідних форматів, масив, аргументи функції тощо.

Вихідні характеристики

Кількість потенційних прямих наступних рухів для лицаря на порожній дошці.

Випробування

3 4 => 8
4 6 => 6
7 7 => 2
1 0 => 3

У тестових випадках використовується індекс на основі 0. Повна сітка значень:

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2

9
Приємний перший виклик! :-)
Луїс Мендо

14
"Лицар на

2
@stacey Ваш коментар був би чудовим заголовком для цієї головоломки :)
starcorder

6
Тепер для справді важкого питання: Чи червоні лицарі на вищезазначених зображеннях однакового кольору?
mbomb007

Відповіді:


25

Python 2 , 35 байт

lambda x,y:50/(8+x*x/7-x+y*y/7-y)-4

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


Python 2 , 39 байт

lambda x,y:50/(8-x*(7-x)/5-y*(7-y)/5)-4

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

Бере входи 0-індексованими.

Вираз x*(7-x)/5приймає значення координат 0..7до

[0, 1, 2, 2, 2, 2, 1, 0]

( min(x,7-x,2)робить те саме, але довше.) Підсумовуючи це для xі yдає правильний зразок, але з неправильними числами

0 1 2 2 2 2 1 0
1 2 3 3 3 3 2 1
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
1 2 3 3 3 3 2 1
0 1 2 2 2 2 1 0

(Дивіться рішення Ніла для кращих міркувань щодо того, чому це дає правильну схему.)

Нарешті, відображення a -> 50/(8-a)-4з поділом на підлогу дає правильні значення

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2

Альтернативне рівномірне рішення з 1-індексованими входами:

lambda x,y:(x*(9-x)/6+y*(9-y)/6)**2/6+2

(7-a)*a/5на 3 байти коротше min(a,7-a,2).
Ніл

1
*lнасправді коштує вам байт загалом, lambda a,b:"23468"[(7-a)*a/5+(7-b)*b/5]становить лише 41 байт.
Ніл

@Neil Я щойно знайшов те саме, з x*(9-x)/6індексом.
xnor

1
Чому ви не використовуєте, <strike>як усі, щоб продемонструвати прогрес у гольфі?
Insane

4
@Insane Я думаю, що це виглядає некрасиво і насправді не допомагає. Код є важливою справою, і кожен, хто хоче побачити його еволюцію, все ще повинен заглянути в історію редагування. Коли мій старий код досить інший, щоб його варто було показати, я показую такі версії, як тут . Але в цьому питанні це все незначні вдосконалення однієї і тієї ж стратегії, тому я вважаю більш чистим лише згадування різних можливостей.
xnor

17

MATL , 17 14 13 12 байт

Дякуємо @Neil за 1 байт!

8:HZ^ZP5X^=s

Введення на основі 1.

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

Пояснення

Це обчислює евклідову відстань від входу до кожної з 64 позицій на шаховій дошці і знаходить, скільки цих значень дорівнює квадратному кореню 5.

Оскільки координати є цілими значеннями, ми можемо бути впевнені, що два значення з плаваючою комою, що представляють квадратний корінь 5 (той, що обчислюється з координат і що обчислюється безпосередньо), дійсно однакові.

8:      % Push array [1 2 ... 8]
H       % Push 2
Z^      % Cartesian power. Gives 2D array [1 1; 1 2; ... 1 8; 2 1; ... 8 8]     
ZP      % Implicit input. Compute Euclidean distances, considering each row as a point
5X^     % Square root of 5
=s      % Compute how many squared distances equal sqrt(5). Implicit display

1
Вражаюче і дякую за пояснення
зірковий запис

1
Якщо порівнювати площу кореня квадрата від 5 до 5 не вдається через помилки округлення, чи можна принаймні порівняти квадратний корінь 5 з квадратним коренем 5?
Ніл

@Neil Дякую за ідею! Так, оскільки обчислення ведуться з цілими числами, я можу бути впевнений, що два "корені 5" є однаковим doubleчислом. Ant це рятує байт
Луїс Мендо

15

Mathematica 63 43 байт

З збереженими 20 байтами завдяки пропозиціям Мартіна Ендера!

EdgeCount[8~KnightTourGraph~8,#+1+8#2/<->_]&

Наведене вище знаходить кількість квадратів, що знаходяться на 1 хоп від даної клітинки на повній графіці екскурсії лицарів.


g=KnightTourGraph[8,8,VertexLabels->"Name",Axes->True]

відображає повну графіку подорожі лицаря, назви вершин та координати. Зауважте, що Mathematica за замовчуванням застосовує одноосновне індексування координат.

графік


#+1+8#2&[r,f]converts повертає вершину, відповідну квадрату за рангом (рядок), rі файлом (стовпцем) f, використовуючи значення введення в якості нуля.

Наприклад, #+1+8#2&[2,1]повертає 11.


EdgeCount дає кількість ребер у графіку сусідства.


Краї для 2-го рангу, файл 1 (квадрат 11):

IncidenceList[8~KnightTourGraph~8, 8 #2 + # + 1] &[2, 1]

(*{1 <-> 11, 5 <-> 11, 11 <-> 17, 11 <-> 21, 11 <-> 26, 11 <-> 28}*)

Виділені краї:

HighlightGraph[g, {1, 5, 11, 17, 21, 26, 28, Style[1 <-> 11, Thick, Blue], Style[5 <-> 11, Thick, Blue], Style[11 <-> 17, Thick, Blue], Style[11 <-> 21, Thick, Blue], Style[11 <-> 26, Thick, Blue], Style[11 <-> 28, Thick, Blue]},GraphHighlightStyle -> "DehighlightFade", PlotRangePadding -> .5]

виділити


Спосіб 2: Евклідова відстань

70 байт

Цей метод довший, але, можливо, певний інтерес. Підхід полягає у перевірці евклідової відстані між центром шахової дошки та цікавою клітиною.

Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&

Приклад

Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&@{0, 0}
Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&@{3, 3}

2

8


Щоб візуалізувати, наскільки відстань від центру шахової дошки достатня для присвоєння значення.

values={{2,3,4,4,4,4,3,2},{3,4,6,6,6,6,4,3},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{3,4,6,6,6,6,4,3},{2,3,4,4,4,4,3,2}};
f[x_]:=Text[x,#]&/@Position[values,x]r_~w~p_:=RegionMember[{3.5`,3.5`}~Disk~r,p]
h@y_:=Which[2.2~w~y,8,3~w~y,6,4~w~y,4,4.6~w~y,3,2<3,2]

Graphics[{Circle[{4.5, 4.5}, 2.3], Circle[{4.5, 4.5}, 3], 

Коло [{4.5, 4.5}, 4],

Коло [{4.5, 4.5}, 4.6], Flatten [f / @ {2, 3, 4, 6, 8}, 1]}, Сокири -> Правда, AxesOrigin -> {-1, -1}]


Числа 2.2, 3, 4 і 4.6 - це радіуси кіл.

зображення


1
Великий графік гастролей
зірковий

20
KnightTourGraphМатематика та її вбудовані ... :-)
Луїс Мендо

Я думаю, що в #кінці вашого вихідного коду (безпосередньо перед цим ]) є заблукалий . Ви повинні мати можливість використовувати IncidenceListзамість цього EdgeList@NeighborhoodGraph. (Крім того, є також EdgeCount, але я думаю, що це закінчується довше.)
Мартін Ендер,

1
О, зачекайте, насправді коротше:EdgeCount[8~KnightTourGraph~8,#+1+8#2<->_]&
Мартін Ендер

EdgeCountдуже круто!
DavidC

12

JavaScript (ES6), 38 байт

(x,y)=>+"23468"[((7-x)*x+(7-y)*y)/5|0]

Бере 0-індексовані входи. Пояснення: Подивіться на квадрати відстаней до центру:

24.5 18.5 14.5 12.5 12.5 14.5 18.5 24.5
18.5 12.5  8.5  6.5  6.5  8.5 12.5 18.5
14.5  8.5  4.5  2.5  2.5  4.5  8.5 14.5
12.5  6.5  2.5  0.5  0.5  2.5  6.5 12.5
12.5  6.5  2.5  0.5  0.5  2.5  6.5 12.5
14.5  8.5  4.5  2.5  2.5  4.5  8.5 14.5
18.5 12.5  8.5  6.5  6.5  8.5 12.5 18.5
24.5 18.5 14.5 12.5 12.5 14.5 18.5 24.5

Кількість квадратів, що доступні, розподіляється на п'ять смуг:

8    0-5
6    5-10
4   10-15
3   15-20
2   20-25

Я фактично обчислюю 24,5 - (3,5 - х) ** 2 - (3,5 - у) ** 2 = (7 - х) * х + (7 - у) * у, оскільки це коротший обчислення, але все це робиться зворотним порядок гуртів.


Супер лаконічний і дуже приємний підхід, тому мені більше не потрібно запускати власне рішення JS :)
starcorder

Хороша думка про те, що формула рівнозначна радіусу у квадраті. Я думав, що x*(7-x)це просто операція, яка виглядає як дуга вниз 0..7і , здається, криво підходить, але це пояснює, чому вона створює таку приємну схему, коли підсумовувати за xі y.
xnor

11

Желе, 10 байт

8ṗ2_³²S€ċ5

1-індексований. Бере єдиний аргумент форми [x,y]. Спробуйте тут.

8ṗ2          Cartesian square [[1,1],[1,2]…[8,8]]
   _³        Subtract the input
     ²S€     Compute the norm of each vector
        ċ5   Count fives

Денніс врятував байт!


Всього одинадцять байтів, ух!
зіркозахисник

Я бачив це питання вранці, і це саме той алгоритм, який я вважав, що буду реалізовувати в Jelly, коли встигну. : P
PurkkaKoodari

8

Математика, 44 40 байт

В даний час у мене є одне і те ж число байтів:

2[3,4,6,8][[Tr@⌊3.2-.8Abs[#-4.5]⌋]]&
Tr@⌈.85(4-Abs[#-4.5])⌉/.{5->6,6->8}&
⌊Tr@⌈.85(4-Abs[#-4.5])⌉^1.1608⌋&

Усі це неназвані функції, які приймають пару координат на зразок {3, 4}1.

Я спробував придумати дещо чітку формулу. Загальна схема на всій дошці виглядає так:

введіть тут опис зображення

Фактичні значення цих кольорів (від найлегшого до темного) 2, 3, 4, 6, 8. Це:

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2

Спочатку ми використовуємо симетрію, зміщуючи походження в центр, беручи абсолютне значення і віднімаючи результат 4. Це дає нам координати 0.5для 3.5збільшення з кожного кута. Для того , щоб координати центру ту ж нам потрібно зіставити 0.5і 1.5з різними значеннями і 2.5і 3.5до того ж значенню. Це легко зробити шляхом множення на 0.8(дає {0.4, 1.2, 2., 2.8}) і настил результату. Отож, тепер ми {0, 1, 2, 2}відстань від центру. Якщо ми складемо координати в кожній комірці, отримаємо цю таблицю:

0 1 2 2 2 2 1 0
1 2 3 3 3 3 2 1
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
1 2 3 3 3 3 2 1
0 1 2 2 2 2 1 0

Це унікальне значення для всіх можливих результатів, тому ми просто використовуємо його як індекс 2[3,4,6,8].

У другому варіанті ми використовуємо стелю замість підлоги. Таким чином, 2, 3і 4вже правильно, але ми отримуємо 5і 6замість 6і 8, таким чином , ми виправимо їх вручну за допомогою правила підстановки.

Нарешті, в третій версії ми розширюємо 5і 6вгору до 6і 8за допомогою експоненції з наступною операцією підлоги.


Мені дуже подобається підхід із загальною схемою ради, чудово!
зірковий звук

6

APL, 21 чол

{+/,5=+/¨×⍨(⍳8 8)-⊂⍵}

Англійською:

  • (⍳8 8): Масив 8x8 ранг-2, що містить координати всіх комірок;
  • +/¨×⍨(⍳8 8)-⊂⍵: квадрат евклідової відстані даної комірки щодо кожної комірки на дошці;
  • 5=: матриця 0/1, де 1s з'являються на відстані квадрата, рівних 5;
  • +/,: підсумовуємо сплюснуту матрицю

Тест (за походженням 1):

    f←{+/,5=+/¨×⍨(⍳8 8)-⊂⍵}
    f¨1+(3 4)(4 6)(7 7)(1 0)
8 6 2 3

У цій формі:

f←{+/,5=+/¨×⍨(⍳⍺)-⊂⍵}

лівий аргумент може вказати розміри дошки. Отже, 8 8 fбуде працювати для стандартної квадратної шахової дошки. Але на більшій та прямокутній дошці тестові приклади давали б різні результати. Наприклад, на дошці 12x10:

    g←(10 12)∘f
    g¨1+(3 4)(4 6)(7 7)(1 0)
8 8 8 3

У жаргоні APL матриця - це масив рангів 2, про вміст комірок нічого не сказано. Роки (ab) використання термінів зробили мене нечутливим до цього. Я оновлю опис для більш традиційно схильних читачів. Дякую.
lstefano

@Istefano Це використання "рангу" як "кількості вимірів", схоже, страждає від тієї ж скорботи :-P
Луїс Мендо,

Я буду ... Ти маєш рацію! Видно, що минув час, коли я взяв лінійну алгебру. Я
здаюсь

1
Повна програма, 27: ≢⍸5=+/¨×⍨-∘⎕¨⍳8 8 Спробуйте онлайн!
Адам

@ Adám ви маєте на увазі 17
пн

6

Java - 160 150 байт

int m(int r,int c){int m=0,i,j;for(i=0;i<3;i+=2)for(j=0;j<3;j+=2){m+=r+i>0&r+i<9&c+2*j>1&c+2*j<11?1:0;m+=r+2*i>1&r+2*i<11&c+j>0&c+j<9?1:0;}return m;}

Безголівки:

public static int m(int r, int c) {
    int m=0;
    for(int i=-1;i<2;i+=2)
        for(int j=-1;j<2;j+=2){
            m += r+i>-1 && r+i<8 && c+2*j>0 && c+2*j<8 ? 1:0;
            m += r+2*i>0 && r+2*i<8 && c+j>1 && c+j<8 ? 1:0;
        }
    return m;
}

Невикольований код є ідентичним, за винятком зміни меж циклу for для збереження 4 байтів. Працює, повторюючи кожен можливий хід і виконуючи перевірку меж (> 0 і <8). Використовує той факт, що зсувами є (1, 2), (2, 1), (-1, 2), (-2, 1) і т. Д. І здатний перевірити 2 ходи для кожного значення i і j.

Редагувати: 10 байт збережено завдяки пропозиціям Leaky Nun та u902383.


Це теж було швидко, приємно!
зіркозахисник

У ньому помилка була виправлена.
ejaszewski

1
int m=0,i=-1,j;щоб зберегти кілька байтів
Leaky Nun

1
змінити логічний AND на бітовий AND і це дозволить видалити додаткові 6 символів
user902383

6

C, 44 байт

f(x,y){return "23468"[((7-x)*x+(7-y)*y)/5];}

Але це краще:

f(x,y){return "2344443234666643468888644688886446888864468888643466664323444432"[x*8+y];}

1
Відсутній ;. Не збирається.
ugoren


1
Це не фрагмент, це функція і не забороняється розміщувати функції. Вибачте за відсутню крапку з комою. Виправлено.
Джакомо Гарабелло

5

Haskell, 49 48 байт

w=[0..7]
x%y=sum[1|a<-w,b<-w,(a-x)^2+(b-y)^2==5]

1
Ви можете зберегти [0..7]до змінної на 1 байт.
xnor

5

Java, 81 символ (113 байт)

int r(int a,int b){return "⍄䐲㑦晃䚈衤䚈衤䚈衤䚈衤㑦晃⍄䐲".codePointAt(a*2+b/4)>>(3-b%4)*4&15;}

Кодуйте всю таблицю результатів як таблицю unicode, а потім отримайте відповідні байти, виконуючи побітові операції.

Ви можете побачити його онлайн тут: https://ideone.com/K9BojC


3

Пітон, 94 байти

lambda x,y,a=[2,1,-1,-2,-2,-1,1,2]:list((9>x+a[i]>0)&(9>y+a[5-i]>0)for i in range(8)).count(1)

Використовує індексацію на основі 1.

Демонстрація на https://repl.it/C6gV .





1

Власне, 18 байт

`;7-2km`MΣ8-:50\¬¬

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

Це реалізує ту ж формулу , що і багато інших відповіді були з допомогою: 50/(8-x*(7-x)//5+y*(7-y))//5)-4. Введення приймається як список: [x,y](або будь-який ітерабельний літерал на Python, як (x,y)або x,y).

Пояснення:

`;7-2km`MΣ8-:50\¬¬
`;7-2km`M           for each value in input:
 ;7-                  make a copy, subtract from 7
    2                 push 2
     km               minimum of the three values (x, 7-x, 2)
         Σ          sum
          8-        subtract from 8
            :50\    integer divide 50 by the value
                ¬¬  subtract 2 twice

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