Programa de identificação de formas

25

Sua tarefa é criar um programa que identifique a forma da entrada. As formas a serem identificadas podem ser uma das seguintes:

Quadrado

Para ser identificada como um quadrado, a fonte deve ter linhas de todos os comprimentos iguais e o mesmo número de linhas que os caracteres por linha (caracteres de nova linha excluídos). Uma nova linha opcional à direita é aceitável.

$_='
$_="
$_"'
;say

Retângulo

Para ser identificada como um retângulo, a origem deve ter linhas de todo o mesmo comprimento, mas o número de linhas não corresponde ao número de caracteres por linha (caracteres de nova linha excluídos). Uma nova linha opcional à direita é aceitável. Isso pode ser horizontal ou vertical.

$_=
"no
t a
squ
are
";#

$_="but it
is still a
consistent
shape!";##

Triângulo

Para ser identificada como um triângulo, a origem deve começar com um caractere e cada linha subseqüente deve ter um caractere adicional (incluindo o último) ou, após a primeira linha, cada linha subseqüente deve ter um caractere a menos até o último, o que tem apenas um.

$
_=
"So
this
"."".
shape;

$_="or
even,
this
way
!!
"

Bagunça

Tudo o que não segue um formato consistente, conforme descrito acima, deve ser identificado como uma bagunça.

Regras

  • Você pode retornar quaisquer quatro valores imprimíveis consistentes para identificar cada forma.
  • Seu código-fonte também deve aderir a uma das formas acima (não, não é uma bagunça).
  • Uma única nova linha à direita na sua origem é aceitável.
  • Você pode assumir que a entrada não contém linhas em branco (incluindo novas linhas à direita), não está vazia e não consiste apenas em novas linhas.
  • Todas as formas devem ter altura e largura>> 2, caso contrário, isso é definido como uma bagunça.
  • As brechas padrão são proibidas.
  • A solução mais curta em bytes, em cada idioma, vence.
Dom Hastings
fonte
"Seu código-fonte também deve aderir a uma das formas acima" significa que um liner está bom?
tsh
1
@ tshAll shapes must have a height and width of >= 2.
TFeld 23/03
1
A entrada pode ser uma matriz? por exemplo, um quadrado ['abc','cfd','fgh']?
Luis felipe De jesus Munoz
1
@ recursivo atualizado, obrigado!
Dom Hastings
3
Você está me dizendo que meu código fonte não pode ser uma bagunça? Por que não?!?!
NH.

Respostas:

9

Geléia , 35 bytes

L€ṀR,Ṛ$ċƲȧ3
L€,;¥LE€S+Ç
ỴµZL«L>1ȧÇ 

Experimente online!

0= Confusão
1= Retângulo
2= Quadrado
3= Triângulo

Erik, o Outgolfer
fonte
O espaço na sua última linha é usado pelo seu código? Ou isso é apenas preenchimento para atender aos critérios de "retângulo"?
BradC 23/03
@BradC Este último. Eu provavelmente deveria adicionar uma explicação.
Erik the Outgolfer /
7

Braquilog , 45 bytes

lᵐ{≥₁|≤₁}o{l>1&t>1&}↰₃
lg,?=∧1w|=∧2w|t⟦₁≡?∧3w

Experimente online!

Código é um retângulo (apesar da maneira como é renderizado na minha tela). Saídas: 1 para quadrado, 2 para retângulo, 3 para triângulo e nada para bagunça


Explicação:

lᵐ{≥₁|≤₁}o{l>1&t>1&}↰₃
lg,?=∧1w|=∧2w|t⟦₁≡?∧3w

lᵐ                        Get the length of each string
  {     }                 Verify 
   ≥₁                     The list is non-increasing
     |                    or...
      ≤₁                  The list is non-decreasing
         o                Sort it to be non-decreasing
          {        }      Verify
           l>1            The number of lines is greater than 1
              &           and...
               t>1&       The longest line is longer than 1 character
                    ↰₃    Call the following

lg,?                      Join the number of lines with the line lengths
    =∧1w                  If they are all equal, print 1 (Square)
         |=∧2w            Or if just the line lengths are equal, print 2 (Rectangle)
              |t⟦₁         Or if the range [1, 2, ... <longest line length>]
                  ≡?       Is the list of lengths
                    ∧3w    Print 3 (triangle)
                           Otherwise print nothing (mess)
