Hexagolf: Validagons

13

Desafio

Dada uma forma de arte ASCII, você deve descobrir se a forma é um hexágono regular ou não.

Hexágonos

Um hexágono regular é definido usando duas regras:

  • Tem seis lados
  • Cada lado tem um número igual de caracteres

Por exemplo, a seguinte forma é regular, mas não possui seis lados e, portanto, não é um hexágono regular :

B a a h
s a i d
y o u r
g a o t

Da mesma forma, a forma a seguir tem seis lados, mas lados de comprimentos diferentes e, portanto, não é um hexágono regular :

  * *
 * * *
* * * *
 * * *
  * *

No entanto, a forma a seguir tem seis lados e todos os lados têm o mesmo número de caracteres, portanto, é um hexágono regular:

  T h e
 h e x a
g o n s a
 r e c o
  m i n

Regras

A saída deve ser um valor verdade ou falsey (verdade se a forma for um hexágono regular, falsey se não).

As formas sempre conterão caracteres ASCII imprimíveis.

A borda da forma nunca conterá espaços. Se isso acontecer, você pode retornar Falsey.

Pode haver quantidades arbitrárias de espaço em branco antes e / ou depois da forma.

Todos os ângulos na forma podem não ser iguais, por exemplo, a seguinte forma é uma entrada válida:

  . . .
   . . .
. . . . .
 . . . .
  . . .

Retornará um valor falsey.

Todas as entradas de forma estarão em uma grade separada por espaço. A entrada hexagonal estará em uma grade escalonada (cada linha é deslocada da seguinte).

Exemplos

Truthy

As seguintes formas devem retornar valores de verdade:

 # _
+ + +
 9 :

  5 6 7
 8 9 0 1
2 3 4 5 6
 7 8 9 0
  1 2 3

    t h i s
   i       s
  a         h
 e           x
  a         g
   o       n
    ! ! ! !

    5 6 7
   8 9 0 1
  2 3 4 5 6
   7 8 9 0
    1 2 3

Falsey

O seguinte deve retornar valores falsey

r e c t a
n g l e s

  h e l l o
 w o r l d s
t h i s i s b
 e t a d e c
  a y n o w

  *
 * *
* * *

  .....
 .......
.........
 .......
  .....

Essa forma não está em uma grade separada por espaço e não é escalonada.


   * * * *
  ---------
 * * * * * *
-------------
 * * * * * *
  ---------
   * * * *

5 6 7
8 9 0 1
2 3 4 5 6
7 8 9 0
1 2 3

Para entradas de um caractere, seu programa pode gerar truthy ou falsey:

&

Ganhando

O programa mais curto em bytes vence.

Beta Decay
fonte
4
Mathematica um liner de entrada.
ThreeFx 9/09/16
1
Acho que você pode querer adicionar dois casos de teste: um sem espaços à esquerda, por exemplo: 5 6 7\n8 9 0 1\n2 3 4 5 6\n7 8 9 0\n1 2 3e um com um espaço adicional à frente de uma das linhas: ss5 6 7\nss8 9 0 1\n2 3 4 5 6\ns7 8 9 0\nss1 2 3(os espaços à esquerda são substituídos por spara tornar um pouco mais claro neste formato não formatado) . Todos os 10 casos de teste estão validando corretamente com meu código atualmente, mas esses dois casos falhariam com a abordagem que eu usei.
Kevin Cruijssen 9/09/16
O exemplo com os períodos é necessariamente falsey? O período que falta é um espaço que é um dos caracteres válidos que compõem o hexágono.
Ton Hospel 9/09/16
1
@TonHospel Acho que a ideia é que o esboço seja um hexágono regular contínuo.
Martin Ender
Todos os ângulos na forma podem não ser iguais, por exemplo, a seguinte forma é uma entrada válida: Essa frase parece enganosa. Certamente estamos detectando hexágonos regulares? Você quer escrever que os símbolos não têm necessariamente simetria angular?
Lynn

