Üçgen Izgaralara Hizalama


18

Altıgen ızgaralar, son zamanlarda 2 boyutlu verilerle ilgili zorluklar için oldukça popüler bir bükülme haline geldi. Ancak, aynı derecede ilginç üçgen ızgaraların şimdiye kadar büyük oranda ihmal edildiği görülüyor. Bunu oldukça basit bir meydan okuma ile düzeltmek istiyorum.

İlk olarak, üçgen bir ızgarayı nasıl temsil ederiz? Aşağıdaki örneği düşünün (şimdilik doğru diyagramı dikkate almayın):

resim açıklamasını buraya girin resim açıklamasını buraya girin

Hücreler düzgün bir şekilde normal bir ızgaraya düşer (normal bir ızgara ile arasındaki fark sadece hangi hücrelerin bitişik olduğu kabul edilir):

1234567
89abcde
fghijkl
mnopqrs

Şimdi, sağ şemada gösterildiği gibi, üçgen bir ızgarada üç ana eksen vardır: yatay ve iki diyagonal.

Bunları ASCII ızgarasında vurgulamak:

AVAVAVA
VAabcAV
fVAiAVl
mnVAVrs

Meydan okuma

Üçgen bir ızgarayı temsil eden dikdörtgen bir dize verilir (sol üst köşenin yukarı dönük bir üçgen olduğu). Hücrelerin çoğu ., ancak tam olarak iki hücre olacaktır #, örneğin:

....#
.#...
.....

İkisinin #ızgaranın üç ekseninden herhangi biri boyunca hizalanıp hizalanmadığını belirleyin (yani, yukarıda vurgulanan üç yönden herhangi birinde tek bir sıra üzerinde olup olmadıkları). Bu örnek için cevap "hayır" dır.

STDIN (veya en yakın alternatif), komut satırı bağımsız değişkeni veya işlev bağımsız değişkeni ile girdi alarak ve sonucu STDOUT (veya en yakın alternatif), işlev dönüş değeri veya işlev (çıkış) parametresi aracılığıyla çıktı alarak bir program veya işlev yazabilirsiniz.

Girdi, satır beslemeleri veya başka bir uygun karakterle ayrılmış tek bir dize veya bir dize listesi olabilir. Sen yerine herhangi iki (tutarlı) yazdırılabilir ASCII karakterleri kullanabilir .ve #.

Çıkış, olmalıdır truthy vurgulanan hücreler hizalanmış olduğu takdirde bir değer ve falsy aksi değer.

Standart kuralları geçerlidir.

Test Durumları

Gerçek ızgaralar:

.#..#.

#
#

...........
...#.......
...........
...........
...........
.......#...
...........

...........
.......#...
...........
...........
...........
...#.......
...........

.#.........
...........
...........
...........
...........
.......#...
...........

...........
...#.......
...........
...........
...........
...........
.......#...

.........#.
...........
...........
...........
...........
...#.......
...........

...........
.......#...
...........
...........
...........
...........
...#.......

...........
.#.....#...
...........
...........
...........

Falsy ızgaraları:

#.....
.....#

.....#
#.....

...#.......
...........
...........
...........
...........
.......#...
...........

...........
...#.......
...........
...........
...........
...........
.........#.

.......#...
...........
...........
...........
...........
...#.......
...........

...........
.......#...
...........
...........
...........
...........
.#.........

Yanıtlar:


3

Salyangoz , 40 39 bayt