PunPun1000
fonte
7

Java 10, 231 221 219 217 213 211 207 bytes

s->{var a=s.split("\n");int r=a.length,l=a[0].length(),R=0,i=1,L,D;if(r>1){for(L=a[1].length(),D=L-l;++
i<r;R=L-a[i-1].length()!=D?1:R)L=a[i].length();R=R<1?D==0?r==l?1:2:D>-2&D<2&(l<2|L<2)?3:0:0;}return R;}

A função é um retângulo em si.
1Quadrados; 2= Retângulos; 3= Triângulos; 0= Bagunça.

-14 bytes graças a @ OlivierGrégoire .

Explicação:

Experimente online.

s->{                        // Method with String parameter and integer return-type
  var a=s.split("\n");      //  Input split by new-lines
  int r=a.length,           //  Amount of lines
      l=a[0].length(),      //  Length of the first line
      R=0,                  //  Result-integer, initially 0
      i=1,                  //  Index integer, starting at 1
      L,D;                  //  Temp integers
  if(r>1){                  //  If there are at least two lines:
    for(L=a[1].length(),    //   Set `L` to the length of the second line
        D=L-l;              //   And set `D` to the difference between the first two lines
        ++i<r;              //   Loop over the array
        ;                   //     After every iteration:
         R=L-a[i-1].length()//     If the difference between this and the previous line
          !=D?              //     is not equal to the difference of the first two lines:
           1                //      Set `R` to 1
          :                 //     Else:
           R)               //      Leave `R` the same
      L=a[i].length();      //    Set `L` to the length of the current line
  R=R<1?                    //   If `R` is still 0:
     D==0?                  //    And if `D` is also 0:
      r==l?                 //     And the amount of lines and length of each line is equal
       1                    //      It's a square, so set `R` to 1
      :                     //     Else:
       2                    //      It's a rectangle, so set `R` to 2
     :D>-2&D<2&             //    Else-if `D` is either 1 or -1,
      (l<2|L<2)?            //    and either `l` or `L` is 1:
       3                    //     It's a triangle, so set `R` to 3
    :0:0;}                  //   In all other cases it's a mess, so set `R` to 0
  return R;}                //  Return the result `R`
