ASCII kutularının hacimleri


40

Giriş

Bu zorlukla, bir dikdörtgen küboidin (3B kutu) ağının (katlanmamış yüzey) ASCII gösterimi olarak girilir . Bu format:

....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......

Küboid'in her yüzü, karakterlerle #çevrili bir dikdörtgendir +-|. Ağın dış tarafı .s ile doldurulur . Ağ her zaman aynı yönelime sahip olacaktır: dört komşu yüzü ile çevrili bir orta yüz vardır ve orta yüzün karşılığı, girişin sağ sınırındadır. Giriş, .s ile dikdörtgen şeklindedir ve fazladan .s veya s sütunu içermez .

Görev

Göreviniz, yukarıdaki gibi bir şema olarak girdi almak ve sadece yüksekliği, genişliği ve derinliğinin ürünü olan temsil ettiği küboidin hacmini hesaplamak. Girdiyi yeni satırla ayrılmış bir dize veya bir dize dizisi olarak alabilirsiniz.

Her bir kenarın uzunluğu +, iki ucundaki karakterlerin arasındaki mesafedir . Örneğin, yatay kenarın +--+uzunluğu 3 ve dikey kenarın

+
|
|
|
+

uzunluğu 4'tür. Minimum kenar uzunluğu 1'dir. Yukarıdaki örnek küboid hacmi 2 * 3 * 4 = 24'tür.

Kurallar ve puanlama

Tam bir program veya fonksiyon yazabilirsiniz ve en düşük bayt sayısı kazanır.

Test durumları

.++..
+++++
+++++
.++..
1

...++....
...||....
...||....
+--++--++
+--++--++
...||....
...||....
...++....
3

..+-+....
..|#|....
+-+-+-+-+
|#|#|#|#|
|#|#|#|#|
+-+-+-+-+
..|#|....
..+-+....
12

.+---+.....
++---++---+
||###||###|
||###||###|
||###||###|
++---++---+
.+---+.....
16

....++.....
....||.....
....||.....
....||.....
+---++---++
|###||###||
|###||###||
|###||###||
+---++---++
....||.....
....||.....
....||.....
....++.....
16

...+--+......
...|##|......
...|##|......
+--+--+--+--+
|##|##|##|##|
+--+--+--+--+
...|##|......
...|##|......
...+--+......
18

....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......
24

....+-----+..........
....|#####|..........
....|#####|..........
....|#####|..........
+---+-----+---+-----+
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
+---+-----+---+-----+
....|#####|..........
....|#####|..........
....|#####|..........
....+-----+..........
120

13
Bu meydan okumayı gerçekten seviyorum. Girdide çok fazla yedekli bir yapı bulunduğundan, boyutların nasıl kurtarılacağı konusunda birçok seçenek var.
xnor

Yanıtlar:


25

Retina , 29 28 bayt

T`.p`xy`\G\..+¶
xy

¶\|
$`
y

Çevrimiçi deneyin!

Bir var çok bu değil emin nasıl optimum değilim, ama zaten aslında bunun olacağını düşündüğümden çok daha kısa böylece hangi tarafı ile çarpın istediğiniz alan bağlı Retina bu yaklaşım yollardan.

Şu anda, aynı byte sayısında, yukarıdaki yaklaşımdan biraz daha fazla golf gibi görünen iki başka çözümüm daha var:

\G\..+¶

¶\|
$'¶
G`\.
T`.|+

¶\||\+¶\.\D+
$'¶
G`\.
T`.|+

Her ne kadar girdilerde sonda bir satır besleme ile bittiğini varsayarsak, her birinde bir bayt biriktirebildiğim halde, buna güvenmemeyi tercih ederim.

Ve bir diğeri, hala 28 baytta (bu aslında bir alanı bir tarafa çarpmak yerine üç tarafı çarpıyor):

\G\.
x
-(?<=^.+)
$`
¶\|
$`
x

açıklama

Ana fikir, yüzün üst tarafını girişin uzunluk sınırına değen dikey tarafın uzunluğu ile çarpmaktır.

