Kılavuzda kaç tane dikdörtgen var?


29

Her ne kadar bu zorluğun büyük bir başarı olduğu ortaya çıksa da çözülmesi çok önemsiz olduğu ortaya çıktı. Bu nedenle, daha fazla zorluk arayanlar için, şimdi benzersiz dikdörtgenlerin sayısını saymanız gereken bu mücadelenin bir devamı oluşturdum . Bunu kontrol et!

Şimdi, bu zorluğu çözmek isteyenler için , işte geliyor.


Henüz böyle bir zorlukla karşılaşmadık, işte başlıyoruz.

Bu 3 x 3dikdörtgen ızgarayı göz önünde bulundurun :

Example

Kaç tane dikdörtgen var? Görsel olarak sayarak, 36aşağıdaki animasyonlu GIF'te gösterilen, tüm düzlemin kendisi de dahil olmak üzere, aslında dikdörtgenlerin olduğunu görebiliriz :

Rectangles in Example

Görev

Yukarıda gösterildiği gibi dikdörtgenlerin sayılması görevdir. Diğer bir deyişle, daha fazla 2 tamsayı verilen ya da eşit 0, mve nburada, mgenişliği temsil eder ve nçıkış olup, bu dikdörtgenler sayısı yüksekliğini temsil eder m x ndikdörtgenler ızgara.

kurallar

  • Bu sorunu doğrudan çözen tümleşik yapıların kullanımı açıkça reddedilir.

  • Bu zorluk, en kısa cevabı bulmak değil, her dilde en kısa cevabı bulmakla ilgilidir. Bu nedenle, hiçbir cevap kabul edilmeyecektir.

  • Standart boşluklar yasaktır.

Test Kılıfları

Biçiminde sunulan Array of Integers Input -> Integer Output:

[0,0] -> 0
[1,1] -> 1
[3,3] -> 36 (Visualized above)
[4,4] -> 100
[6,7] -> 588

Referanslar

Unutmayın, bu , bu yüzden en kısa kod kazanır!


588Son test için hesapladım .
Sızdıran Rahibe,

@LeakyNun O zaman, sanırım onları sayarken biraz özledim . Sabitlendi.
R. Kap,

Girişin maksimum değeri nedir?
Outgolfer'lı Erik,

Yanıtlar:


34

Python, 22 bayt

lambda m,n:m*~m*n*~n/4

Formül m*n*(m+1)*(n+1)/4bit tamamlayıcı kullanılarak kısaltılmaktadır ~m=-(m+1)eksprese (m+1)*(n+1)olarak ~m*~n.

Dikdörtgenlerin sayısı neden m*n*(m+1)*(n+1)/4? Her dikdörtgen, iki yatay çizgi (üst ve alt) ve iki dikey çizgi (sol ve sağ) seçimi ile belirlenir. Orada m+1iki ayrı olanlar bir alt kümesini seçmek üzere yatay çizgiler. Yani seçim sayısı choose(m+1,2), ki öyle m*(m+1)/2. n*(n+1)/2Dikey çizgiler için seçeneklerle çarpma sonucu verir.


Bu +1 numarası harika.
David Ljung Madison Stellar

11

Jöle , 4 bayt

RS€P

Çevrimiçi deneyin!

Alternatif olarak, ayrıca 4 bayt

pP€S

Çevrimiçi deneyin!


Aferin. Başparmak havaya. :)
R. Kap

24
Açıklamak ister misin?
Pureferret

Da var בHPve ‘c2Pbelki diğer 4 bayt alternatifleri.
mil:

1
@Pureferret Bu, OEIS'in formülünü, bunun nthve mthüçgen sayının çarpımı olarak kullanır . R1 bazlı endeks içine her numarayı çevirir: [1, 2, ..., n]. Stoplamı olduğu anlamına gelir 'den her biri, her liste toplanır, böylece, böyle bir listesini verir: [nth triangle number, mth triangle number]. Ardından P, istenen sonucu veren listenin ürününü alır.
FryAmTheEggman

1
@FryAmTheEggman ne diyorsunuz .... Sihirli
Pureferret


9

Mathematica, 15 bayt

##(1##+##+1)/4&

Bu, iki tamsayı argümanı alan ve dikdörtgen sayısını döndüren adsız bir fonksiyondur.

açıklama

Uygulama temel olarak, iki üçgen sayının çarpımının çok golf gibi bir halidir. Detaylar için bu yazıdaki "Argümanların Dizileri" bölümünü okumak faydalı olabilir , ancak özeti burada özetlemeye çalışacağım.

##Tüm argümanların bir dizisine genişler . Bu, diğer dillerde sıçramaya benzer . Mesela, eğer argümanlar ise, 3ve 4sonra {1, 2, ##, 5}size verecektir {1, 2, 3, 4, 5}. Ama bu listelerde sadece işi değil, ama herhangi bir ifadede, örneğin f[1, 2, ##, 5]da olurdu f[1, 2, 3, 4, 5].

