Кількість штук на дошці шашок


14

Вступ

Звичайна дошка шашок містить 8 х 8 = 64 квадратів:

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

Видно, що всього 12 білих шматочків . Чорно-білі завжди мають однакову кількість штук. Якщо на дошці ще є шматки, шматки будуть сусідніми, що заборонено для цього виклику. Для уточнення речей, ось кілька прикладів:

Найменша дошка для цього виклику - 3 х 3 :

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

Видно, що максимальна кількість штук дорівнює 2 . Отже, коли вам задано N = 3 , вам потрібно вивести 2 . Якщо вхід N = 4 , отримуємо наступне:

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

Ви можете бачити, що максимальна сума також 2. Отже, для N = 4 вихід повинен бути 2 . Для N = 5 вихід повинен дорівнювати 5 :

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

Приклади

STDIN:  3
STDOUT: 2

STDIN:  4
STDOUT: 2

STDIN:  5
STDOUT: 5

STDIN:  6
STDOUT: 6

STDIN:  8
STDOUT: 12

Правила

  • Ваша заявка повинна бути програмою або функцією тощо, яка займає одне ціле число і виводить або повертає кількість фрагментів на дошці
  • Можна сміливо припускати, що вхід - це невід'ємне ціле число> 2
  • Це , тому програма з найменшою кількістю байтів виграє!
  • Зауважте, що квадрат у нижній лівій частині дошки завжди темний. Шматки розміщуються лише на темних квадратиках
  • Ви повинні зайняти повний ряд з шматками

3
Чому обмеження на повні програми та STDIN / STDOUT? ІМО, це просто несправедливо до мов, які мають необхідні накладні програми та / або введення.
lirtosiast

@ThomasKwa, ти маєш рацію. Функції тощо тепер дозволені
Аднан

Відповіді:


5

Пар , 8 байт

✶″½↓┐*½┐

На один символ використовується один байт.

Пояснення

               ## [implicit: read line]      Example
✶              ## Convert to number           7
″              ## Duplicate                   7 7
½              ## Divide by two               7 3.5    half the board
↓              ## Minus one                   7 2.5    leave one row empty
┐              ## Ceiling                     7 3      a whole number of rows
*              ## Multiply                    21       total number of spaces
½              ## Divide by two               10.5     only the blue squares
┐              ## Ceiling                     11       starts with blue, so round up

12

Шестикутник , 19 байт