Aşağıdaki girişi örnek olarak kullanacağım (yan uzunlukları 2, 3 ve 4, yani 24'lük bir alan):

...+---+.......
...|###|.......
...|###|.......
+--+---+--+---+
|##|###|##|###|
+--+---+--+---+
...|###|.......
...|###|.......
...+---+.......

Aşama 1: Harf Çevirisi

T`.p`xy`\G\..+¶

Regex \G\..+¶ile başlayan .ve hemen önceki satıra bitişik olan bir satırla eşleşir . Yani bu üst yüzü içeren tüm çizgilerle eşleşir. Sahne kendisi döner .içine xve diğer tüm karakterler (herhangi |+-#) içine y. Bu bize şu sonucu verir:

xxxyyyyyxxxxxxx
xxxyyyyyxxxxxxx
xxxyyyyyxxxxxxx
+--+---+--+---+
|##|###|##|###|
+--+---+--+---+
...|###|.......
...|###|.......
...+---+.......

Bunun, yüst yüzün alanını temsil etmemiz gerekenden daha fazla bir sütunu var . Bunu bir sonraki aşamada düzeltiriz.

Aşama 2: Değiştir

xy

Bu nedenle y, önce gelen x(bir satır başına tam olarak onlardan biri olan) öncekilerle eşleşir ve her ikisini de dizeden kaldırırız. Bunu anlıyoruz:

xxyyyyxxxxxxx
xxyyyyxxxxxxx
xxyyyyxxxxxxx
+--+---+--+---+
|##|###|##|###|
+--+---+--+---+
...|###|.......
...|###|.......
...+---+.......

Şimdi üst yüzün alanını ys sayısı ile temsil ettik .

Aşama 3: Değiştir

¶\|
$`

Buradaki amacımız, bu alanı bir satırın başlangıcındaki Asayı olan eksik kenar uzunluğuyla çarpmaktır |. Ancak, aslında bir sayı ile çarpmak daha kolaydır, n+1çünkü zaten Adizgede bir kopyasını aldık. . Bir nşeyleri değiştirirsek A, n+1kopyalarını alırız A. Bu bizim için işleri çok daha kolaylaştırıyor.

Bu yüzden |, maçtan hemen sonra her şeyi, maçtan hemen sonra yeniledik. Bu, dizeyi oldukça fazla tutar ve ihtiyaç duyduğumuzdan biraz daha büyük hale getirir, ancak ys sayısı aradığımız sonuç olarak ortaya çıkar:

xxyyyyxxxxxxx
xxyyyyxxxxxxx
xxyyyyxxxxxxx
+--+---+--+---+xxyyyyxxxxxxx
xxyyyyxxxxxxx
xxyyyyxxxxxxx
+--+---+--+---+##|###|##|###|
+--+---+--+---+
...|###|.......
...|###|.......
...+---+.......

Aşama 4: Eşleşme

y

Geriye kalan tek şey y, sonunda bir ondalık sayı olarak basılan s sayısını saymak .


15

Python 2, 57 bayt

lambda l:l[0].find('+')*~l[0].count('-')*~`l`.count("'|")

Dizeler listesinde yer alan bir işlev.

3 boyutu ayrı ayrı belirler:

l[0].find('+')
+İlk satırdaki ilk dizini .

-~l[0].count('-')
-İlk satırdaki işaretlerin sayısı .

~`l`.count("'|")
Sembolle başlayan satır sayısı |, listenin dize gösterimi ile ondan önce bir alıntı sembolüne sahiptir.


62 bayt:

def f(l):a=l[0].find('+');print(len(l[0])/2-a)*(len(l)-a+~a)*a

Dizelerin listesini alan ve sonucu basan bir işlev.

İlk satırın adizini olarak bir boyut bulur +. Diğer iki boyut, bunlardan ve giriş dikdörtgeni genişliğinden ve yüksekliğinden çıkarılır.

Boyutları ayrı ayrı bulmak için 63 baytlık bir alternatif:

lambda l:l[0].find('+')*~l[0].count('-')*~zip(*l)[0].count('|')

11

Bash + coreutils, 83, 77 bayt

DÜZENLEMELER:

  • "Here String" kullanarak ve bir bit regexp optimize ederek 6 bayt kaydedildi

golfed

bc<<<`sed -rn '1{s/(.+)[^\.]*\1/(0\1)*(0/
s/\./+1/gp;a)*(-1
}
/^[+|]/a+1
'`\)

