Introdução
Neste desafio, você recebe como representação a representação ASCII da rede (superfície desdobrada) de um cubóide retangular (caixa 3D). O formato é este:
....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......
Cada face do cubóide é um retângulo de #
s cercado por +-|
caracteres. A parte externa da rede é preenchida com .
s. A rede sempre terá a mesma orientação: há uma face do meio cercada pelas quatro faces vizinhas e a contraparte da face do meio está na borda direita da entrada. A entrada é preenchida com .
s para uma forma retangular e não conterá linhas ou colunas extras de .
s.
A tarefa
Sua tarefa é tomar como entrada um diagrama como acima e calcular o volume do cubóide que ele representa, que é apenas o produto de sua altura, largura e profundidade. Você pode considerar a entrada como uma sequência delimitada por nova linha ou uma matriz de sequências.
O comprimento de cada aresta é a distância entre os +
caracteres em suas duas extremidades. Por exemplo, a borda horizontal +--+
tem comprimento 3 e a borda vertical
+
|
|
|
+
tem comprimento 4. O comprimento mínimo de uma aresta é 1. O exemplo cubóide acima tem volume 2 * 3 * 4 = 24.
Regras e pontuação
Você pode escrever um programa completo ou uma função, e a menor contagem de bytes vence.
Casos de teste
.++..
+++++
+++++
.++..
1
...++....
...||....
...||....
+--++--++
+--++--++
...||....
...||....
...++....
3
..+-+....
..|#|....
+-+-+-+-+
|#|#|#|#|
|#|#|#|#|
+-+-+-+-+
..|#|....
..+-+....
12
.+---+.....
++---++---+
||###||###|
||###||###|
||###||###|
++---++---+
.+---+.....
16
....++.....
....||.....
....||.....
....||.....
+---++---++
|###||###||
|###||###||
|###||###||
+---++---++
....||.....
....||.....
....||.....
....++.....
16
...+--+......
...|##|......
...|##|......
+--+--+--+--+
|##|##|##|##|
+--+--+--+--+
...|##|......
...|##|......
...+--+......
18
....+--+.......
....|##|.......
....|##|.......
....|##|.......
+---+--+---+--+
|###|##|###|##|
+---+--+---+--+
....|##|.......
....|##|.......
....|##|.......
....+--+.......
24
....+-----+..........
....|#####|..........
....|#####|..........
....|#####|..........
+---+-----+---+-----+
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
|###|#####|###|#####|
+---+-----+---+-----+
....|#####|..........
....|#####|..........
....|#####|..........
....+-----+..........
120
Respostas:
Retina ,
2928 bytesExperimente online!
Há muitas maneiras de abordar isso na Retina, dependendo de qual área você deseja multiplicar com qual lado, por isso não tenho certeza de como isso é ótimo, mas na verdade já é muito mais curto do que eu pensava.
Atualmente, tenho duas outras soluções na mesma contagem de bytes que parecem um pouco mais eficientes do que a abordagem acima:
Embora neles eu possa salvar um byte cada se assumir que a entrada termina com um avanço de linha à direita, mas prefiro não ter que confiar nisso.
E outro, ainda com 28 bytes (na verdade, este multiplica três lados em vez de multiplicar uma área por lado):
Explicação
A idéia principal é multiplicar a área da face no topo pelo comprimento do lado vertical que toca a borda de comprimento da entrada.
Usarei a seguinte entrada como exemplo (ela possui comprimentos laterais 2, 3 e 4, portanto, uma área de 24):
Etapa 1: Transliterar
A regex
\G\..+¶
corresponde a uma linha que começa com.
e é imediatamente adjacente à linha anterior. Portanto, isso corresponde a todas as linhas que contêm a face superior. O palco em si se.
transformax
e todos os outros personagens (qualquer um|+-#
) emy
. Isso nos dá o seguinte resultado:Isso tem mais uma coluna do
y
que precisamos para representar a área da face superior. Corrigimos isso com o próximo estágio.Etapa 2: substituir
Então, combinamos um
y
que é precedido por umx
(que é exatamente um deles por linha) e os removemos da string. Temos isso:Então agora temos a área da face superior representada pelo número de
y
s.Etapa 3: substituir
Nosso objetivo aqui é multiplicar essa área
A
pelo comprimento do lado que falta, que é o número de|
no início de uma linha mais 1. No entanto, é realmente mais fácil multiplicar por um número,n+1
porque já temos uma cópiaA
na string . Se substituirmos asn
coisas porA
, acabaremos comn+1
cópias deA
. Isso facilita muito as coisas para nós.Então, simplesmente substituímos qualquer
|
imediatamente após um avanço de linha por tudo à frente da partida. Isso manipula bastante a string e a torna um pouco maior do que precisamos, mas o número dey
s acaba sendo o resultado que estamos procurando:Etapa 4: partida
Tudo o que resta é contar o número de
y
s, que é impresso como um número decimal no final.fonte
Python 2, 57 bytes
Uma função que recebe uma lista de cadeias.
Determina as 3 dimensões separadamente:
l[0].find('+')
O índice do primeiro
+
na primeira linha.-~l[0].count('-')
O número de
-
sinais na primeira linha.~`l`.count("'|")
O número de linhas que começam com o
|
símbolo, através da representação em cadeia da lista que possui um símbolo de aspas antes dela.62 bytes:
Uma função que recebe uma lista de cadeias e imprime o resultado.
Localiza uma dimensão
a
como o índice de+
na primeira linha. As outras duas dimensões são inferidas a partir dele e a largura e altura do retângulo de entrada.Uma alternativa de 63 bytes, localizando as dimensões separadamente:
fonte
Bash + coreutils,
83, 77 bytesEDITAS:
Golfe
Explicado
Transforme com sed :
Livre-se das novas linhas usando backticks, acrescentar
Alimente a expressão resultante para bc
Teste
Experimente online! (usa expansão aritmética bash, em vez de bc , pois o último não está disponível)
fonte
Caracóis , 19 bytes
Experimente online.
A idéia é que começamos em algum lugar na extremidade mais direita da rede e depois viajemos para algum lugar na parte inferior. O comprimento da aresta e a área da face são multiplicados pelo mecanismo de contagem de todos os caminhos correspondentes.
fonte
JavaScript (ES6), 67
91Teste
fonte
Ruby, 44
Funciona de acordo com um princípio semelhante a outras respostas: encontre o primeiro
+
para encontrar a profundidade, encontre o próximo.
depois+
para encontrar a largura e conte o número|
no final da linha e adicione 1 para encontrar a altura.ungolfed no programa de teste
fonte
05AB1E , 21 bytes
Seja
W
eH
seja, respectivamente, a largura e a altura da entrada - não a caixa. Em seguida, as dimensões da caixaA
,B
eC
seguir estas regras:A figura a seguir mostra o que
A
,B
eC
são, em termos de nomes de ponta:Daí as fórmulas acima. Este programa calcula
A
, deduz os valores deB
eC
e, finalmente, calcula o seu produto.Experimente online!
Versão anterior - Abordagem diferente - 26 bytes
fonte
Abaixo 93 , 56 bytes
Experimente Online!
Explicação:
O volume da caixa pode ser calculado multiplicando o número de
.
s na primeira linha antes de qualquer outro caractere, pelo número de+
e-
s na primeira linha - 1 e o número de linhas que começam com|
+ 1.Eu tive que mover as linhas de IP para cima em vez de para baixo, a fim de usar a vertical se estiver na terceira linha. Se o IP estivesse descendo as linhas, a vertical se forçaria o topo da pilha a 1 ao atingir a seguinte horizontal se, enviando-a na direção errada.
fonte
Haskell,
6456 bytesExperimente online!
Explicação
Espera-se que a entrada seja uma lista de cadeias para cada linha, portanto, no
f
parâmetrox
está a primeira linha er
uma lista das linhas restantes.fst(span(>'+')x)
retorna o.
prefixo-da primeira linha como uma string, assimlength(fst(span(>'+')x))
como a primeira dimensãod1
.['-' | '-' <- x]
retorna uma sequência de tudo-
na primeira linha,1 + length['-' | '-' <- x]
gerando a segunda dimensãod2
.|
na primeira linha pode ser contado, assim1 + length['|' | '|':_ <- r]
como a terceira dimensãod3
.As compreensões de lista de 2. e 3. podem ser reduzidas para
1+sum[1|'-'<-x]
e1+sum[1|'|':_<-r]
construindo uma lista de itens para cada ocorrência de '-' ou '|' e depois pegando a soma. Podemos colocar ainda mais o exterior1+
para a compreensão da lista anexando-
aox
e"|"
parar
para produzirsum[1|'-'<-'-':x]
esum[1|'|':_<-"|":r]
. Agora podemos combinar as duas compreensões de lista colocando os dois predicados na mesma compreensão:sum[1|'|':_<-"|":r,'-'<-'-':x]
Convenientemente, isso calcula exatamente o produto das duas dimensões, porque para listasF
eG
a seguinte compreensão de lista é o produto cartesianoF x G =[(a,b)|a<-F,b<-G]
.Finalmente, em vez de multiplicar 1. pela combinação de 2. e 3., podemos usar o
>>
operador nas listas:F>>G
repete osG
length F
tempos e concatena o resultado. Entãofst(span(>'+')x)>>[1|'|':_<-"|":r,'-'<-'-':x]
repete a lista ded2*d3
unsd1
tempos, produzindo uma lista ded1*d2*d3
aqueles que são então somados até obter o volume.fonte
lines
.Java 8,
185129 bytesgraças ao Zgarb por -56 bytes
golfed:
ungolfed:
Explicação
a*b*h = ((length_of_line-2*h-1)/2)*(number_of_lines-2*h-1)*h
onde
a
eb
são as dimensões da base eh
é a altura. Você pode encontrarh
contando as primeirash
linhas em que começa com a.
.fonte
Java, 112 bytes
Expandido:
fonte
Powershell,
6867 bytesNota:
"$args"|% i*f +
é um atalho para"$args".indexOf('+')
Explicação
Boa explicação tirada da resposta do Osable :
Seja
W
eH
seja, respectivamente, a largura e a altura da entrada - não a caixa. Em seguida, as dimensões da caixaA
,B
eC
seguir estas regras:A figura a seguir mostra o que
A
,B
eC
são, em termos de nomes de ponta:E
C
é a posição do primeiro+
na primeira linha da entrada.Script de teste:
Saída:
fonte
Wolfram Language (Mathematica) , 64 bytes
Experimente online!
Usa o número de
.
,|
e\n
caracteres na entrada para resolver para o volume. Parece estúpido porque há uma nova linha real no lugar de\n
.Se
A
,B
eC
são os lados, em seguida. = 2C(A+2C)
,| = 5B+4C-9
e\n = B+2C
, por isso, podemos resolver para o volumeABC
em termos dessas três contagens de caracteres.fonte