Mendeteksi Pelat Lisensi yang Hampir Sempurna


15

Catatan: Ini terinspirasi oleh pertanyaan ini oleh @ Willilling di mana tugasnya adalah untuk menghitung jumlah lempeng sempurna dengan panjang tertentu, tetapi sedikit berbeda.


Kami menyebutnya plat nomor sempurna yang plat yang teksnya memenuhi ketentuan berikut:

  • Ini terdiri dari karakter, yang bisa berupa huruf besar ( [A-Z]) atau digit ( [0-9])
  • Menjumlahkan posisi huruf-hurufnya dalam alfabet Inggris, 1-diindeks (yaitu:) A=1,B=2,...,Z=26memberikan bilangan bulat n
  • Mendapatkan setiap potongan angka, menjumlahkannya dan kemudian mengalikan semua hasil memberikan hasil yang sama, n
  • n adalah kuadrat sempurna (mis: 49 (7 2 ) , 16 (4 2 ) )

Sebuah plat hampir sempurna memenuhi kondisi untuk plat sempurna, kecuali bahwa n adalah tidak persegi sempurna.


Memasukkan

String yang mewakili teks plat, diambil sebagai input dalam bentuk standar apa pun, kecuali untuk hardcoding.

Keluaran

Jika string yang diberikan merupakan hampir sempurna plat, mengembalikan nilai truthy (misalnya: True/ 1), jika tidak mengembalikan falsy nilai (misalnya: False/ 0). Segala bentuk standar keluaran diterima sambil memperhatikan bahwa celah ini dilarang keras.


Contohnya

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!

Mencetak gol

Ini adalah , jadi jawaban tersingkat dalam byte menang!



Saya pikir ini akan lebih baik sebagai kode-golf .
Erik the Outgolfer

Biarkan saya memastikan saya mengerti ini. Kami hanya keluaran truthy jika plat sempurna dan nadalah tidak persegi sempurna?
pecandu matematika

@ mathjunkie Ya. TL; DR: hanya jika lisensi hampir sempurna (PS maaf atas keterlambatan tanggapan)
Tn. Xcoder

1
Sebelum ada yang melakukan s/licence/license/ighal ini, ketahuilah bahwa "lisensi" adalah ejaan yang benar dalam bahasa Inggris Inggris (dan juga bahasa Inggris di bagian lain dunia).
Mego

Jawaban:


7

Jelly , 29 28 30 byte

1 byte untuk memperbaiki bug ditemukan oleh ChristianSievers (salah berurusan dengan substring hanya nol) 1 byte untuk memperbaiki positif palsu untuk "0", "00", ... ditemukan selama fixing atas (0 adalah persegi sempurna).

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

Cobalah online! , atau menjalankan tes

Bagaimana?

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

Wow, solusi Jelly jenius!
Tn. Xcoder

Bagaimana dengan 11AA0?
Christian Sievers

@ChristianSievers, tangkapan bagus. Diperbaiki bersama dengan bug lain yang terkait, dan memperpanjang test suite.
Jonathan Allan

7

MATL, 36 34 33 35 byte

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

Cobalah di MATL Online

Penjelasan

        % 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

Menghasilkan false positive untuk pelat yang hanya terdiri dari nol, misalnya '0'atau '00'(FWIW saya baru saja memperbaikinya dalam kode saya).
Jonathan Allan

1
@JonathanAllan Diperbarui.
Suever

6

Python 2, 120 118 byte

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)

Cobalah online!

Menafsirkan masing-masing karakter sebagai angka dalam basis-36 ( h). Konversi ke desimal dan tambahkan ke penjumlahan if h>9(artinya itu surat), jika tidak, tambahkan ke variabel yang dikalikan untuk membentuk produk yang sedang berjalan nanti.


4

Perl 5 , 80 byte

79 byte kode + -pbendera.

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

Cobalah online!