Kevin Cruijssen
fonte
1
Corrigido para 221 bytes: s->{var a=s.split("\n");int S=a.length,l=a[0].length(),L,D,b=0,i=1;if(S<2)return 0;for(L=a[1].length(),D=L-l; b<1&++i<S;)if((L=a[i].length())-a[i-1].length()!=D)b=1;return b<1?D==0?S==l?1:2:D==-1|D==1?l==1|L==1?3:0:0:0;}(espaço duplo depois var, quebra de linha depois D=L-l;.
Olivier Grégoire
@ OlivierGrégoire Obrigado. E joguei mais dois bytes mudando D==-1|D==1para D>-2|D<2. Essa e a l==1|L==1podem ser mais jogáveis ​​com algumas operações bit a bit, mas essa não é minha especialidade.
Kevin Cruijssen 23/03
1
207 bytes: s->{var a=s.split("\n");int r=a.length,l=a[0].length(),L,D,b=0,i=1;if(r>1){for(L=a[1].length(),D=L-l;++ i<r;b=L-a[i-1].length()!=D?1:b)L=a[i].length();b=b<1?D==0?r==l?1:2:D>-2&D<2&(l<2|L<2)?3:0:0;}return b;}(após D=L-l;++). Ainda jogável, mesclando o loop e a declaração posteriormente em um, mas não vejo como agora.
Olivier Grégoire
6

Python 2 , 129 114 109 107 113 bytes

l=map(len,input().split('\n'));m=len(
l);r=range(1,m+1);print[[1],0,r,r[::-
1],[m]*m,0,[max(l)]*m,l].index(l)%7/2

Experimente online!


Impressões

  • 0 = Mess
  • 1 = Triangle
  • 2 = Square
  • 3 = Rectangle
TFeld
fonte
@KevinCruijssen Obrigado, deve ser corrigido agora #
TFeld 23/03
6

Geléia , 32 27 bytes

,U⁼€JẸ,E;SƲ$
ZL«L’aL€Ç$æAƝ

Experimente online!

Agora, pegue a entrada em uma lista de linhas e alterne >1×com ’ae usando SƲdepois em L€ vez de FLƲƊ. Isso me permitiu condensar em duas linhas e salvei 5 bytes no total. Os seguintes valores são os mesmos de antes.

[0.0, 0.0]= Confusão
[0.0, 1.5707963267948966]= Retângulo
[0.0, 0.7853981633974483]= Quadrado
[1.5707963267948966, 0.0]= Triângulo


ZL«Lobtém o mínimo de altura e largura e subtrai 1 dele. Çchama o segundo link e, no final, se a entrada for uma única linha, o resultado Çserá lógico ANDed com o número anterior, se houver apenas uma única linha que será a saída [0.0, 0.0].

No segundo link: ,Ugera uma lista de comprimentos de linha emparelhados com o reverso. Jé range(number of lines)e ⁼€verifica se cada um deles é igual ao resultado de J. (Qualquer) produz 1 se a entrada for um triângulo.

E verifica se todos os comprimentos de linha são iguais (retângulo / quadrado).

SƲcom a $para agrupá-los em uma única mônada, verifica se o número total de caracteres é um número quadrado.

Portanto, no final do segundo link, temos [[a,b],c]onde cada número está 0ou 1indicando se a entrada é um triângulo, retangular e possui um número quadrado de caracteres, respectivamente.

No entanto, um número quadrado de elementos não implica que a entrada seja um quadrado, pois uma entrada bagunçada como

a3.
4

tem um número quadrado de elementos, mas não é um quadrado.

É aqui que æAentra (arctan2). 0æA0== 0æA1== 0. Em outras palavras, se a entrada tiver um número quadrado de elementos, mas não for um retângulo, não será um quadrado. Certamente, existem maneiras mais claras de fazer isso, mas o que isso importa quando temos bytes para pensar e nos é permitido uma saída arbitrária consistente.

Observe que eu estava usando anteriormente em æA/vez de æAƝ(e um em ,vez de a ;no segundo link), mas o método anterior distingue entre triângulos que possuem número quadrado de elementos e aqueles que não, mas que obviamente devem ser contados como a mesma coisa.

dylnan
fonte
Eu estava olhando para os números de pensamento, eles parecem vagamente familiar ...
Dom Hastings
@DomHastings Haha. Eu estava tendo problemas para distinguir quadrados de bagunças com número quadrado de elementos e arctan2era exatamente o que eu precisava.
dylnan
1
Engraçado que eu não acho que isso seria mais curta, se não houve restrição fonte
dylnan
... Tem certeza de que isso é válido? Como a nova linha no Jelly é 0x7F, não 0x0A.
precisa saber é o seguinte
@DomHastings Isso é válido? (ver acima da razão)
user202729
4

Java 10, 274 323 298 229 bytes

Submissão do primeiro triângulo.

s
->
{  
var 
a=s. 
split 
("\n");
int i,l=
a.length,
c,f=a[0]. 
length(),r=
l<2||f<2&a[1
].length()<2?
0:f==l?7:5;var
b=f==1;for(i=1;
i<l;){c=a[i++]. 
length();r&=c!=f?
4:7;r&=(b&c!=f+1)|
(!b&c!=f-1)?3:7;f=c
;}return r;}        

0 Bagunça

1 Retângulo

3 Quadrado

4 Triângulo

Experimente online aqui .

Editado várias vezes para jogar um pouco mais.

É claro que eu poderia economizar muitos bytes transformando isso também em um retângulo ( 281 267 259 200 bytes, veja aqui ).

O resultado da identificação é manipulado usando AND bit a bit, produzindo uma máscara de bit da seguinte maneira:

1        1      1
triangle square rectangle

Versão não destruída:

s -> {
    var lines = s.split("\n"); // split input into individual lines
    int i, // counter for the for loop
    numLines = lines.length, // number of lines
    current, // length of the current line
    previous = lines[0].length(), // length of the previous line
    result = numLines < 2 // result of the identification process; if there are less than two lines
    || previous < 2 & lines[1].length() < 2 // or the first two lines are both shorter than 2
    ? 0 : previous == numLines ? 7 : 5; // it's a mess, otherwise it might be a square if the length of the first line matches the number of lines
    var ascending = previous == 1; // determines whether a triangle is in ascending or descending order
    for(i = 1; i < numLines; ) { // iterate over all lines
         current = lines[i++].length(); // store the current line's length
        result &= current != previous ? 4 : 7; // check if it's not a rectangle or a square
        result &= (ascending & current != previous+1)|(!ascending & current != previous-1) ? 3 : 7; // if the current line is not one longer (ascending) or shorter (descending) than the previous line, it's not a triangle
        previous = current; // move to the next line
    }
    return result; // return the result
}
OOBalance
fonte
1
Bem-vindo ao PPCG!
Steadybox
Viva para triângulos! Obrigado!
Dom Hastings
Olá, seja bem-vindo ao PPCG! Ótima primeira resposta. Também tentei transformar minha resposta em um triângulo, mas custaria muitos bytes em comparação ao retângulo, e algumas palavras-chave também eram um pouco longas na minha resposta inicial. :) Ótima resposta, +1 de mim. E tomei a liberdade de editar sua postagem para adicionar destaque a toda a postagem, para que os comentários em sua versão sem armas sejam mais fáceis de ler. Aproveite sua estadia!
21718 Kevin Kevin Kurtzssen
@KevinCruijssen Obrigado pelo voto positivo e pela edição, parece muito melhor agora. Minha resposta pode ser reduzida, transformando-o também em um retângulo, 281 bytes. Mas onde está a graça nisso?
OOBalance
3

