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.

"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


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)

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`

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

@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.


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
}

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))


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

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
=============

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.


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

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 !


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


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!


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~

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!


@ 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


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


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

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.