Wprowadzenie
W tym wyzwaniu otrzymujesz jako dane wejściowe reprezentację ASCII siatki (rozłożonej powierzchni) prostokątnego prostopadłościanu (ramka 3D). Format jest następujący:
....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......
Każda twarz prostopadłościanu jest prostokątem #
s otoczonym +-|
-znakami. Zewnętrzna część siatki jest wypełniona .
s. Sieć zawsze będzie miała tę samą orientację: środkowa ściana otoczona jest czterema sąsiadującymi ścianami, a odpowiednik środkowej ściany znajduje się po prawej stronie wejścia. Dane wejściowe są wypełnione .
s do kształtu prostokąta i nie będą zawierać dodatkowych wierszy ani kolumn .
s.
Zadanie
Twoim zadaniem jest wziąć jako dane wejściowe diagram jak wyżej i obliczyć objętość prostopadłościanu, który reprezentuje, który jest tylko iloczynem jego wysokości, szerokości i głębokości. Możesz wziąć dane wejściowe jako ciąg rozdzielany znakiem nowej linii lub tablicę ciągów.
Długość każdej krawędzi to odległość między +
znakami na dwóch końcach. Na przykład krawędź pozioma +--+
ma długość 3, a krawędź pionowa
+
|
|
|
+
ma długość 4. Minimalna długość krawędzi wynosi 1. Przykładowy prostopadłościan powyżej ma objętość 2 * 3 * 4 = 24.
Zasady i punktacja
Możesz napisać pełny program lub funkcję, a wygrywa najniższa liczba bajtów.
Przypadki testowe
.++..
+++++
+++++
.++..
1
...++....
...||....
...||....
+--++--++
+--++--++
...||....
...||....
...++....
3
..+-+....
..|#|....
+-+-+-+-+
|#|#|#|#|
|#|#|#|#|
+-+-+-+-+
..|#|....
..+-+....
12
.+---+.....
++---++---+
||###||###|
||###||###|
||###||###|
++---++---+
.+---+.....
16
....++.....
....||.....
....||.....
....||.....
+---++---++
|###||###||
|###||###||
|###||###||
+---++---++
....||.....
....||.....
....||.....
....++.....
16
...+--+......
...|##|......
...|##|......
+--+--+--+--+
|##|##|##|##|
+--+--+--+--+
...|##|......
...|##|......
...+--+......
18
....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......
24
....+-----+..........
....|#####|..........
....|#####|..........
....|#####|..........
+---+-----+---+-----+
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
+---+-----+---+-----+
....|#####|..........
....|#####|..........
....|#####|..........
....+-----+..........
120
Odpowiedzi:
Retina ,
2928 bajtówWypróbuj online!
Istnieje wiele sposobów podejścia do tego w Retinie, w zależności od tego, który obszar chcesz pomnożyć przez którą stronę, więc nie jestem pewien, jak optymalne jest to, ale w rzeczywistości jest już znacznie krótsze, niż się spodziewałem.
Obecnie mam dwa inne rozwiązania o tej samej liczbie bajtów, które wydają się nieco bardziej grywalne niż powyższe podejście:
Chociaż w każdym z nich mogę zapisać bajt, jeśli założę, że dane wejściowe kończą się końcowym podawaniem linii, ale wolałbym nie polegać na tym.
I jeszcze jeden, wciąż o 28 bajtach (ten w rzeczywistości mnoży trzy strony zamiast mnożenia jednego obszaru przez bok):
Wyjaśnienie
Główną ideą jest pomnożenie obszaru twarzy na górze przez długość pionowej strony, która dotyka granicy długości wejścia.
Jako przykład wykorzystam następujące dane wejściowe (ma długości boków 2, 3 i 4, czyli obszar 24):
Etap 1: Transliteracja
Wyrażenie regularne
\G\..+¶
dopasowuje linię rozpoczynającą się od.
i bezpośrednio przylegającą do poprzedniej linii. To pasuje do wszystkich linii zawierających górną ścianę. Sama scena zamienia się.
wx
i wszystkie inne postacie (dowolne|+-#
) wy
. To daje nam następujący wynik:Ma jeszcze jedną kolumnę,
y
niż potrzebujemy, aby przedstawić obszar górnej powierzchni. Naprawiamy to w następnym etapie.Etap 2: Wymień
Dopasowujemy więc
y
poprzednikx
(który jest dokładnie jednym z nich w wierszu) i usuwamy je oba z ciągu. Otrzymujemy to:Mamy teraz obszar górnej powierzchni reprezentowany przez liczbę
y
s.Etap 3: Wymień
Naszym celem jest pomnożenie tego obszaru
A
przez brakującą długość boku, czyli liczbę|
na początku wiersza plus 1. Jednak w rzeczywistości łatwiej jest pomnożyć przez liczbę,n+1
ponieważ mamy już jedną kopięA
ciągu . Jeśli zastąpimyn
rzeczyA
, otrzymamyn+1
kopieA
. To nam znacznie ułatwia.Więc po prostu zastępujemy dowolne
|
bezpośrednio po wysunięciu linii wszystkim przed meczem. Spowoduje to, że struna dość mocno i sprawia, że jest ona nieco większa niż potrzebujemy, ale liczbay
s kończy się wynikiem, którego szukamy:Etap 4: Mecz
Pozostało tylko policzyć liczbę
y
s, która jest drukowana jako liczba dziesiętna na końcu.źródło
Python 2, 57 bajtów
Funkcja, która przyjmuje listę ciągów.
Określa 3 wymiary osobno:
l[0].find('+')
Indeks pierwszego
+
w pierwszym rzędzie.-~l[0].count('-')
Liczba
-
znaków w pierwszym rzędzie.~`l`.count("'|")
Liczba wierszy rozpoczynających się od
|
symbolu, poprzez ciąg znaków reprezentujący listę z symbolem cytatu przed nią.62 bajty:
Funkcja, która pobiera listę ciągów i wypisuje wynik.
Znajduje jeden wymiar
a
jako indeks+
w pierwszym wierszu. Pozostałe dwa wymiary są z niego wywnioskowane oraz szerokość i wysokość prostokąta wejściowego.63-bajtowa alternatywa polegająca na oddzielnym określaniu wymiarów:
źródło
Bash + coreutils,
83, 77 bajtówEDYCJE:
Grał w golfa
Wyjaśniono
Przekształć za pomocą sed :
Pozbądź się nowych linii, używając backticków, dołącz)
Wprowadź wynikowe wyrażenie do bc
Test
Wypróbuj online! (używa rozszerzenia arytmetycznego bash zamiast bc , ponieważ ten ostatni nie jest dostępny)
źródło
Ślimaki , 19 bajtów
Wypróbuj online.
Chodzi o to, że zaczynamy gdzieś na skraju prawej krawędzi w sieci, a następnie udajemy się gdzieś w dolną ścianę. Długość krawędzi i powierzchnia twarzy są mnożone przez mechanizm zliczania wszystkich pasujących ścieżek.
źródło
JavaScript (ES6), 67
91Test
źródło
Ruby, 44
Działa na zasadzie podobnej do innych odpowiedzi: znajdź pierwszą,
+
aby znaleźć głębokość, znajdź następną.
po,+
aby znaleźć szerokość i policz liczbę|
na końcu linii i dodaj 1, aby znaleźć wysokość.nie wziął udziału w programie testowym
źródło
05AB1E , 21 bajtów
Niech
W
iH
będzie odpowiednio szerokością i wysokością danych wejściowych - nie pudełkiem. Następnie, wymiary skrzyniA
,B
aC
według poniższych zasad:Poniższy rysunek pokazuje co
A
,B
iC
są, w zakresie nazw brzegowych:Stąd powyższe formuły. Ten program Oblicza
A
, dedukuje wartościB
iC
wreszcie oblicza swój produkt.Wypróbuj online!
Poprzednia wersja - Inne podejście - 26 bajtów
źródło
Befunge 93 , 56 bajtów
Wypróbuj online!
Wyjaśnienie:
Objętość pudełka można obliczyć mnożąc liczbę
.
sekund na pierwszej linii przed wszelkimi innymi postaciami, przez liczbę+
i-
s na pierwszej linii - 1, oraz liczbę wierszy, które zaczynają się od|
+ 1.Musiałem przesunąć IP w górę, zamiast w dół, aby użyć pionu, jeśli w 3. linii. Jeśli adres IP spadał w dół, pionowe if zmusiłoby górę stosu do 1, gdy trafi w następujący poziomo if, wysyłając go w złym kierunku.
źródło
Haskell,
6456 bajtówWypróbuj online!
Wyjaśnienie
Dane wejściowe powinny być listą ciągów dla każdej linii, więc w
f
parametrzex
jest pierwszy wiersz ir
lista pozostałych wierszy.fst(span(>'+')x)
zwraca.
prefiks pierwszej linii jako ciąg znaków, podobnielength(fst(span(>'+')x))
jak pierwszy wymiard1
.['-' | '-' <- x]
Zwraca ciąg wszystkiego-
w pierwszym wierszu, a więc1 + length['-' | '-' <- x]
zwraca drugi wymiard2
.|
można policzyć liczbę w pierwszym rzędzie, podobnie1 + length['|' | '|':_ <- r]
jak trzeci wymiard3
.Zrozumienie listy w punktach 2. i 3. można skrócić do
1+sum[1|'-'<-x]
i1+sum[1|'|':_<-r]
budując listę takich dla każdego wystąpienia „-” lub „|” a następnie biorąc sumę. Możemy dodatkowo umieścić zewnętrznej1+
do listy pojmowania przez dołączenie-
dox
i"|"
dor
otrzymującsum[1|'-'<-'-':x]
asum[1|'|':_<-"|":r]
. Teraz możemy połączyć oba zestawienia listowe, umieszczając oba predykaty w tym samym rozumieniu:sum[1|'|':_<-"|":r,'-'<-'-':x]
Dogodnie oblicza to dokładnie iloczyn dwóch wymiarów, ponieważ dla listF
iG
poniższym zestawieniem list jest produkt kartezjańskiF x G =[(a,b)|a<-F,b<-G]
.Wreszcie, zamiast mnożenia 1. przez kombinację 2. i 3. możemy skorzystać z
>>
operatora na listach:F>>G
powtarzaG
length F
czasy i łączy wynik.fst(span(>'+')x)>>[1|'|':_<-"|":r,'-'<-'-':x]
Powtarza więc listęd2*d3
tychd1
czasów, dając listęd1*d2*d3
tych, które są następnie sumowane w celu uzyskania objętości.źródło
lines
.Java 8,
185129 bajtówdzięki Zgarbowi za -56 bajtów
grał w golfa:
bez golfa:
Wyjaśnienie
a*b*h = ((length_of_line-2*h-1)/2)*(number_of_lines-2*h-1)*h
gdzie
a
ib
są wymiary podstawy ih
jest wysokość. Możesz znaleźćh
, licząc pierwszeh
linie, od których zaczynasz od.
.źródło
Java, 112 bajtów
Rozszerzony:
źródło
PowerShell,
6867 bajtówUwaga:
"$args"|% i*f +
jest skrótem do"$args".indexOf('+')
Wyjaśnienie
Dobre wyjaśnienie pochodzi z odpowiedzi Osable :
Niech
W
iH
będzie odpowiednio szerokością i wysokością danych wejściowych - nie pudełkiem. Następnie, wymiary skrzyniA
,B
aC
według poniższych zasad:Poniższy rysunek pokazuje co
A
,B
iC
są, w zakresie nazw brzegowych:I
C
jest pozycją pierwszego+
w pierwszym wierszu wejścia.Skrypt testowy:
Wynik:
źródło
Wolfram Language (Mathematica) , 64 bajty
Wypróbuj online!
Wykorzystuje szereg
.
,|
i\n
znaki na wejściu do rozwiązania dla objętości. Wygląda to głupio, ponieważ zamiast niego pojawiła się nowa linia\n
.Jeśli
A
,B
iC
są stronami, to. = 2C(A+2C)
,| = 5B+4C-9
i\n = B+2C
, więc możemy rozwiązać problem z objętościąABC
pod względem tych trzech liczb znaków.źródło