\#{z|=(ul.ul.`,l~a~)(l.a3|.a|d.ea5}.,\#
\# ,, eşleşme '#'
{
  z | ,, Herhangi bir oktinilear yönde dönün ya da diğer tüm şeyleri}
  = (,, Bu iddia başarılı olursa, başlangıç ​​hücresi "yukarı dönük üçgen" tir.
    ul.ul.`, ,, Bir hücre yukarı veya iki kez, herhangi bir sayıda sola gidin.
              ,, Bu ul.`2 veya ul.`2 + ile bir bayt daha kısa olmalıdır? fakat
              `` ayrıştırma arabasıdır.
    l ~ a ~ ,, Sınırların dışını sola ve kuzeydoğuya eşleştirerek sol üst hücrede olduğumuzu kontrol edin
  )
  (l.a3 | ,, Bir kez sola git, sonra yönü kuzeybatıya ayarla; veya
    .a | ,, Bir kez sağa (başlangıç ​​yönü) gidin, sonra yönü kuzeydoğuya ayarlayın; veya
    d.ea5 ,, Bir kez aşağı gidin, sonra yönü kuzeybatı veya kuzeydoğu olarak ayarlayın
}
., ,, İstediğiniz sayıda rastgele karakteri eşleştirin (geçerli yönde hareket ederek)
\# ,, eşleşme '#'

2

CJam, 47 bayt

Artık daha kısa bir çözüm olduğu için artık kendimi paylaşmaktan kendimi kötü hissetmiyorum. :) (Çoğunlukla 2D desen eşleştirme diliniz olmasa bile bunun özellikle zor olmadığını göstermek için ...)

qN%:eeee::f+:~{S&},2f<:P0f=P::+Xf|P::-Xf|]::=:|

Bu, yerine boşluklar #ve gerçekten de başka her şeyi kullanır ..

Tüm test senaryolarını çevrimiçi çalıştırın.

Kopyalamadan gerçekten nefret ediyorum P::+Xf|P::-Xf|ama şimdiye kadar ondan kurtulmak için hiçbir şey bulamadım.

açıklama

Kendiniz için bir çözüm bulmak istiyorsanız okumaya devam etmeyin.

İlk olarak, sıkıcı kısım: giriş ızgarasındaki iki boşluğun iki koordinat çiftini elde etmek:

qN%   e# Read input and split into lines.
:ee   e# Enumerate the characters in each line. I.e. turn each character 'x into a pair
      e# [N 'x] where N is its horizontal 0-based index.
ee    e# Enumerate the lines themselves, turning each line [...] into [M [...]] where M
      e# is its vertical 0-based index.
::f+  e# This distributes the vertical index over the individual lines, by prepending it
      e# to each pair in that line. So now we've got a 2-D array, where each character 'x
      e# has been turned into [M N 'x].
:~    e# Flatten the outermost dimension, so that we have a flat list of characters with
      e# their coordinates.
{S&}, e# Filter only those lists that contain a space.
2f<   e# Truncate the two results to only their first two elements.
:P    e# Store the result in P.

Şimdi ilginç olan kısım, bu koordinatların hizalanıp hizalanmadığının nasıl belirleneceğidir. Kodum üç eksenin tümünü ayrı ayrı hesaplar:

  • Yatay eksen önemsizdir. Dikey koordinatların eşleşip eşleşmediğini kontrol edin.
  • Kuzey-doğu diyagonaline bakalım. ASCII ızgarasında, her üç ızgara diyagonaline ait her zaman iki antidiagonal vardır:

    ....AV..
    ...AV...
    ..AV....
    

    Mevcut antidiagonali xve ykoordinatlarını toplayarak tanımlayabiliriz :

    01234567
    12345678
    23456789
    

    Yani isterdik 0 ve 1yanı sıra aynı Diagonal'da ait olduğu 2ve 3ve 4ve 5ve böyle devam eder. Bu, anti-diyagonal dizinimize sahip olduğumuzda, bir sonraki tek sayıya yuvarlamak istediğimiz anlamına gelir. Başka bir deyişle, bit ile VEYA ile alıyoruz 1. (Ayrıca bitwise AND ile bir sonraki çift sayıya yuvarlanabiliriz, -2ancak kodda daha pahalıdır.)

  • Şimdi güney-doğu köşegenleri:

    .VA.....
    ..VA....
    ...VA...
    

    Çaprazlara bir dizin vermek için için x, ykoordinattan çıkarırız (negatif sayıları harf olarak temsil eder):

    0abcdefg
    10abcdef
    210abcde
    

    Bu durumda, 0 ve 1yanı sıra aynı Diagonal'da ait olduğu -1ve -2ya 2ve 3. Bir kez daha, bir sonraki tek sayıya yuvarlamak istiyoruz.

İşte bunun için kod:

0f=  e# The coordinates are still on the stack. Replace each with its vertical coordinate
     e# to check for the horizontal axis.
P    e# Push the coordinates again.
::+  e# Sum each pair to get an anti-diagonal index.
Xf|  e# OR each index with 1 to round up to the next odd number.
P    e# Push the coordinates again.
::-  e# In each pair, subtract the horizontal coordinate from the vertical, to
     e# get a diagonal index.
Xf|  e# OR each index with 1.
]    e# Wrap all three index pairs in an array.
::=  e# Check equality for each pair.
:|   e# Fold bitwise OR over the results to check if at least one pair of indices
     e# was equal.
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.