Detectar as placas quase perfeitas

15

Nota: Isso é inspirado nesta pergunta no @Willbeing, onde a tarefa era contar o número de pratos perfeitos de um determinado comprimento, mas é um pouco diferente.


Chamamos uma placa perfeita de placa cujo texto satisfaz as seguintes condições:

  • Consiste em caracteres, que podem ser letras maiúsculas ( [A-Z]) ou dígitos ( [0-9])
  • Somando as posições de suas letras no alfabeto inglês, 1 indexado (ie :)A=1,B=2,...,Z=26 fornece um número inteiro n
  • Obter cada pedaço de dígito, somar e depois multiplicar todos os resultados dá o mesmo resultado, n
  • n é um quadrado perfeito (por exemplo: 49 (7 2 ) , 16 (4 2 ) )

Uma placa quase perfeita atende às condições para uma placa perfeita, exceto que n não é um quadrado perfeito.


Entrada

Uma sequência que representa o texto da placa do veículo, tomada como entrada em qualquer formato padrão, exceto na codificação codificada.

Resultado

Se a sequência especificada representar uma placa quase perfeita , retorne um valor verdadeiro (por exemplo: True/ 1), caso contrário, retorne um valor falso (por exemplo: False/ 0). Qualquer forma padrão de saída é aceita enquanto se observa que essas brechas são estritamente proibidas.


Exemplos

licence plate -> output


A1B2C3 -> 1

A + B + C = 1 + 2 + 3 = 6
1 * 2 * 3 = 6 
6 is not a perfect square, 6 = 6 => nearly perfect plate

01G61 -> 1

(0 + 1) * (6 + 1) = 7
G = 7
7 is not a perfect square, 7 = 7 => nearly perfect plate

11BB2 -> 0

(1 + 1) * 2 = 4
B + B = 2 + 2 = 4
4 = 4, but 4 is the square of 2 => perfect license plate (not what we want)

67FF1 -> 0

(6 + 7) * 1 = 13
F + F = 6 + 6 = 12
12 != 13 => not perfect at all!

Pontuação

Isso é , então a resposta mais curta em bytes vence!

Mr. Xcoder
fonte
popularidade-contest
Matthew Roh
Eu acho que isso seria melhor como código-golfe .
Erik the Outgolfer
Deixe-me ter certeza de que entendo isso. Só produzimos verdade se a placa do veículo for perfeita e nãon for um quadrado perfeito?
matemática viciado em
@mathjunkie Sim. TL; DR: somente se a licença é quase perfeito (PS desculpe pela resposta tardia)
Mr. Xcoder
1
Antes que alguém faça s/licence/license/igisso, lembre-se de que "licença" é a grafia correta no inglês britânico (assim como em outras partes do mundo).
Mego

Respostas:

7

Geléia , 29 28 30 bytes

1 byte para corrigir um bug descoberto por ChristianSievers (incorretamente lidar com substrings de apenas zeros) +1 byte para corrigir falsos positivos para "0", "00"... encontrado durante fixação acima (0 é um quadrado perfeito).

i@€ØAS;Ʋ$
e€ØAœpV€€LÐfS€P;0⁼Ç

Experimente online! ou execute testes

Quão?

i@€ØAS;Ʋ$ - Link 1: [letter-sum, letter-sum is perfect square?]: plate
i@€        - index of €ach char in plate [reversed @rguments] (1-based, 0 otherwise) in:
   ØA      -     uppercase alphabet
     S     - sum
         $ - last two links as a monad:
      ;    -     concatenate with:
       Ʋ  -         is square?

e€ØAœpV€€LÐfS€P;0⁼Ç - Main link: plate                        e.g. "11BB2"
    œp              - partition plate at truthy values of:
e€                  -     is in? for €ach char in plate:
  ØA                -         uppercase alphabet                   [['1','1'],[''],['2']]
      V€€           - evaluate for €ach for €ach                   [[1,1],[],[2]]
          Ðf        - filter keep:
         L          -     length                                   [[1,1],[2]]
            S€      - sum each                                     [2,2]
              P     - product                                      4
               ;0   - concatenate a zero                           [4,0]
                  Ç - last link (1) as a monad (taking plate)      [4,1]
                 ⁼  - equal? (non-vectorising)                     0