Javascript 125 bytes

_=>(g=(l=_.split('\n').map(a=>a.length)).
length)<3?0:(r=l.reduce((a,b)=>a==b?a:0))
?r==g?2:1:l.reduce((a,b)=>++a==b?a:0)?3:0

0 = Mess
1 = Rectangle
2 = Square
3 = Triangle

fa=_=>(g=(l=_.split('\n').map(a=>a.length)).length)<3?0:(r=l.reduce((a,b)=>a==b?a:0))?r==g?2:1:l.reduce((a,b)=>++a==b?a:0)?3:0

var square = `asd
asd
asd`

var rectangle = `asd
asd
asd
asd
asd
asd`

var triangle = `asd
asdf
asdfg
asdfgh`

var mess = `asd
dasdasd
sd
dasasd`

console.log(fa(square), fa(rectangle), fa(triangle), fa(mess))

Luis felipe De jesus Munoz
fonte
3
A contagem de bytes é 125 (incluindo as novas linhas)
Herman L
Triângulo deve ir para um 1? Não é um 3456
l4m2 23/03
@ l4m2, o que você quer dizer?
Luis felipe De jesus Munoz
2
triângulo deve sempre começar em 1?
Luis felipe De jesus Munoz
3
Acho que o que l4m2 está apontando é que um triângulo deve ter apenas um caractere na primeira ou na última linha, caso contrário, é uma "bagunça".
Shaggy
3

Perl 5 -p , 83 bytes

  • Bagunça: nada
  • Quadrado: 0
  • Triângulo: 1
  • Retângulo: 2