Respostas:

2

R, 184 bytes

Golfed, provavelmente poderia ser golfed por alguns bytes

function(m){e=min;f=max;l=length;v=which(m!=" ",T);a=v[,1];n=l(v[a==1,2]);u=(v[a==e(a),2]);all(u==v[a==f(a),2])&all(c(e(d<-v[a==ceiling(f(v[,1])/2),2]),f(d))==c(u[1]-n+1,u[l(u)]+n-1))}

Ungolfed, muito bagunçado, mais como na metade do golfe

f=function(m) {
  v = which(m!=" ",T)
  a = v[,1]
  n = length(v[a==1,2])
  u=(v[a==min(a),2])
  c1 = all(u==v[a==max(a),2])
  d = v[a==ceiling(max(v[,1])/2),2]
  c2 = all(c(min(d), max(d))==c(u[1]-n+1,u[length(u)]+n-1))
  c1 & c2
}

Como o formato de entrada não é especificado, a Entrada precisa ser especificada em um formato de matriz R, parecido com este.

         [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] " "  " "  "5"  " "  "6"  " "  "7"  " "  " " 
[2,] " "  "8"  " "  "9"  " "  "0"  " "  "1"  " " 
[3,] "2"  " "  "3"  " "  "4"  " "  "5"  " "  "6" 
[4,] " "  "7"  " "  "8"  " "  "9"  " "  "0"  " " 
[5,] " "  " "  "1"  " "  "2"  " "  "3"  " "  " " 

Aqui está uma função geradora que gera a entrada. O gerador não gera um objeto que é alimentado na função de verificação hexagonal, mas o código que especifica a matriz (efetivamente a mesma coisa). Portanto, isso não deve contar como análise do texto. Lembre-se de que não estou inserindo texto, mas uma estrutura de matriz.

generate = function(x) {
  s = strsplit(strsplit(x, "\n")[[1]], "")
  m = max(sapply(s, length))
  dput(do.call(rbind, lapply(s, function(x) c(x, rep(" ", m-length(x))))))
}

Por exemplo, o código gerado seria: structure(c(" ", " ", "2", " ", " ", " ", "8", " ", "7", " ", "5", " ", "3", " ", "1", " ", "9", " ", "8", " ", "6", " ", "4", " ", "2", " ", "0", " ", "9", " ", "7", " ", "5", " ", "3", " ", "1", " ", "0", " ", " ", " ", "6", " ", " "), .Dim = c(5L, 9L ))que é idêntico aarray(c(" ", " ", "2", " ", " ", " ", "8", " ", "7", " ", "5", " ", "3", " ", "1", " ", "9", " ", "8", " ", "6", " ", "4", " ", "2", " ", "0", " ", "9", " ", "7", " ", "5", " ", "3", " ", "1", " ", "0", " ", " ", " ", "6", " ", " "), dim = c(5, 9))

Esperemos que este método de entrada esteja em conformidade com as regras.

Aqui estão os casos de teste

x1 = 
"  5 6 7
 8 9 0 1
2 3 4 5 6
 7 8 9 0
  1 2 3"

x2 =
" # _
+ + +
 9 :"

x3 = 
"    t h i s
   i       s
  a         h
 e           x
  a         g
   o       n
    ! ! ! !"

x4 ="    5 6 7
   8 9 0 1
  2 3 4 5 6
   7 8 9 0
    1 2 3"

x5 = "r e c t a
n g l e s"

x6 = "  h e l l o
  w o r l d s
t h i s i s b
 e t a d e c
  a y n o w"

x7 ="  *
 * *
* * *"

x8 ="   .....
  .......
.........
  .......
   ....."

Gere matrizes de entrada

sapply(mget(paste("x", 1:8, sep = "")), generate)

Teste para hexágono

sapply(.Last.value , f)

   x1    x2    x3    x4    x5    x6    x7    x8 
 TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE 
