Dama Tahtası üzerindeki parça sayısı


14

Giriş

Normal bir dama tahtası 8 x 8 = 64 kare içerir:

resim açıklamasını buraya girin

Toplamda 12 beyaz parça olduğunu görebilirsiniz . Siyah ve beyaz daima aynı miktarda parçaya sahiptir. Tahtada daha fazla parça varsa, bu meydan okuma için izin verilmeyen parçalar komşu olur. Bazı şeyleri açıklığa kavuşturmak için bazı örnekler:

Bu meydan okuma için mümkün olan en küçük tahta 3 x 3'tür :

resim açıklamasını buraya girin

Maksimum parça miktarının 2'ye eşit olduğunu görebilirsiniz . Bu nedenle, N = 3 verildiğinde , 2 çıktısı almanız gerekir . Giriş N = 4 ise , aşağıdakileri elde ederiz:

resim açıklamasını buraya girin

Maksimum miktarın da 2 olduğunu görebilirsiniz. Dolayısıyla N = 4 için çıktı 2 olmalıdır . İçin , N = 5 , çıkış eşit olmalıdır 5 :

resim açıklamasını buraya girin

Örnekler

STDIN:  3
STDOUT: 2

STDIN:  4
STDOUT: 2

STDIN:  5
STDOUT: 5

STDIN:  6
STDOUT: 6

STDIN:  8
STDOUT: 12

kurallar

  • Gönderiminiz, bir tamsayı alan ve tahtadaki parça sayısını veren veya döndüren bir program veya işlev vb. Olmalıdır.
  • Girişin negatif olmayan bir tamsayı> 2 olduğunu güvenle varsayabilirsiniz.
  • Bu , bu yüzden en az bayt miktarı ile program kazanır!
  • Tahtanın sol alt köşesindeki karenin her zaman karanlık olduğunu unutmayın. Parçalar sadece karanlık karelere yerleştirilir
  • Parçalarla dolu bir sıra işgal etmelisin

3
Tam programlara ve STDIN / STDOUT'a neden kısıtlama getiriliyor? Gerekli program ve / veya giriş ek yükü olan diller için adil olmayan IMO.
lirtosiast

@ThomasKwa, haklısın. Artık işlevler vb. Kullanılabilir
Adnan

Yanıtlar:


5

Par , 8 bayt

✶″½↓┐*½┐

Karakter başına bir bayt kullanılır.

açıklama

               ## [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

Altıgen , 19 bayt

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

Çevrimiçi deneyin.

açıklama

Bu hala CJam ve Labirent cevaplarımda kullandığım hesaplama ile aynı, ancak Hexagony'in ... özel ... bellek modeli nedeniyle, hesaplamayı 19 bayta sıkıştırmak biraz daha zor (böylece bir yan uzunluk 3 altıgen).

Labirent cevabım gibi bu da 0'a bölünme hatasıyla sona erer.

Açılan kod şöyledir:

resim açıklamasını buraya girin

Dediğim gibi kod tamamen doğrusal. Yürütülen yolu gri-mor-yeşil-kırmızı-mavi olarak bir araya getirebilirsiniz. Yol aslında :sol tarafa vuruncaya kadar biraz daha devam eder . /Doğrusal olarak açılan tüm program (yalnızca kontrol akışını yeniden yönlendiren) kaldırıldığında :

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

Soru şu: Nasıl çalışıyor? Hexagony'nin belleği, ızgaranın her kenarının bir tamsayı değeri (başlangıçta sıfır) içerdiği onaltılık bir ızgaranın çizgi grafiğidir. Bellek işaretçisi (MP) her zaman bir kenardadır ve bu kenar boyunca belirli bir yönü gösterir. Aritmetik işlemler genellikle , MP'nin bulunduğu kenarı işaret eden ve saklanan iki kenara uygulanır .

Bu program için, MP burada gösterildiği şekilde başlayarak A , B , C etiketli üç kenarı kullanacağız :

resim açıklamasını buraya girin

İşte bunun nasıl çalıştığı:

?  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.