?({{&2'2':{):!/)'*/

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

Пояснення

Це все ті ж обчислення, які я використовував у моїх відповідях CJam і Labyrinth, але завдяки ... спеціальній ... моделі пам'яті Гексагоні, трохи складніше видавити обчислення на 19 байт (так, щоб воно вмістилося всередині бічна довжина 3 шестикутника).

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

Ось розгорнутий код:

enter image description here

Як я вже сказав, код повністю лінійний. Ви можете скласти виконаний шлях разом для порядку сіро-фіолетово-зелений-червоно-синій. Шлях насправді продовжується трохи далі, поки він не потрапить :на ліворуч. Видаляючи /(який перенаправляє лише потік управління), вся програма лінійно розкручується:

?({2':{)'*){&2':!:&?':

Тож питання в тому, як це працює. Пам'ять гексагонії - це лінійний графік шестигранної сітки, де кожен край сітки містить ціле значення (спочатку нуль). Вказівник пам’яті (МП) завжди знаходиться на одному краї і вказує в певному напрямку вздовж цього краю. Арифметичні операції, як правило, застосовуються до двох ребер, спрямованих на і збережених у краю, на якому знаходиться MP.

Для цієї програми ми будемо використовувати три ребра, позначені A , B , C , починаючи з MP, як показано тут:

enter image description here

Отже, ось як це працює:

?  Read an integer N from STDIN into edge A.
(  Decrement to get N-1.
{  Move the MP forwards onto edge B.
2  Set the edge to 2.
'  Move the MP backwards onto edge C.
:  Divide edge A by edge B (rounding down) to compute (N-1)/2.
{  Move the MP forwards onto edge A.
)  Increment to restore value of N.
'  Move the MP backwards onto edge B.
*  Multiply edges A and C to compute N*(N-1)/2.
)  Increment to compute N*(N-1)/2 + 1.
{  Move the MP forwards onto edge C.
&  This actually a copy operation, but we use it to reset the edge to zero.
2  Set the edge to 2.
'  Move the MP backwards onto edge A.
:  Divide edge B by edge C to compute (N*(N-1)/2 + 1)/2.
!  Output the result as an integer. We're basically done now.
:  no-op (we already have this value)
&  Copy either B or C into A (doesn't matter).
?  Read a zero (EOF) into A.
'  Move the MP backwards onto an unused cell.
:  Divide some unused cell by A (which is zero), terminating with an error.

{{переміщує край пам'яті двічі, так що & у другому ряду, здається, нічого не роблять? В обох негібурів має бути 0
Eumel

@Eumel Це не порядок виконання коду. Після першого {, IP переходить до2 лівого кута. Після )правого кута IP переходить до 'лівого нижнього кута. Тоді лінії IP 2 та 4 проходять по дивному циклічному обгортанню.
Мартін Ендер

о, я думав, що це змінило лише мене, а не IP. також +1 лише для використання гексагонії, що ця мова є занадто смішною
Eumel

@Eumel Це так. Ось так, як краї коду загортаються в шестикутнику.
Мартін Ендер


8

CJam, 10 байт

ri_(2/*)2/

Тестуйте це тут.

Пояснення

ri   e# Read input and convert to integer N.
_    e# Duplicate N.
(2/  e# Decrement, integer divide by two, to determine the number of rows that can be used.
*    e# Multiply by the input to determine the number of cells that can be used.
)2/  e# Increment, integer divide by two, which essentially ceil()s the result of the
     e# division.

8

Лабіринт , 11 байт

Woohoo, лише один байт позаду CJam .

?:(#/*)_2/!

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

Це по суті те саме:

? reads an integer value.
: duplicates the result.
( decrements it.
# pushes the stack depth which happens to be 2.
/ is integer division.
* is multiplication.
) increments the result.
_ pushes a 0.
2 turns it into a 2.
/ is once again integer division.
! prints the result as an integer.

Однак на даний момент програма ще не припиняється. Натомість покажчик інструкцій потрапив у глухий кут і обертається. Але тепер /намагається обчислити, 0/0що закінчується помилкою .


5

Серйозно , 8 байт

,;D½L*½K

Серйозно це зручно ½ (поплавковий поділ на 2) та K(стеля), тому нам не потрібно додавати його до поділу.

Спробуйте тут із поясненням.


5

Python 2, 22 21 байт

lambda n:~-n/2*n+1>>1

Я спочатку відокремлююсь у двох випадках, непарних N і парних N.

Непарними N ми можемо заповнити (N - 1) / 2 ряди, що містять в середньому N / 2 штуки. Оскільки в першому ряді завжди є більше шматків, ми повинні закінчити цей результат. Отже, коли N непарне, у нас є шматки ((N-1) / 2 * N / 2).

З рівними N ми можемо заповнити рядки N / 2 - 1, або підлоги ((N - 1) / 2), кожен ряд містить N / 2 шматки.

Ми можемо поєднати ці два вирази по ceil (пол ((N-1) / 2) * N / 2). Так як (х стелі / 2) = підлогу ((х + 1) / 2) , ми можемо використовувати підлогове покриття ділення: ((N - 1) // 2 * N + 1) // 2.


3

JavaScript, 37 35 байт

alert(((n=prompt()/2)-.5|0)*n+.5|0)

Пояснення

Використовує аналогічну техніку до решти відповідей. Це алгоритм, який не має сил:

var n = parseInt(prompt());
var result = Math.ceil(Math.floor((n - 1) / 2) * n / 2);
alert(result);


3

Pyth, 9 байт

/h*/tQ2Q2

Такий же алгоритм, як і моя відповідь Python 2.


3

Japt , 16 14 байт

U-1>>1 *U+1>>1

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

Як це працює

Досить просто:

         // Implicit: U = input number
U-1>>1   // Subtract 1 from U and integer divide by 2.
*U+1>>1  // Multiply the result by U, add 1, and integer divide by 2.
         // Implicit: output last expression

Я хотів би, щоб був якийсь спосіб врахувати, що дві половини коду настільки схожі. Пропозиції Ласкаво просимо!

Стара версія (16 байт):

U*½-½|0 *U*½+½|0

3

Ява, 230 155 52

Гольф:

int f(int s){return(int)Math.ceil(s*((s-1)/2)/2.0);}

Безголівки:

public class NumberOfPiecesOnACheckersBoard {

  public static void main(String[] args) {
    // @formatter:off
    int[][] testData = new int[][] {
      {3, 2},
      {4, 2},
      {5, 5},
      {6, 6},
      {8, 12}
    };
    // @formatter:on

    for (int[] data : testData) {
      System.out.println("Input: " + data[0]);
      System.out.println("Expected: " + data[1]);
      System.out.print("Actual:   ");
      System.out.println(new NumberOfPiecesOnACheckersBoard().f(data[0]));
      System.out.println();
    }
  }

  // Begin golf
  int f(int s) {
    return (int) Math.ceil(s * ((s - 1) / 2) / 2.0);
  }
  // End golf

}

Вихід програми:

Input: 3
Expected: 2
Actual:   2

Input: 4
Expected: 2
Actual:   2

Input: 5
Expected: 5
Actual:   5

Input: 6
Expected: 6
Actual:   6

Input: 8
Expected: 12
Actual:   12

throws Exceptionдопустимо.
Ніл

1
Дозволені функції ОП.
ліртосіаст

Ви можете використовувати Scannerклас для введення. Це врятувало б вам купу байтів, я думаю. ( Комбо BufferedReader/ InputStreamReaderкомбо може бути кращим у загальному використанні, але це код з гольфом, і він Scannerпрацює чудово для простого введення даних.)
Даррел Гофман

Перетворення на автономну функцію та використання параметрів / значення повернення замість стандартного вводу / виводу зробило величезну різницю.

2

Машинний код Zilog ez80, 9 байт

У шістнадцятковій формі:

6C 2D CB3D ED6C 2C CB3D

У зборі:

ld l,h
dec l
srl l
mlt hl
inc l
srl l

Введення в регістрі h, а вихід уl .

Zilog ez80 - це 8-розрядний процесор з 8-бітовим акумулятором і 24-розрядними регістрами. На відміну від z80, він має mltінструкцію (8-бітне множення), яка в 16-бітному режимі примножує тут високі та низькі байти пари регістрів hlі зберігає їх назад hl.

Це працює лише для значень, для яких вдвічі результат відповідає 8 бітам; тобто n≤23.


2

TI-BASIC, 13 байт

⁻int(⁻.5Ansint(Ans/2-.5

Неявне множення TI-BASIC допомагає, але воно не має цілого поділу. ⁻int(⁻Xє коротшою формою стелі (х).


2

vba, 46

Function f(x)
f=(((x-1)\2)*x+1)\2
End Function

Викличте за формулою? F (x) або = f (A1)


2

Pyth, 17 14 13 байт

-3 байти завдяки Ypnypn ! Впорядкував номери оператора *, щоб зберегти 1 байт.

/+*Q-/Q2-1%Q2 1 2 (original)
/h*Q-/Q2!%Q2 2
/h*-/Q2!%Q2Q2

Пояснення:

Коли n парне, ми можемо займати n / 2-1 рядки з n / 2 штук, складаючи в цілому n * (n / 2-1) / 2 штуки. Цей вираз еквівалентний (n * (n / 2-1) +1) / 2

Коли n непарних, ми можемо виявити, як удвічі буде виглядати кількість штук, удвічі більша кількість штук буде простягатись n-1 рядів, і якщо я відніму одну частину, ми можемо розділити n-1 рядки на (n- 1) / 2 групи по 2 рядки, так що кожна група має n частин, тому вираз для цього випадку є (n * (n / 2) +1) / 2

Тепер, коли обидва вирази досить схожі, ми можемо написати код.

/h*-/Q2!%Q2Q2
        %Q2   Check if the number is odd
       !      Logical not to make 1 if even and 0 if odd
    /Q2       n/2
   -          n/2-1 if even, and n/2 if odd
  *        Q  n*(n/2-1) if even, n*(n/2) if odd
 h            Add one
/           2 Divide the result by two.

Вперше я використовую мову для гольфу.


2

Javascript, 33 байти

a=prompt();alert(a*(a-1>>1)+1>>1)

Якщо функція ES6 дозволена, то 18 байт:

a=>a*(a-1>>1)+1>>1

2

МАТЛАБ, 37 25 байт

@(a)ceil(fix(a/2-.5)*a/2)

Я вважаю, що це повинно працювати, як і для всіх тестових випадків.

Він також працює на Octave . Ви можете спробувати онлайн тут .


Для старого коду я додав програму до цієї робочої області у файлі з назвою checkerboard.m. Ви можете запустити його, просто ввівшиcheckerboard підказку, а тоді, коли він запуститься, введіть потрібний розмір у запиті. Результат буде надруковано.

Для нового коду просто введіть код, розміщений тут, у підказку, а потім зателефонуйте як анонімну функцію як ans(n).


Дякуємо за голоси, нарешті дійшли до 1000 Rep :) Woop.
Том Карпентер

@ThomasKwa дякую, що вказали на це. Збережено 12 байт :).
Том Карпентер

2

Сітківка , 18 байт

11(..?$)?
$_
11?
1

Вхід і вихід не є одинаковими .

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

Остання версія Retina (новіша, ніж ця проблема) може обробляти десятковий введення / вивід для чотирьох додаткових байтів:

.+
$*
11(..?$)?
$_
11?

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

За допомогою одинарного введення та десяткового виведення ми можемо зробити 16 байт, але це здається трохи розтягнутим:

11(..?$)?
$_
11?

Пояснення

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

11(..?$)?
$_

Це обчислює n*((n-1)/2). Ми робимо це, поєднуючи два символи одночасно (ділення на два) і замінюючи їх цілим рядком (множення на n). Зменшення функції nробиться, пропускаючи решту рядка, якщо залишилося лише один або два символи.

11?
1

Це ціле ділення на 2, округлене вгору. Ми просто замінюємо два символи одним (поділ на 2), але дозволяємо останньому матчу складатися лише з одного символу (округлення вгору).


Вітаю з вашою 1000-ю відповіддю: p
Аднан


1

Пролог, 39 38 байт

Код:

p(N):-X is ((N-1)//2*N+1)//2,write(X).

Пояснення:

Subtract 1 from input and integer divide by 2 to get number of rows available.
Multiply that number by input to get number of squares available. 
Add one and integer divide by 2 to round up, since at at least half the rows 
will have a checker at the first square.
Print.

Приклад:

p(8).
12

Спробуйте його онлайн тут

Редагувати: збережено 1 байт, замінивши ceil / 2 на + 1 // 2


1

Свинка, 17 байт

R I W I-1\2*I+1\2

Дякую Еміньї за просте пояснення алгоритму. Це використовує «дефіцит» математики свинки, що операції виконуються строго зліва направо (не PEMDAS), тому дужки не потрібні. :-)

Вихід виглядає дуже дивним, однак, оскільки ансамбль Cache (середовище Mumps, до якого я маю доступ) не виводить автоматично повернення каретки навіть при натисканні на вхід. Якщо ви хочете красивіше, додайте 4 символи для повернення до / після перевезення:

R I W !,I-1\2*I+1\2,!

Спасибі!




1

Пакет, 30 байт

@cmd/cset/a(%1*((%1-1)/2)+1)/2

38 байт, якщо потрібно ввести stdin:

@set/pa=
@cmd/cset/a(a*((a-1)/2)+1)/2
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.