Açıklaması

Sed ile dönüştür :

....+--+....... => (0+1+1+1+1)*(0+1+1+1 )*(-2 +1
. =>()
. =>()
. =>()
. =>()
+ => +1
| => +1
+ => +1
. =>()
. =>()
. =>()
. =>()

Backticks kullanarak yeni satırlardan kurtulun, ekleyin)

=> (0+1+1+1+1)*(0+1+1+1 )*(-2 +1 +1 +1 +1)

Elde edilen ifadeyi bc'ye besle

=> 24

Ölçek

./box <<EOF
.++..
+++++
+++++
.++..
EOF

1

./box <<EOF
...++....
...||....
...||....
+--++--++
+--++--++
...||....
...||....
...++....
EOF

3

./box <<EOF
....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......
EOF

24

Çevrimiçi deneyin! (ikincisi mevcut olmadığından bc yerine bash aritmetik genişlemesi kullanır)


10

Salyangoz , 19 bayt

AM
=~d^.+\+.+l.+^.2

Çevrimiçi deneyin.

Buradaki fikir, ağın en sağ kenarında bir yerden başlayıp, en alt yüzünde bir yere seyahat etmemiz. Kenarın uzunluğu ve yüzün alanı, eşleşen tüm yolları sayma mekanizmasıyla çarpılır.

AM   ,, A -> count all matching paths
     ,, M -> first char matched is the one in the current direction
     ,,      from the starting location, rather than directly on it
=~          ,, check that we are on the right edge of the grid
d ^.+ \+    ,, go down, matching one or more non-'.' characters, then a '+'
.+          ,, go down one or more times
l .+        ,, go left one or more times
^. 2        ,, match two further characters which aren't '.' to the left

4

JavaScript (ES6), 67 91

s=>(a=~-s.search`
`/2-(b=s.indexOf`+`))*b*(s.split`
`.length-1-2*b)

Ölçek

F=
s=>(a=~-s.search`
`/2-(b=s.indexOf`+`))*b*(s.split`
`.length-1-2*b)

out=x=>O.textContent+=x+'\n\n'

;`.++..
+++++
+++++
.++..
1

...++....
...||....
...||....
+--++--++
+--++--++
...||....
...||....
...++....
3

..+-+....
..|#|....
+-+-+-+-+
|#|#|#|#|
|#|#|#|#|
+-+-+-+-+
..|#|....
..+-+....
12

.+---+.....
++---++---+
||###||###|
||###||###|
||###||###|
++---++---+
.+---+.....
16

....++.....
....||.....
....||.....
....||.....
+---++---++
|###||###||
|###||###||
|###||###||
+---++---++
....||.....
....||.....
....||.....
....++.....
16

...+--+......
...|##|......
...|##|......
+--+--+--+--+
|##|##|##|##|
+--+--+--+--+
...|##|......
...|##|......
...+--+......
18

....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......
24

....+-----+..........
....|#####|..........
....|#####|..........
....|#####|..........
+---+-----+---+-----+
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
+---+-----+---+-----+
....|#####|..........
....|#####|..........
....|#####|..........
....+-----+..........
120`
.split('\n\n').forEach(t=>{
  t=t.split('\n')
  k=+t.pop()
  t=t.join('\n')
  v=F(t)
  out(v+' '+k +' '+(v==k?'OK':'KO')+'\n'+t)
})
<pre id=O></pre>


3

Ruby, 44