{{bellek kenarını iki kez hareket ettirir, böylece ikinci satırdaki & hiçbir şey yapmıyormuş gibi görünür? Her iki komşu da 0 olmalı
Eumel

@Eumel Bu, kodun yürütüldüğü sıra değil. İlkinden sonra {IP 2sol köşeye atlar . Sonra )sağ köşede, IP atlar 'sol alt köşesinde. Sonra IP çapraz çizgiler 2 ve 4 garip döngüsel olarak sarma bir şekilde.
Martin Ender

oh ben sadece IP değil ME değişti düşündüm. Ayrıca dil sadece çok komik olduğunu sadece hexagony kullanmak için +1
Eumel

@Eumel Öyle. Kodun kenarları Hexagony'de böyle sarılır.
Martin Ender


8

CJam, 10 bayt

ri_(2/*)2/

Burada test edin.

açıklama

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

Labirent , 11 bayt

Woohoo, CJam'ın arkasında sadece bir bayt .

?:(#/*)_2/!

Çevrimiçi deneyin.

Aslında aynı şey:

? 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.

Ancak, bu noktada program henüz sona ermemektedir. Bunun yerine, talimat işaretçisi bir çıkmaza girdi ve geri döndü. Ama şimdi /hesaplamak için çalışır 0/0hangi bir hata ile sonlanır .


5

Ciddi , 8 bayt

,;D½L*½K

Ciddi kullanışlı ½(şamandıra bölünme 2) ve K(tavan) vardır, bu yüzden bölünmeden önce bir tane eklememiz gerekmez.

Burada açıklama ile deneyin .


5

Python 2, 22 21 bayt

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

İlk olarak iki durumda ayrıldım, tek N ve hatta N.

Tek N ile ortalama N / 2 adet içeren (N - 1) / 2 satır doldurabiliriz. İlk sıra her zaman daha fazla parça içerdiğinden bu sonucu tavana almalıyız. Yani N tuhaf olduğunda tavan ((N-1) / 2 * N / 2) parçalarımız var.

N ile bile, her satırda N / 2 parça içeren N / 2 - 1 veya zemin ((N - 1) / 2) satırlarını doldurabiliriz.

Bu iki ifadeyi tavana (zemin ((N-1) / 2) * N / 2)) birleştirebiliriz. : Ceil (x / 2) = kat ((x + 1) / 2) bir bölünme döşeme kullanabilir yana ((N - 1) // 2 * N + 1) // 2.


3

JavaScript, 37 35 bayt

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

açıklama

Cevapların geri kalanına benzer bir teknik kullanır. Bu çözülmemiş algoritma:

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

3

dc, 12

?d1-2/*1+2/p

Test çıktısı:

$ 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 bayt

/h*/tQ2Q2

Python 2 cevabımla aynı algoritma.


3

Japt , 16 14 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

Gayet basit:

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

Kod iki yarısı çok benzer olduğunu dikkate almanın bir yolu olsaydı. Öneriler hoş geldiniz!

Eski sürüm (16 bayt):

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

3

Java, 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

}

Program çıktısı:

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 Exceptionizin verilir.
Neil

1
OP izin verilen fonksiyonlar.
lirtosiast

ScannerSınıfı giriş için kullanabilirsiniz . Sanırım bu bir sürü bayt kurtarır. ( BufferedReader/ InputStreamReaderCombo genel kullanımda daha iyi olabilir, ancak bu kod golftür ve Scannerbasit giriş için gayet iyi çalışır.)
Darrel Hoffman

Tek başına bir işleve dönüştürmek ve standart giriş / çıkış yerine parametreler / dönüş değerleri kullanmak büyük bir fark yarattı.

2

Zilog ez80 makine kodu, 9 bayt

Onaltılı olarak:

6C 2D CB3D ED6C 2C CB3D

Montajda:

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

Giriş kayıtta hve çıkış var l.

Zilog ez80, 8 bit akümülatör ve 24 bit kayıtlara sahip 8 bit işlemcidir. Z80'in aksine, mlt16 bit modunda burada bir kayıt çiftinin yüksek ve düşük baytlarını çarpan hlve tekrar saklayan bir (8 bit çarpma) komutuna sahiptir hl.

Bu sadece sonucun iki katı 8 bit'e uyan değerler için geçerlidir; yani n23.


2

TI-BASIC, 13 bayt

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

TI-BASIC'in örtülü çarpımı yardımcı olur, ancak tamsayı bölünmesi yoktur. ⁻int(⁻Xdaha kısa bir tavan şeklidir (x).


2

vba, 46

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

Formülde? F (x) veya = f (A1) ile çağırın


2

Pyth, 17 14 13 bayt

Ypnypn sayesinde -3 bayt ! 1 bayt kaydetmek için * operatörünün numaralarını yeniden düzenledi.

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

Açıklama:

N eşit olduğunda, toplam n * (n / 2-1) / 2 adet yaparak n / 2-1 satırları n / 2 adet ile işgal edebiliriz. Bu ifade (n * (n / 2-1) +1) / 2'ye eşdeğerdir

N tuhaf olduğunda, parça sayısının iki katı nasıl görüneceğini bulabiliriz, iki parça sayısı n-1 satırlara yayılır ve bir parçayı alırsam, n-1 satırlarını (n- 1) / 2 gruptan oluşan 2 grup, böylece her grubun n parçası olur, bu nedenle bu durum için ifade (n * (n / 2) +1) / 2'dir.

Şimdi her iki ifade de oldukça benzer olduğundan, kodu yazabiliriz.

/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.

İlk kez bir golf dili kullanıyorum.


2

Javascript, 33 bayt

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

ES6 işlevine izin verilirse 18 bayt:

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

2

MATLAB, 37 25 bayt

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

Bunun çalışması gerektiğine inanıyorum, tüm test vakaları için geçerli.

Ayrıca Octave üzerinde de çalışır . Burada çevrimiçi deneyebilirsiniz .


Eski kod için programı bu çalışma alanına adlı bir dosyaya ekledim checkerboard.m. Sadece checkerboardbilgi istemine girerek çalıştırabilirsiniz , daha sonra başladığında, bilgi istemine gerekli boyutu girin. Sonuç yazdırılacaktır.

Yeni kod için, burada yayınlanan kodu bilgi istemine girin ve anonim işlevi olarak çağırın ans(n).


Yukarı oy için teşekkürler, nihayet 1000 Rep :) ulaştı Woop.
Tom Carpenter

@ThomasKwa bunu gösterdiğin için teşekkürler. 12 bayt kaydedildi :).
Tom Carpenter