Jonathan Allan
fonte
Uau, genial solução Jelly!
Mr. Xcoder
Que tal 11AA0?
Christian Sievers
@ChristianSievers, boa captura. Corrigido junto com outro tipo de bug relacionado e estendido o conjunto de testes.
Jonathan Allan
7

MATL, 36 34 33 35 bytes

3Y432YXU"@V!Usvp]GlY2&msy=wtQ:qUm~v

Experimente no MATL Online

Explicação

        % Implicitly grab input as a string
3Y4     % Push the predefined literal '[A-Za-z]+' to the stack
32      % Push the literal 32 to the stack (ASCII for ' ')
YX      % Replace the matched regex with spaces (puts a space in place of all letters)
U       % Convert the string to a number. The spaces make it such that each group of
        % of consecutive digits is made into a number
"       % For each of these numbers
  @V!U  % Break it into digits
  s     % Sum the digits
  v     % Vertically concatenate the entire stack
  p     % Compute the product of this vector
]       % End of for loop
G       % Explicitly grab the input again
lY2     % Push the predefined literal 'ABCD....XYZ' to the stack
&m      % Check membership of each character in the input in this array and 
        % return an array that is 0 where it wasn't a letter and the index in 'ABC..XYZ'
        % when it was a letter
s       % Sum the resulting vector
y       % Duplicate the product of the sums of digits result
=       % Compare to the sum of letter indices result
w       % Flip the top two stack elements
Q       % Add one to this value (N)
t:      % Duplicate and compute the array [1...N]
q       % Subtract 1 from this array to yield [0...N-1]
U       % Square all elements to create all perfect squares between 1 and N^2
m~      % Check to ensure that N is not in the array of perfect squares
v       % Vertically concatenate the stack.
        % Implicitly display the truthy/falsey result
Suever
fonte
Produz falsos positivos para placas que consistem apenas em zeros, por exemplo, '0'ou '00'(FWIW também corrigi isso também no meu código).
Jonathan Allan
1
@JonathanAllan Atualizado.
Suever
6

Python 2, 120 118 bytes

s=t=p=0;r=1
for n in input():
 h=int(n,36)
 if h>9:s+=h-9;r*=t**p
 p=h<10;t=(t+h)*p
print(s==r*t**p)&(int(s**.5)**2<s)

Experimente online!

Interpreta cada caractere como um número na base-36 ( h). Converte em decimal e adiciona à soma se h>9(ou seja, é uma letra); caso contrário, adiciona a uma variável que é multiplicada para formar o produto em execução posteriormente.

viciado em matemática
fonte
4

Perl 5 , 80 bytes

79 bytes de código + -psinalizador.

$.*=eval s/./+$&/gr for/\d+/g;$t-=64-ord for/\pl/g;$_=$.==$t&&($.**.5|0)**2!=$.

Experimente online!