$.*=eval s/./+$&/gr for/\d+/g;mengalikan jumlah digit berturut-turut. (Saya menggunakan $.karena nilai awalnya adalah 1, yang berarti itu adalah elemen netral untuk perkalian). Lebih tepatnya, untuk setiap potongan digit ( for/\d+/g), s/./+$&/grtempatkan +sebelum setiap digit, kemudian string tersebut evaldinotasikan, dan dikalikan dengan produk saat ini.
Kedua, $t-=64-ord for/\pl/g;jumlah dalam $tsetiap huruf ( for/\pl/g). ( ordkembalikan kode ascii untuk surat itu, dan 64-..buat itu antara 1 dan 26.
Akhirnya, $.==$tperiksa bahwa kedua nilai sama, dan ($.**.5|0)**2!=$.itu bukan kotak yang sempurna.


4

Python 2, 267 207 byte

Disimpan 60 byte berkat 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

Fungsi dengan penggunaan: print(g('A1B2C3'))

Cobalah online!



4

Python 3 , 163 156 155 164 161 byte

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

Cobalah online!

  • disimpan 7 byte berkat Jonathan dan Shooqie
  • disimpan 1 byte: Juga Memperbaiki masalah positif palsu. Terima kasih kepada Jonathan karena menunjukkannya!
  • ditambahkan 11 byte: Suntingan sebelumnya salah (penggandaan jumlah digit terjadi dalam satu lingkaran yang tidak diinginkan)

1
from math import*lebih pendek
shooqie

1
Anda tidak perlu a, gunakan saja for x in input():. Anda dapat memiliki positif palsu untuk pelat yang diakhiri dengan string nol (misalnya 11AA00), karena final m*=ttidak dieksekusi.
Jonathan Allan

1
Rupanya, kode saya menunjukkan false positive untuk string dengan nol terisolasi di dalamnya (3A0B juga ditampilkan benar) ... Terima kasih telah menunjukkan bahwa @JonathanAllan. Saya akan mencoba memperbaikinya.
officialaimm

Periksa versi yang lebih baru ... Saya telah menambahkan variabel flag baru 'p' untuk memutuskan apakah akan mengalikan jumlah digit atau tidak.
officialaimm

3

Retina, 143 byte

Mengembalikan 1 untuk true, 0 untuk false

[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 $

Cobalah secara Online!

Penjelasan:

[1-9]
$ *
10 | 01
1

Pertama, kami mengganti semua digit non-nol dengan representasi unary mereka. Kami menghapus nol apa pun dengan angka yang berdekatan sehingga tidak memengaruhi operasi unary kami

S_` (\ D)

Pisahkan string yang dihasilkan pada huruf, hati-hati untuk mengecualikan baris kosong (ini adalah masalah ketika dua huruf berturut-turut AA).

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

Urutkan string secara leksikografis. Kemudian berulang kali lakukan hal berikut:

1) Ganti masing 1- masing dengan jumlah 1s pada baris berikut (ini meniru multiplikasi)

2) Hapus baris kedua 1s

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

Ganti surat J-Sdengan 1J,1K , dll dan mengganti huruf T-Zdengan 2T, 2U, dll Kemudian, ganti masing-masing kelompok A-I, J-Sdan T-Zdengan 1-9. Kami akan dibiarkan dengan nilai numerik setiap huruf (mis. 13Untuk M).

1> `\ d + \ n?
$ *

Konversi setiap baris tetapi yang pertama menjadi unary (baris pertama sudah di unary). Gabungkan garis-garis ini. Kita sekarang dibiarkan dengan string formulir <product of digits>\n<sum of letters>.

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

Ganti nomor kuadrat dengan string kosong. Ini menggunakan metode "pohon perbedaan" .

^ (1 *) \ n \ 1 $

Kembali 1jika kedua string di kedua sisi \npertandingan. Kalau tidak, kembalilah 0.


Positif salah untuk 11AA0,, 0AA11dll.
Jonathan Allan

@ Jonathan Allan Terima kasih! Harganya 11 byte untuk diperbaiki
pecandu matematika
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.