Diğer cevaplar benzer ilkesine İşleri: İlk bulmak +, derinlik bulmak için bir sonraki bulmak .sonra +genişliğini bulmak için, ve sayısını |satırın sonunda ve yüksekliğini bulmak için 1 ekleyin.

->s{(s=~/\+/)*($'=~/\./)*s.split("|
").size}

test programında ungolfed

f=->s{(s=~/\+/)*    # index of first match of /\+/ in s
($'=~/\./)*         # $' is a special variable, contains string to right of last match. index of /\./ in $' 
s.split("|
").size}            # split the string at |\n to form an array and count the members

puts f[".++..
+++++
+++++
.++.."]

puts f["...++....
...||....
...||....
+--++--++
+--++--++
...||....
...||....
...++...."]

#etc.

3

05AB1E , 21 bayt

Let Wve Hsırasıyla genişliği ve girişin yüksekliği - değil kutu. Ardından, kutu boyutları A, Bve Cbu kuralları uygulayın:

W = 2(A+C)+1
H = B+2C+1

Ne şu şekil gösterileri A, Bve Ckenar adlarına bakımından şöyledir:

....AAAA.......
....|##|.......
....|##|.......
....|##|.......
B---+--CCCCC--+
B###|##|###|##|
B---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......

Dolayısıyla yukarıdaki formüller. Bu program değerlerini hesaplar A, değerlerini deduces Bve Cnihayet onların ürünü hesaplar.

S'.ÊO<D¹g<;-(D·|g-()P

S'.Ê                  From each character of the first line, yield 0 if it is '.' or 1 otherwise. The result is stored in an array
    O<D               A = sum(array) - 1
       ¹g<;-(D        C = (W-1)/2 - A
              ·|g-(   B = H-1-2*C
                   )  Yield [A,C,B]
                    P Take the product and implicitly display it

Çevrimiçi deneyin!

Eski sürüm - Farklı yaklaşım - 26 bayt

|vyS'.Ê})¬O<sø¬O<s€O¬Ê1k)P

|                          Take the input as an array of lines (strings)
 vy                        For each line
   S'.Ê                    For each character in the line, yield 0 if it is '.' or 1 otherwise
       }                   End For
        )                  Wrap the results as an array
         ¬O<               A = sum(first_line) - 1
            sø             Transpose the box pattern
              ¬O<          B = sum(first_line) - 1 ; since the pattern is transposed, it corresponds to the first column
                 s€O       Sum every line from the transposed pattern
                    ¬Ê1k   C = index of the first line that has a different sum from the first line
                        )  Yield [A, B, C]
                         P Take the product A*B*C and implicitly display it

2

Befunge 93 , 56 bayt

~2%#^_1+
  @.*+<
`"z"~<|:`~0+
5*\`#^_\1>*\~7
%2~\<\+1_^#

Çevrimiçi Deneyin!

Açıklama:

Kutu hacmi sayısı ile çarpılarak hesaplanabilir .sayısına göre, herhangi bir diğer karakterler önce ilk satırda s +ve -1 ve ile başlayan hat sayısı - ilk satırda s |+ 1.

~2%#^_1+         Uses the ASCII value % 2 of a character to count the .s

%2~\<\+1_^#      IP wraps around to the bottom. Counts the non . chars
                 Works because ("+" % 2) == ("-" % 2) == 1

5*\`#^_\1>*\~7   Multiplies the previous 2 results and cycles through
                 characters until it hits a newline or EOF

`"z"~<|:`~0+     Adds 1 to the 3rd dimension if the following char is a "|"
                 Also checks for EOF; If there is more input, goes back to
                 previous line. Otherwise, goes to the last line

  @.*+<          Adds 1 to the 3rd dimension, multiplies it to the rest,
                 prints the volume, and ends the program

3. satırda düşey kullanmak için IP yerine aşağı doğru satırları taşımak zorunda kaldım. IP çizgilerden aşağıya doğru düşüyorsa, dikey ise yığının tepesini 1 olacak şekilde aşağıya doğru çekerek yanlış yönde gönderiyor.


2

Haskell, 64 56 bayt

f(x:r)=sum$fst(span(>'+')x)>>[1|'|':_<-"|":r,'-'<-'-':x]

Çevrimiçi deneyin!

açıklama

Girişin her satır için bir dize listesi olması beklenir, bu nedenle fparametrede xilk satır ve rkalan satırların bir listesidir.

  1. fst(span(>'+')x)döndürür ., böylece bir dize olarak ilk satırın -prefix length(fst(span(>'+')x))ilk boyuttur d1.
  2. Bir liste anlama filtre olarak işlev görebilir, örneğin ilk satırdaki ['-' | '-' <- x]hepsinin bir dizesini döndürür -, böylece 1 + length['-' | '-' <- x]ikinci boyutu verir d2.
  3. Benzer şekilde, |ilk satırdaki sayı sayılabilir, 1 + length['|' | '|':_ <- r]üçüncü boyut da aynıdır d3.

2. ve 3. liste kavrayışları, '-' veya '|' olaylarının her biri için bir liste oluşturularak 1+sum[1|'-'<-x]ve kısaltılabilir. 1+sum[1|'|':_<-r]ve sonra toplamı alıyor. Biz ayrıca dış koyabilirsiniz 1+ekleyerek liste anlama içine -etmek xve "|"hiç rverim sum[1|'-'<-'-':x]ve sum[1|'|':_<-"|":r]. Şimdi her iki öngörüyü de aynı anlama getirerek her iki liste anlaşmasını birleştirebiliriz: sum[1|'|':_<-"|":r,'-'<-'-':x]Uygun bir şekilde bu, iki boyutun ürününü tam olarak hesaplar çünkü listeler için Fve Gaşağıdaki liste kavrama Kartezyen ürünüdür F x G =[(a,b)|a<-F,b<-G].

Son olarak, 1. ve 2. kombinasyonu ile çarpma yerine, >>operatörü listelerde kullanabiliriz: süreleri F>>Gtekrarlar G length Fve sonucu birleştirir. Yani fst(span(>'+')x)>>[1|'|':_<-"|":r,'-'<-'-':x]listesini tekrarlar d2*d3olanları d1bir listesini elde zamanlarda d1*d2*d3ardından sesi almak için toplanır olanlar.


Giriş ihtiyacını ortadan kaldırarak dizgelerin bir listesi olarak alabilirsiniz lines.
Zgarb,

@ Zgarb Teşekkürler, bu bazı baytları kurtarır.
Laikoni,

1

Java 8, 185 129 bayt

-56 baytlık Zgarb sayesinde

golfed:

int g(String[]i){int h=0;for(String k:i){if(k.charAt(0)=='.')h++;else break;}return((i[0].length()-2*h-1)/2)*(i.length-2*h-1)*h;}

ungolfed:

int g(String[] i) {
    int h = 0;
    for (String k : i) {
        if (k.charAt(0) == '.') h++;
        else break;
    }
    return ((i[0].length()-2*h-1)/2)*(i.length-2*h-1)*h;
}

açıklama

a*b*h = ((length_of_line-2*h-1)/2)*(number_of_lines-2*h-1)*h

burada ave bbaz boyutları ve hyükseltir. A ile başladığınız hilk hsatırları sayarak bulabilirsiniz ..


Girdiyi bir dizi veya dizge olarak alabilirsiniz, bu nedenle manuel olarak bölmenize gerek yoktur.
Zgarb,

oops thx, onu tamir ediyor ...
Bobas_Pett

1

Java, 112 bayt

int v(String[]s){int a=s[0].lastIndexOf('+')-s[0].indexOf('+'),b=s[0].length()/2-a;return a*b*(s.length-2*b-1);}

Expanded:

int v(String[] s)
{
  // length of the edge in the first line
  int a = s[0].lastIndexOf('+') - s[0].indexOf('+');
  // length of the second edge
  // int b = s[0].length() - 2 * a - 1; <-- multiplied by 2
  int b = s[0].length()/2 - a; // <-- hack, length is always odd
  // length of the third edge in ()
  // volume
  return a * b * (s.length - 2 * b - 1);
} // end method v

1

Powershell, 68 67 bayt

($c="$args"|% i*f +)*($args[0].Length/2-.5-$c)*($args.Count-1-2*$c)

Not: "$args"|% i*f + kısayol edilir için"$args".indexOf('+')

açıklama

Osable'ın cevabından iyi bir açıklama geldi :

Let Wve Hsırasıyla genişliği ve girişin yüksekliği - değil kutu. Ardından, kutu boyutları A, Bve Cbu kuralları uygulayın:

W = 2(A+C)+1
H = B+2C+1

Ne şu şekil gösterileri A, Bve Ckenar adlarına bakımından şöyledir:

CCCCAAAA.......
....|##|.......
....|##|.......
....|##|.......
B---+--+---+--+
B###|##|###|##|
B---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......

Ve girişin ilk satırındaki Cilk pozisyondur +.

Test komut dosyası:

$f = {

($c="$args"|% i*f +)*($args[0].Length/2-.5-$c)*($args.Count-1-2*$c)

}

@(

,(1, ".++..",
     "+++++",
     "+++++",
     ".++..")

,(3,"...++....",
    "...||....",
    "...||....",
    "+--++--++",
    "+--++--++",
    "...||....",
    "...||....",
    "...++....")

,(12,"..+-+....",
     "..|#|....",
     "+-+-+-+-+",
     "|#|#|#|#|",
     "|#|#|#|#|",
     "+-+-+-+-+",
     "..|#|....",
     "..+-+....")

,(16,".+---+.....",
     "++---++---+",
     "||###||###|",
     "||###||###|",
     "||###||###|",
     "++---++---+",
     ".+---+.....")

,(16,"....++.....",
     "....||.....",
     "....||.....",
     "....||.....",
     "+---++---++",
     "|###||###||",
     "|###||###||",
     "|###||###||",
     "+---++---++",
     "....||.....",
     "....||.....",
     "....||.....",
     "....++.....")

,(18,"...+--+......",
     "...|##|......",
     "...|##|......",
     "+--+--+--+--+",
     "|##|##|##|##|",
     "+--+--+--+--+",
     "...|##|......",
     "...|##|......",
     "...+--+......")


,(24,"....+--+.......",
     "....|##|.......",
     "....|##|.......",
     "....|##|.......",
     "+---+--+---+--+",
     "|###|##|###|##|",
     "+---+--+---+--+",
     "....|##|.......",
     "....|##|.......",
     "....|##|.......",
     "....+--+.......")

,(120,"....+-----+..........",
      "....|#####|..........",
      "....|#####|..........",
      "....|#####|..........",
      "+---+-----+---+-----+",
      "|###|#####|###|#####|",
      "|###|#####|###|#####|",
      "|###|#####|###|#####|",
      "|###|#####|###|#####|",
      "+---+-----+---+-----+",
      "....|#####|..........",
      "....|#####|..........",
      "....|#####|..........",
      "....+-----+..........")

) | % {
    $expected,$s = $_
    $result = &$f @s
    "$($result-eq$expected): $result"
}

Çıktı:

True: 1
True: 3
True: 12
True: 16
True: 16
True: 18
True: 24
True: 120

0

Wolfram Dili (Mathematica) , 64 bayt

(2(x=#@"
")-(y=#@"|")-9)((9-5x+y)^2-9#@".")/54&@*CharacterCounts

Çevrimiçi deneyin!

Sayısını kullanır ., |ve \ngirişteki karakterler hacmi için çözmek için. Aptal görünüyor çünkü yerine yeni bir satır var \n.

Eğer A,, Bve Cyanlarsak, o zaman . = 2C(A+2C), | = 5B+4C-9ve \n = B+2C, öyleyse hacim için ABCbu üç karakter sayımı ile çözebiliriz .

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.