($z)=grep++$$_{"@+"-$_*~-$.}==$.,0,/$/,-1
}{$.<2or$_=$$z{$z>0||$.}?$z%2:@F>1&&2x!$z

Experimente online!

Ton Hospel
fonte
3

PHP, 195 205 bytes

<?$a=$argv[1];$r=substr($a,-2,1)=="\n"?strrev($a):$a;foreach(explode("\n",$r)as$l){$s=strlen($l);$x[$s
]=++$i;$m=$i==$s?T:M;}$z=count($x);echo$i*$z>2?$z==1&&key($x)==$i?S:($z==1&&$i>2?R:($i==$z?$m:M)):M;?>

O triângulo invertido adiciona 56 bytes caros a isso!

As saídas são S, R, T, M

Economizou alguns bytes graças a Dom Hastings.

Experimente online!

Corrigidos alguns problemas agora ... Execuções de teste produzem isso.

$_="
$_="
$_""
;say

RESULT:S
=============
$_=
"no
t a
squ
are
";#

RESULT:R
=============
$
_=
"So
this
"."".
shape;

RESULT:T
=============
$_="or
even,
this
way
!!
"

RESULT:T
=============
as
smiley
asd
A

RESULT:M
=============
X

RESULT:M
=============
XX

RESULT:M
=============
cccc
a
aa
cccc

RESULT:M
=============
Dave
fonte
Omit ?>deve estar bem
tsh
Isso parece retornar Tpara cccc\na\naa\ncccc Experimente online!
Dom Hastings
3

Perl 6 , 81 bytes

{.lines>>.chars.&{($_==.[0],3)[2*(2>.max
)+($_ Z- .skip).&{.[0].abs+.Set*2+^2}]}}

Experimente online!

Retorna Truepara quadrado, Falseretângulo, 3triângulo, Nilconfusão.

Nwellnhof
fonte
Muito bom, você se importaria de desempacotar um pouco, em particular $_ Z- .skip?
Phil H
3

Stax , 39 bytes

L{%m~;:-c:u{hJchC; 
|mb1=-C;%a\sI^^P}M0

Execute e depure online!

Resposta mais curta apenas ASCII até agora.

0 - Confusão
1 - Retângulo
2 - Quadrado
3 - Triângulo

Explicação

A solução utiliza o seguinte fato: Se algo for explicitamente impresso na execução do programa, nenhuma saída implícita será gerada. Caso contrário, a parte superior da pilha no final da execução é emitida implicitamente.

L{%m~;:-c:u{hJchC;|mb1=-C;%a\sI^^P}M0
L                                        Collect all lines in an array
 {%m                                     Convert each line to its length
    ~;                                   Make a copy of the length array, put it on the input stack for later use
      :-                                 Difference between consecutive elements.
                                         If the original array has only one line, this will be an empty array
        c:u                              Are all elements in the array the same?
                                         Empty array returns false
           {                      }M0    If last test result is true, execute block
                                         If the block is not executed, or is cancelled in the middle, implicitly output 0
            hJ                           The first element of the difference array squared (*)
              chC                        Cancel if it is not 0 or 1
                 ;|m1=                   Shortest line length (**) is 1
                      -                  Test whether this is the same as (*)
                                         Includes two cases:
                                             a. (*) is 1, and (**) is 1, in which case it is a triangle
                                             b. (*) is 0, and (**) is not 1, in which case it is a square or a rectangle
                        C                Cancel if last test fails
                         ;%              Number of lines
                           a\            [Nr. of lines, (*)]
                             I           Get the 0-based index of (**) in the array
                                         0-> Square, 1->Triangle -1(not found) -> Rectangle
                              ^^P        Add 2 and print
Weijun Zhou
fonte
3

Haskell , 113 107 103 101 bytes

((#)=<<k).map k.lines;k=length;1#x=0;l#x|x==[1..l]
  ||x==[l,l-1..1]=3;l#x=k[1|z<-[l,x!!0],all(==z)x]

Experimente online!

Retorna 0, 1, 2 e 3 para bagunça, retângulo, quadrado e triângulo, respectivamente.

Edit: -2 bytes graças a Lynn !

Laikoni
fonte
3

05AB1E , 35 29 27 bytes

Economizou 8 bytes graças ao Magic Octopus Urn

DgV€g©ZU¥ÄP®Y
QP®ËJCXY‚1›P*

Experimente online!

0= Confusão
4= Triângulo
1= Retângulo
3= Quadrado

Emigna
fonte
Isso parece falhar em algum código confuso: Experimente online!
Dom Hastings
@ DomHastings: Obrigado por capturar isso. Eu pensei que o golfe era um pouco duvidoso. Deve ficar bem agora.
Emigna
Experimente online! - 19 bytes - 1 (retângulo), 2 (triângulo), 5 (quadrado) e 0 (confusão) [Usando números binários]. Possivelmente não aceitável lol. gs€g©QP®¥ ÄP®1å&®ËJCpode adicionar um caractere de espaço e um Cpara 21, no entanto.
Magic Octopus Urn
@MagicOctopusUrn: Ele ainda precisa verificar o comprimento / altura> = 2, mas ainda deve salvar bytes. Truque inteligente construindo os números de saída do binário!
Emigna
1
@MagicOctopusUrn: usei seu delta e truques binários para salvar alguns bytes na minha versão original. Provavelmente poderia economizar um pouco mais de reescrevê-lo um pouco mais.
Emigna
2

R , 101 bytes

"if"(var(z<-nchar(y<-scan(,"",,,"
","")))==0,"if"(length(y)==z,1,2
),"if"(all(abs(diff(z))==1),3,4))

1 = Quadrado
2 = Retângulo
3 = Triângulo
4 = Aleatório

O código não pode lidar com 'RECONHECIMENTO NEGATIVO' (U + 0015) ou o quadrado no código acima. Esse byte pode ser alterado para algo diferente se a entrada requerer contiver esse byte.

Experimente online!

Vlo
fonte
talvez você possa usar em readLines()vez de scan()?
Giuseppe
@Giuseppe não pode / muito noob para obter readlines ao trabalho
Vlo
Hmm, parece que você precisa especificar file("stdin")para fazer a leitura no console (em vez das próximas linhas de código). Isso significa que provavelmente será menos golfe. Ah bem.
Giuseppe
2

Caracóis, 29 bytes

ada7A
.2,lr
?!(t.
rw~)z
.+~o~

Chave de saída:

  • 0 - Confusão
  • 3 - Triângulo
  • 6 - Retângulo
  • 7 - Quadrado

Seriam 23 bytes sem layout de origem:

zA
.2,dun!(t.rf~)z.+~o~
feersum
fonte
Sempre gostei de brincar com esse idioma desde a leitura da pergunta que o gerou!
Dom Hastings
1

Wolfram Language (Mathematica) , 119 bytes

(x=StringLength/@#~StringSplit~"\n")/.{{1}->3,s~(t=Table)~{
s=Tr[1^x]}:>0,x[[1]]~t~s:>1,(r=Range@s)|Reverse@r:>2,_->3}&

Uso Replace /.e correspondência de padrões na contagem de caracteres por linha. Replaceexpulsará o primeiro RHS de uma regra que corresponda, de modo que a ordem é testar a entrada de 1 caractere, depois quadrados, retângulos, triângulos e um resumo de falhas.

quadrado = 0, retângulo = 1, triângulo = 2, confusão = 3

Experimente online!

Kelly Lowder
fonte
@ DomHastings, está consertado.
23418 Kelly Lowder
1

Vermelho , 209 bytes

func[s][c: copy[]foreach a split s"^/"[append c length? a]d: unique c
r: 0 if 1 < l: length? c[if 1 = length? d[r: 2 if(do d)= l[r: 1]]n: 0
v: copy[]loop l[append v n: n + 1]if(v = c)or(v = reverse c)[r: 3]]r]

Experimente online!

0 Bagunça

1 Quadrado

2 Retângulo

3 Triângulo

Galen Ivanov
fonte
1

AWK , 119 bytes

{p=l;l=L[NR]=length($0)
D=d}{d=p-l;x=x?x:NR>2?\
d!=D:0}END{print x==1?\
3:d*d==1?(L[NR]+L[1]==\
NR+1)?2:3:p!=NR}#######

Experimente online!

Saída:

0= Quadrado
1= Retângulo
2= Triângulo
3= Confusão

Robert Benson
fonte
1

Ruby , 115 111 bytes

->s{m=s.split(?\n).map &:size;r=*1..s=m.size;s<2?4:(m|[
]).size<2?m[0]<2?4:s==m[0]?1:2:r==m.reverse||r==m ?3:4}

Experimente online!

Lambda anônimo. Saídas:

  1. Quadrado
  2. Retângulo
  3. Triângulo
  4. Bagunça
Kirill L.
fonte
Isso parece falhar em alguns que devem ser sinalizados como bagunça: Experimente online!
Dom Hastings
Ai, acho que isso terá que ser uma solução rápida. Provavelmente terá de tentar jogar golfe um pouco mais ...
Kirill L.
1

C (gcc) , 125 123 bytes

Obrigado ao ceilingcat por -2 bytes.

f(L,n)int**L;{int i,l,c,F=strlen(*L),s=-F;for(l=i=0;i<n;l=c)c
=strlen(L[i++]),s+=c-l;s=n>1?s||F<2?~abs(s)+n?0:3:n^F?2:1:0;}

Experimente online!

gastropner
fonte