##Operatörler ile birleştirdiğinizde bu ilginçleşiyor . Mathematica’daki tüm operatörler, benzer f[...]ifadelerin (muhtemelen yuvalanmış) kısa yollarını gösterir. Örneğin a+b, aslında Plus[a, b]ve a-btemsil eder Plus[a, Times[-1, b]]. Artık ##operatörlerle bir araya geldiğinde , Mathematica'nın yaptığı şey, önce operatörleri genişletmek, ##tek bir operatör gibi davranmak ve yalnızca sonunda genişletmektir. Ekleyerek ##doğru yerlerde, bu nedenle her iki çoğalmaya kullanabilir ve işlenen ekleyin.

Bunu yukarıdaki kod için yapalım:

##(1##+##+1)/4

Tam biçimine genişleterek, şunu elde ederiz:

Times[##, Plus[Times[1, ##], ##, 1], Rational[1/4]]

İşlev değişkenlerini ekleyelim ave b:

Times[a, b, Plus[Times[1, a, b], a, b, 1], Rational[1/4]]

Ve şimdi tekrar standart matematiksel gösterime dönüştürüyoruz:

a * b * (a * b + a + b + 1) / 4

Küçük bir yeniden düzenleme, bunun üçgen sayıların ürünü olduğunu gösteriyor:

a * b * (a + 1) * (b + 1) / 4
(a * (a + 1) / 2) * (b * (b + 1) / 2)
T(a) * T(b)

Eğlenceli gerçek: Bu uygulama çok golf gibi, tek bir üçgen sayı hesaplamak için kullanılan ile aynı uzunlukta PolygonalNumber.


8

C, 25 bayt

#define r(x,y)x*y*~x*~y/4

Saf sürüm (27):

r(x,y){return x*y*~x*~y/4;}

ISO-er sürümü (35):

#define r(x,y)((x)*(y)*~(x)*~(y)/4)

Sizce hangi versiyon en iyisidir?
Outgolfer'lı Erik,

8

Denizanası , 16 bayt

p|%/**+1
  4  Ei

Giriş formatı [x y], çıktı sadece sonuçtur.

Çevrimiçi deneyin!

Alternatif çözüm, aynı bayt sayısı:

pm%/*[*i
  4  +1

açıklama

Jellyfish'e hak ettiği tanıtımı yapma zamanı! :)

Denizanası, 2D sözdizimi mücadelesine dayanan Zgarb'ın dilidir . Anlambilim büyük ölçüde J'den ilham alıyor, ancak sözdizimi bir sanat eseri. Tüm fonksiyonlar tek karakterlerdir ve bir ızgarada düzenlenmiştir. İşlevler argümanlarını bir sonraki belirteçten güney ve doğusundan alır ve sonucu kuzey ve batıya döndürür. Bu, değerleri yeniden kullanmak istediğinizde, birden çok yönden çeşitli fonksiyonlara geçirerek ilginç bir fonksiyon çağrıları ağı oluşturalım.

Yukarıdaki programdaki bazı belirteçlerin özel operatörler (üst düzey işlevler) olduğu gerçeğini görmezden gelirsek, yukarıdaki program aklı başında bir dilde böyle bir şey yazılır:

p(|( /*(i*(i+1)) % 4 ))

Kod aşağıdan yukarıya geçelim. Girdi i, bu nedenle değerlendiren tarafından beslenir [x y].

+Bunun üst sabitin ile birlikte, bu girdi alır 1ve bu nedenle elde her iki elemanı artırır [(x+1) (y+1)](çoğu işlemleri listeler üzerinde otomatik olarak dişli edilmiştir).

Diğer değeri isola gönderilir, ancak Ebölmeler kuzey ve batıdaki doğu argümanıdır. Bu, sağdaki girdilerin *gerçekte olduğu [x y]ve [(x+1) (y+1)]dolayısıyla bunun hesaplandığı anlamına gelir [x*(x+1) y*(y+1)].

Bir sonraki *yukarı aslında /onu bir katlama işlemine dönüştüren öncekiyle değiştirilir . Katlanabilir *aldığımız böylece, sadece çarpar onu bir çift üzerinde x*(x+1)*y*(y+1).

Şimdi %sadece bölünme olduğu için hesaplar x*(x+1)*y*(y+1)/4. Maalesef, bu bir sonuçlandırmaya neden oluyor, bu yüzden onu birliği ile yuvarlamamız gerekiyor |. Son olarak, bu değer pnihai sonucu basan beslenir .


Doktorlarda tamsayı bölme ile ilgili bir şeyler okuduğuma yemin edebilirdim ...
Conor O'Brien

7

R, 40 35 bayt

Eh, derin sonuna atlamak için zaman! İşte benim R kodum, @xnor cevabından ilham alan:

a=scan();(n=a[1])*(m=a[2])*(n+1)*(m+1)/4 

EDIT : Bu versiyonda, R girişler için iki kez soracaktır.

(n=scan())*(m=scan())*(n+1)*(m+1)/4

cat(prod(choose(scan()+1,2)))29 bayttır.
Giuseppe

6

CJam, 12 10 Bayt

Martin sayesinde 2 bayt kaydedildi.

{_:)+:*4/}

Çevrimiçi deneyin!

Bu, yığından 2 öğenin bir listesini alan ve çözümü yığında bırakan bir bloktur. Test için Kullanılabilir tam programı: riari+{_:)+:*4/}~.

Xnor'ın üstün python çözümünden yola çıkarak.

Açıklama:

{_:)+:*4/}
{        } -- Define a block
 _:)       -- Duplicate list, increment all values in new list
    +      -- Join the two lists
     :*    -- Fold multiply over all 4 elements
       4/  -- Divide by 4

2
İki öğenin bir listesini yaparsanız, bunun 10 için işe yaradığını düşünüyorum? {_:~+:*4/}
Martin Ender

Aslında, hiç ~CJam'da kullanmaya gerek yok . Sadece kullan ).
Martin Ender

5

Matlab, 23 19 bayt

@(x)prod([x/2,x+1])

m*n*(m+1)*(n+1)/4
Kullanım formülünün uygulanması :ans([m,n])


4

MATL , 6 bayt

tQ*2/p

Giriş, formun bir dizisidir [m,n].

Çevrimiçi deneyin!

açıklama

Formüle dayalı doğrudan hesaplama m*(m+1)*n*(n+1)/4.

t     % Input array [m,n] implicitly. Duplicate
Q     % Add 1 to each entry of the copy: gives [m+1,n+1]
*     % Multiply element-wise: gives [m*(m+1),n*(n+1)]
2/    % Divide each entry by 2: [m*(m+1)/2,n*(n+1)/2]
p     % Product of the two entries: m*(m+1)*n*(n+1)/4. Display implicitly


4

Java 7, 39 38 bayt

int c(int a,int b){return~a*a*b*~b/4;}

Java 8, 26 25 19 18 17 bayt

a->b->a*~a*b*~b/4

Dayanarak @xnor 'mükemmel cevap bu . Sayesinde birden fazla bayt kaydedildi@DavidConrad . Burada dene.

Test kodu (Java 7):

Burada dene.

class M{
  static int c(int a,int b){return~a*a*b*~b/4;}

  public static void main(String[] a){
    System.out.println(c(0, 0));
    System.out.println(c(1, 1));
    System.out.println(c(3, 3));
    System.out.println(c(4, 4));
    System.out.println(c(6, 7));
  }
}

Çıktı:

0
1
36
100
588

1
Buna ihtiyacınız yok returnve a->b->bir bayttan daha kısa (a,b)->.
David Conrad,

2
Ben yok düşünmek size aldı bir yöntem haline lambda geçen olsaydı beri ya, noktalı virgül ihtiyaç Function<Integer, Function<Integer, Integer>>parametre olarak, bir noktalı virgül ardından olmaz.
David Conrad

2
@DavidConrad ile hemfikirim: ;Tekli J8 lambda ifadesinin sonunu saymıyorum .
CAD97

@DavidConrad Çok geç düzenlemeye üzüldüm, ancak yalnızca şimdi kaldırdım yorumunuzu okuduğumu fark ettim return . Ayrıca, neredeyse hiç Java 8 programlamamıştım (dolayısıyla tüm Java 7 cevaplarım), ancak nasıl a->b->çalışabilirim? İşte mevcut dava için ideone.
Kevin Cruijssen 21:16

1
Çok geç cevap verdiğim için özür dilerim! Eğer değişime ihtiyaç, böylece işlevini köri gerek MathOperation.operationtek almaya int, bir dönüş Function<Integer, Integer>ve bunu çağırdığınızda, başlangıçta sadece ilk parametre olarak geçirmek, ave sonra çağrı .apply(b)üzerine Function. Ayrıca içe aktarmanız gerekir java.util.function.Function. İşte değişikliklerin olduğu bir ideone.
David Conrad

3

Ruby, 22 bayt

@ Xnor'ın numarasını çalmak ve stabby-lambda yapmak:

r=->(m,n){m*n*~m*~n/4}

Örnek çağrı:

r[6,7]     # => 588

Veya bir proc olarak, ayrıca 22 bayt:

proc{|m,n|m*n*~m*~n/4}

O zaman arayabiliriz ki:

proc{|m,n|m*n*~m*~n/4}.call(6,7)     # => 588

İsimlendirmene gerek yok - anonim işlevler site kurallarına göre tamam
Conor O'Brien

3

Labirent , 13 11 bayt

*?;*_4/!
):

Çevrimiçi deneyin!

açıklama

Bu aynı zamanda çoğu cevap gibi üçgen sayıların çarpımını da hesaplar. Önde gelen 2x2 bloğu küçük bir döngüdür:

*?
):

İlk yineleme *hiçbir şey yapmaz, böylece gerçek döngü sırası şudur:

?   Read integer N from STDIN or 0 at EOF and push onto stack. If 0, exit the loop.
:   Duplicate N.
)   Increment.
*   Multiply to get N*(N+1).

Kalan kod sadece doğrusaldır:

;   Discard the zero that terminated the loop.
*   Multiply the other two values.
_4  Push a 4.
/   Divide.
!   Print.

Labirent daha sonra /tekrar çalıştırılmaya çalışır , bu da programı sıfıra bölme nedeniyle sonlandırır.


2

Pyke, 6 bayt

mh+Bee

Burada dene!

mh     -    map(increment, input)
  +    -   ^ + input
   B   -  product(^)
    ee - ^ \ 4

Bu bir arızaya yol açabilir ama ben şahsen bir sanat eseri olarak buluyorum.
corsiKa

2

05AB1E, 4 bayt

€LOP

açıklama

A096948'de açıklanan formülü kullanır

      # Implicit input, ex: [7,6]
€L    # Enumerate each, [[1,2,3,4,5,6,7],[1,2,3,4,5,6]]
  O   # Sum, [28,21]
   P  # Product, 588
      # Implicit display

Girişi [n, m] olarak alır .

Çevrimiçi deneyin


1

Pyth, 8 6 bayt

@DenkerAffe sayesinde iki bayt kurtarıldı.

*FmsSd

Gibi bir liste olarak giriş bekleniyor [m,n] . Burada dene .

Açıklama:

          Implicit assignment of Q to eval(input).
*         Multiplication.
 F        Splat the following sequence onto the arguments of the previous function.
  m       Map the following function of d over Q (Q is implicitly added to the end).
   s      Reduce the following list with addition, initial value of 0.
    Sd    Return range(1,d+1).

1
Bunun Fyerine kullanabilirsiniz .*ve Qdolaylı olarak eklendiğinden beri kaldırabilirsiniz .
Denker

Biliyordum Fama nasıl kullanacağımı bulamadım ve kullanmam gerektiğini düşündüm .*... Teşekkürler!
Rhyzomatic

1

C #, 19 bayt

(n,m)=>m*n*~m*~n/4;

@ Xnor'ın cevabına dayanan isimsiz bir fonksiyon.


1

Lua, 74 63 bayt

x,y=...n=0 for i=1,y do for j=i,i*x,i do n=n+j end end print(n)

İşlev, sayı parametresi olarak girdi alır.

Lua'nın uygulanma biçimi nedeniyle, bu teknik olarak, bir "function" deyimine sarılarak ya da "loadstring" kullanarak kaynak kodundan yükleyerek çağrılabilen değişken argalı bir fonksiyondur


1
Sadece G / Ç için oldukça fazla kodunuz olduğunu görüyorum. Belki de sadece iki sayı alan ve yanıtı döndüren bir işlev yapmak ve tüm bu gereksiz I / O kodunu kaldırmak daha kısa olacaktır.
Zwei

@Zwei Ben işlevlerin parametrelerle girdi almalarına izin verildiğini unuttum. Gösterdiğin için teşekkürler.
brianush1

İşlev, 7 bayttan daha fazla tasarruf etmek için "işlev" yerine "f" gibi bir ad verebilir
Zwei

Lua'da, bir işlevi bildirmek için "function" anahtar sözcüğü gereklidir. İsim belirtilmemişse (örn: "f ()" işlevi), adsız bir işlevdir. (örn: "function ()"). Bu nedenle, kodun çalışması için "işlev" gerekir.
brianush1

Oh, Lua'nın böyle çalıştığını unuttum. Benim hatam!
Zwei


1

Brain-Flak , 84 80 bayt

({}<>)({({})<({}[()])>}{})<>({({})<({}[()])>}{}[()]){<>(({}))<>({}[()])}<>({{}})

Çevrimiçi deneyin!

Muhtemelen çok alt-optimal, özellikle de üçgen sayılarıyla ilgili kodun yeniden kullanılması nedeniyle, ama en azından işe yarayan bir Brain-Flak çözümümüz var.

Maalesef 0 0testcase ile sınırsız bir şekilde dolaşarak başarısız gözüküyor ama diğerleri iyi çalışıyor.


0

Dışbükey, 7 bayt

Bunun daha küçük olabileceğini biliyorum, henüz nasıl olduğunu çözemiyorum ...

_:)+×½½

Çevrimiçi deneyin! . CP-1252 kodlamasını kullanır.



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.