$.*=eval s/./+$&/gr for/\d+/g;multiplica as somas de dígitos consecutivos. (Estou usando $.porque seu valor inicial é 1, o que significa que é o elemento neutro para multiplicação). Mais precisamente, para cada parte dos dígitos ( for/\d+/g), s/./+$&/grcoloca a +antes de cada dígito, a sequência é evalatualizada e multiplicada pelo produto atual.
Em segundo lugar, $t-=64-ord for/\pl/g;somas em $tcada letra ( for/\pl/g). ( ordretorne o código ascii da letra e 64-..faça com que fique entre 1 e 26.
Finalmente, $.==$tverifica se os dois valores são iguais e se ($.**.5|0)**2!=$.não é um quadrado perfeito.

dada
fonte
4

Python 2, 267 207 bytes

Economizou 60 bytes graças a ovs

import re
def g(l):a=reduce(lambda a,b:a*b,[sum(map(int,list(i)))for i in re.sub(r'\D',' ',l).split()],1);return a==sum(sum(k)for k in[[ord(i)-64for i in x]for x in re.sub(r'\d',' ',l).split()])and a**.5%1>0

Função com uso: print(g('A1B2C3'))

Experimente online!

Mr. Xcoder
fonte
4

Python 3 , 163 156 155 164 164 bytes

from math import*
m=1;s=t=p=0
for x in input():
 try:t+=int(x);p=1
 except:m*=[1,t][p];p=t=0;s+=ord(x.upper())-64
if p:m*=t
print(m==s and sqrt(m)!=int(sqrt(m)))

Experimente online!

  • economizou 7 bytes graças a Jonathan e Shooqie
  • 1 byte salvo: também foi corrigido o problema de falso positivo. Obrigado a Jonathan por apontar isso!
  • 11 bytes adicionados: a edição anterior estava incorreta (a multiplicação da soma dos dígitos acontecia em um loop indesejado)
officialaimm
fonte
1
from math import*é menor
shooqie
1
Você não precisa a, apenas use for x in input():. Você pode ter falsos positivos para placas que terminam com uma sequência de zeros (por exemplo 11AA00), pois a final m*=tnão é executada.
Jonathan Allan
1
Aparentemente, meu código mostra falso positivo para qualquer cadeia de caracteres com zeros isolados (3A0B também é mostrado como verdadeiro) ... Obrigado por apontar isso para @ JonathanAllan. Vou tentar consertar isso.
officialaimm
Verifique a versão mais recente ... Adicionei uma nova variável de flag 'p' para decidir se deve ou não multiplicar a soma dos dígitos.
officialaimm
3

Retina, 143 bytes

Retorna 1 para verdadeiro, 0 para falso

[1-9]
$ *
10 | 01
1
S_` (\ D)
O`
{`1 (? = 1 * \ n (1+))
$ 1
) 2 = `1 + \ n

[JS]
1 $ +
[TZ]
2 $ +
T`0L`ddd
1> `\ d + \ n?
$ *
^ ((? (1) ((? (2) \ 2 (11) | 111)) | 1)) * \ n

^ (1 *) \ n \ 1 $

Experimente Online!

Explicação:

[1-9]
$ *
10 | 01
1

Primeiro, substituímos todos os dígitos diferentes de zero por sua representação unária. Removemos quaisquer zeros com um dígito adjacente para que eles não afetem nossas operações unárias

S_` (\ D)

Divida a sequência resultante em letras, tomando cuidado para excluir linhas vazias (este é um problema quando duas letras são consecutivas AA).

O`
{`1 (? = 1 * \ n (1+))
$ 1
) 2 = `1 + \ n

Classifique a sequência lexicograficamente. Em seguida, faça o seguinte:

1) Substitua cada um 1pelo número de 1s na linha a seguir (isso imita a multiplicação)

2) Remova a segunda linha de 1s

[JS]
1 $ +
[TZ]
2 $ +
T`0L`ddd

Substituir letras J-Scom 1J, 1Ketc. e substituir letras T-Zcom 2T, 2Uetc. Em seguida, substituir cada um dos grupos A-I, J-Se T-Zcom 1-9. Seremos deixados com o valor numérico de cada letra (por exemplo, 13para M).

1> `\ d + \ n?
$ *

Converta todas as linhas, exceto a primeira, em unário (a primeira linha já está em unário). Concatene essas linhas. Agora ficamos com uma string do formulário <product of digits>\n<sum of letters>.

^ ((? (1) ((? (2) \ 2 (11) | 111)) | 1)) * \ n

Substitua um número quadrado pela sequência vazia. Isso usa o método "árvore da diferença" .

^ (1 *) \ n \ 1 $

Retorne 1se as duas cordas de cada lado da \npartida. Caso contrário, retorne 0.

viciado em matemática
fonte
Falsos positivos para 11AA0, 0AA11, etc.
Jonathan Allan
@JonathanAllan Thanks! Custou-me 11 bytes de correção
matemática viciado em