2

Retina , 18 bayt

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

Giriş ve çıkış tekli .

Çevrimiçi deneyin!

Retina'nın en son sürümü (bu meydan okumadan daha yeni) dört ek bayt için ondalık G / Ç işleyebilir:

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

Çevrimiçi deneyin!

Tekli giriş ve ondalık çıktı ile 16 bayt yapabiliriz, ancak bu biraz esneme gibi görünüyor:

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

açıklama

Yine de herkesle aynı yaklaşım, ancak sayının sıradan bir temsilinde regex değişimini kullanıyor.

11(..?$)?
$_

Bu hesaplar n*((n-1)/2). Bunu, bir seferde iki karakteri eşleştirerek (ikiye böl) ve bunları tüm dizeyle (çarparak n) değiştirerek yaparız . Bir eksiltme nsadece bir veya iki karakter bırakılırsa, dize kalanını atlama yapılır.

11?
1

Bu, yuvarlatılmış tamsayı 2'dir. İki karakteri sadece bir karakterle değiştiririz (2'ye bölün), ancak son eşleşmenin yalnızca bir karakterden (yuvarlama) oluşmasına izin veririz.


1000'inci cevabın için tebrikler: p
Adnan


1

Prolog, 39 38 bayt

Kod:

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

Açıklama:

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.

Misal:

p(8).
12

Buradan çevrimiçi deneyin

Düzenleme: Tavan / 2'yi + 1 // 2 ile değiştirerek 1 bayt kaydedildi


1

Kabakulak, 17 bayt

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

Basit algoritma açıklaması için Emigna'ya teşekkürler . Bu Kabakulak matematik "eksiklik" sömürü işlemleri kesinlikle soldan sağa (PEMDAS değil) yürütülür böylece parantez gerekli değildir. :-)

Bununla birlikte, önbellek Ensemble (eriştiğim Kabakulak ortamı), girişe basıldığında bile satır başlarını otomatik olarak vermediğinden, çıktı biraz garip görünüyor. Daha güzel olmasını istiyorsanız, taşıma öncesi / sonrası taşıma iadeleri için 4 karakter ekleyin:

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

Teşekkürler!


1

Bash, 32 bayt

read a;echo $((a*(a-1>>1)+1>>1))


1

Toplu, 30 bayt

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

Stdin girişi gerekiyorsa 38 bayt:

@set/pa=
@cmd/cset/a(a*((a-1)/2)+1)/2
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.