Количество штук на шашечной доске

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? IMO, это просто несправедливо по отношению к языкам, которые имеют необходимые программные и / или входные данные.
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
Ypnypn
источник
12

Гексагония , 19 байт

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

Попробуйте онлайн.

объяснение

Это все те же вычисления, которые я использовал в своих ответах на CJam и Labyrinth, но из-за ... особой ... модели памяти Hexagony, немного сложнее сжать вычисление в 19 байтов (так, чтобы оно помещалось внутри длина стороны 3 шестиугольника).

Как и в моем ответе Лабиринт, это заканчивается ошибка деления на 0.

Вот развернутый код:

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

Как я уже сказал, код полностью линейный. Вы можете объединить выполненный путь в следующем порядке: серый-фиолетовый-зеленый-красный-синий. Путь фактически продолжается немного дальше, пока он не достигнет :слева. Удаляя /(который только перенаправляет поток управления), вся программа развернута линейно:

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

Так что вопрос в том, как это работает. Память Hexagony - это линейный график шестнадцатеричной сетки, где каждое ребро сетки содержит целочисленное значение (изначально ноль). Указатель памяти (MP) всегда находится на одном ребре и указывает в определенном направлении вдоль этого ребра. Арифметические операции , как правило , применяется к двум краям указывали на и находится на краю МП включен.

Для этой программы мы будем использовать три ребра, обозначенные A , B , C , причем MP начинается, как показано здесь:

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

Вот как это работает:

?  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 Это так. Именно так оборачиваются края кода в Hexagony.
Мартин Эндер
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 (потолок), поэтому нам не нужно добавлять один перед делением.

Попробуйте здесь с объяснением.

lirtosiast
источник
5

Python 2, 22 21 байт

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

Я сначала разделяю в двух случаях, нечетные N и четные N.

Нечетным N мы можем заполнить (N - 1) / 2 строки, содержащие в среднем N / 2 штуки. Так как в первом ряду всегда больше частей, мы должны закрыть этот результат. Поэтому, когда N нечетно, у нас есть части ceil ((N-1) / 2 * N / 2).

Даже четным N мы можем заполнить N / 2 - 1, или этаж ((N - 1) / 2) строк, каждая строка содержит N / 2 штук.

Мы можем объединить эти два выражения с помощью ceil (floor ((N-1) / 2) * N / 2). Так как (х потолке / 2) = пол ((х + 1) / 2) , мы можем использовать напольное покрытие деления: ((N - 1) // 2 * N + 1) // 2.

orlp
источник
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);
user81655
источник
3

12

?d1-2/*1+2/p

Тестовый вывод:

$ for t in 3 4 5 6 8; do echo $t | dc -e?d1-2/*1+2/p; done
2
2
5
6
12
$ 
Цифровая травма
источник
3

Pyth, 9 байт

/h*/tQ2Q2

Тот же алгоритм, что и в моем ответе на Python 2.

orlp
источник
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
ETHproductions
источник
3

Ява, 230 155 52

Golfed:

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

Ungolfed:

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
ОП разрешенные функции.
lirtosiast
Вы можете использовать Scannerкласс для ввода. Я думаю, это сэкономит вам кучу байтов. (The 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.

lirtosiast
источник
2

TI-BASIC, 13 байтов

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

Помогает неявное умножение TI-BASIC, но оно не имеет целочисленного деления. ⁻int(⁻Xэто более короткая форма ceil (x).

lirtosiast
источник
2

vba, 46

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

Вызовите с? F (x) или = f (A1) в формуле

SeanC
источник
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.

Я впервые использую язык игры в гольф.

Element118
источник
2

Javascript, 33 байта

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

Если функция ES6 разрешена, то 18 байтов:

a=>a*(a-1>>1)+1>>1
Нил
источник
2

MATLAB, 37 25 байт

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

Я считаю, что это должно работать, подходит для всех тестовых случаев.

Это также работает в Октаве . Вы можете попробовать онлайн здесь .


Для старого кода я добавил программу в это рабочее пространство в файле с именем checkerboard.m. Вы можете запустить его, просто введя checkerboardв командной строке, а затем при запуске введите необходимый размер в командной строке. Результат будет распечатан.

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

Том Карпентер
источник
Спасибо за поднятые голоса, наконец-то достиг 1000 Реп :) 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

Emigna
источник
1

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

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

Благодаря Эмигне за простое объяснение алгоритма. Это использует «недостаток» математики Мампа в том, что операции выполняются строго слева направо (не PEMDAS), поэтому скобки не требуются. :-)

Однако вывод выглядит немного странно, поскольку Ensemble Cache (среда Mumps, к которой у меня есть доступ) не выводит автоматически возврат каретки даже при нажатии на ввод. Если вы хотите, чтобы он был красивее, добавьте 4 символа для возвратов до / после переноса:

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

Благодарность!

zmerch
источник
1

Баш, 32 байта

read a;echo $((a*(a-1>>1)+1>>1))
Нил
источник
1

Пакетный, 30 байтов

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

38 байт, если требуется ввод на stdin:

@set/pa=
@cmd/cset/a(a*((a-1)/2)+1)/2
Нил
источник