Vlo
fonte
@DLosc Você não tinha a função de geração definida. Tente este link: goo.gl/9MtCLg Você também pode verificar com uma entrada manual comof(array(c(" ", " ", "2", " ", " ", " ", "8", " ", "7", " ", "5", " ", "3", " ", "1", " ", "9", " ", "8", " ", "6", " ", "4", " ", "2", " ", "0", " ", "9", " ", "7", " ", "5", " ", "3", " ", "1", " ", "0", " ", " ", " ", "6", " ", " "), dim = c(5, 9)))
Vlo 10/09/16
Ah, eu perdi essa parte. Obrigado.
DLosc
1

JavaScript (ES6), 214 bytes

(s,a=s.split`\n`,n=a[l=a.length>>1].match(r=/(?=\S).*\S/),i=n.index)=>!/\S(  )*\S/.test(s)&&!a.some((s,j)=>(m=r.exec(s))&&(k=m.index)<i+(j<l?j=l-j:j-=l)|k+(m=m[0].length)+j>i+n[0].length|k+i+j&1|j%l<1&m+j+j!=l*4+1)

Onde \nrepresenta um caractere literal de nova linha. Ungolfed:

function validhex(s) {
    if (/S(  )*/S/.test(s)) return false;
    var a = s.split("\n");
    var l = Math.floor(a.length / 2);
    var n = a[l].match(/(?=\S).*\S/);
    for (var j = -l; j <= l; j++) {
        var m = a[j+l].match(/(?=\S).*\S/);
        if (!m) continue;
        if (m.index < n.index + Math.abs(j)) return false;
        if (m.index + m[0].length + Math.abs(j) > n.index + n[0].length) return false;
        if ((m.index + n.index + j) % 2) return false;
        if (j % l) continue;
        if (m[0].length != l * 4 + 1 - 2 * Math.abs(j)) return false;
    }
    return true;
}
Neil
fonte
Eu encontrei um bug: a entrada " x\n g g\ng g g\n g g"deve dar false, mas dá true.
DLosc
@DLosc Presumo que são dois espaços antes da x?
Neil
@DLosc Eu acho que eu tê-lo fixo agora, custou-me 30 bytes embora ...
Neil
1

SnakeEx , 200 bytes

O idioma certo para o trabalho ... mais ou menos.

m:{v<>}{r<RF>2P}{r<R>2P}{h<RF>1P}{w<>}{l<RF>2P}{l<R>2P}{h<.>1}
w:{u<>P}{v<>}
v:{e<L>}{u<R>1}
u:.*{e<>}
e:.$
r:[^ ]+
h:([^ ] )+
l:({c<.>}[^ ])+{c<.>}
c:{b<B>}(. )+{x<>LP}{s<>}
b:.{s<>}
s:[^\!-\~]*$
x:.

SnakeEx é um idioma do desafio de Correspondência de Padrão 2-D . Deveria ser muito bom nessa tarefa, mas infelizmente todos os casos de canto realmente incharam o código. Também descobri alguns erros de intérprete. Ainda assim, foi um desafio divertido.

mé a principal cobra que chama todas as outras para fazer o trabalho real. Corresponde a partir do canto superior direito do hexágono e no sentido horário. Grupos numerados são usados ​​para verificar se os comprimentos laterais da diagonal são todos iguais e se o comprimento lateral horizontal corresponde à altura da figura inteira. Eu poderia escrever uma explicação mais detalhada, mas passei os últimos dois dias lidando com casos extremos, então tente você mesmo aqui . : ^)

DLosc
fonte
1

Perl, 127 125 124 121 bytes

Inclui +4 para -0p

Dê entrada no STDIN

#!/usr/bin/perl -0p
/ *(.*\S)/;$a=join'\S *
\1',map$"x(abs).'\S '.(/$n/?'\S ':'. ')x(2*$n-1-abs),-($n=$1=~y/ //)..$n;$_=/^$`( *)$a\S\s*$/
Ton Hospel
fonte