Levenshtein Komşuları


20

Çoğu kare sayılar onların hangi sahip en az 1 farklı kare sayısına sahip Levenshtein mesafesi Tam olarak belirli kare için 1'dir , bir adlandırılan bu durumun karşılayan her kareyi Levenshtein komşu arasında . Örneğin, , bir Levenshtein komşusudur , çünkü sadece 1 düzenleme ( ) gereklidir. Ancak, bir Levenshtein komşu değil o 2 düzenlemelerin az gerektirir olarak. Başında 0'lar ( ) olan sayılar Levenshtein komşuları değildir .xx36161364162025025

Göreviniz bir kare sayısını giriş olarak almak ve herhangi bir makul formatta Levenshtein komşularının tam listesini çıkarmaktır. İsterseniz, listeye tekrar komşuları dahil edebilirsiniz, ancak kendi başına bir Levenshtein komşusu olmadığı için orijinal girişi dahil edemezsiniz.

Herhangi bir makul format, çıkışlar arasında ,bir satırsonu veya bir yeni satır içermelidir ve karakterleri sayıların kendisinden ziyade karşılık gelen Unicode değerine (yani beyin sapı) sahip olabilir. Çıktının sırası önemli değil.

Bu giriş her zaman büyük bir kare sayı olacaktır . Programınızın teorik bir sınırı olmamalıdır , ancak pratik nedenlerle (örneğin 32-bit sayıların ötesinde) çok sayıda başarısız olursa, bu tamamen iyidir.0

Girişin herhangi bir Levenshtein komşusu yoksa, çıktı hiçbir şey, boş bir dizi / dize, negatif bir tamsayı, vb.0

Bu , bu yüzden bayttaki en kısa kod kazanır.

Test senaryoları

Bunlar kadar olan karelerin sonuçlarıdır :120

  1: 4, 9, 16, 81
  4: 1, 9, 49, 64
  9: 1, 4, 49
 16: 1, 36, 169, 196
 25: 225, 256, 625
 36: 16, 361
 49: 4, 9
 64: 4
 81: 1, 841
100: 400, 900, 1600, 8100
121: 1521
144: 1444
169: 16, 1369
196: 16, 1296, 1936
225: 25, 625, 1225, 2025, 4225, 7225
256: 25
289: 2809
324: 3249
361: 36, 961
400: 100, 900, 4900, 6400

Buna ek olarak, 1024herhangi bir komşusu yoktur, bu yüzden iyi bir test vakasıdır.


3
Daha ilginç olan komşuların ne olacağıdır 2025.
Neil

6
Bir şeyi kaçırmadıkça, 32 * 32 = 1024kare Levenshtein komşuları yok.
xnor

2
@xnor Evet, haklı olduğuna inanıyorum 1024, herhangi bir Levenshtein komşusu yok, bu örneği düzenleyeceğim
caird coinheringaahing

6
"Herkes için ..." biçimindeki tüm ifadeler için, bir karşı örnek bulunabiliyorsa, bu ifadenin titiz bir şekilde kanıtlanmasıdır. (Ama yanılıyorsam, karşı bir örneği katı bir geçirmez olarak kabul edeceğim.)
Neil

2
Orijinal numarayı çıktıya ekleyebilir miyiz? Örneğin 49 -> 4, 9, 49.
Robin Ryder

Yanıtlar:


7

05AB1E ,  11 10  6 bayt

-4 Grimy sayesinde! (kareler aramak yerine ilk kare 3 kaydeder; 10 ^ n tasarruf 1 kullanın)

°Lnʒ.L

Bir tam sayı alır, muhtemelen boş bir liste çıkarır

Çevrimiçi deneyin! - Bu çılgınca yavaş olduğu için°, bu yüzden bunu denemenin bir anlamı yok9.
Veya biraz daha hızlı bir sürümü deneyin - Bu, yerine sekiz ekler,8+ardından aynı yaklaşımı kullanır.

Nasıl?

°Lnʒ.L - f(integer)    stack = n
°      - push 10^n             10^n
 L     - range                 [1,2,3,...,10^n]
  n    - square                [1,4,9,...,10^2n]
   ʒ   - filter keep if == 1:
    .L -   Levenshtein distance

1
9s«Senin 11-Byter olabilirdi . Yine de güzel bir cevap! Benden +1.
Kevin Cruijssen

7 Yavaş: т+Lnʒ.L. Gülünç 6 yavaş: °Lnʒ.L. Sonsuz 5 yavaş: ∞nʒ.L.
Grimmy

1
@Grimy Teşekkürler - neden yeryüzünde ilk kareyi düşünmedim:. Bu sonsuz bir "tümünü göster" sorusu için kabul edilebilir mi? (Üreteçleri işlev gönderimleri olarak gönderebileceğimizi görüyorum, ancak kodlanmış bir durma noktası yoksa, bize ne zaman nihai değer verildiğini bilemeyiz).
Jonathan Allan

∞nʒ.LBir cevap olarak kabul edilebilir olduğunu düşünmüyorum çünkü sunumların sona ermesi gerekiyor . İlgisiz: 7 baytlık sürüm için TIO bağlantınız kullanır ; bu, T+büyük sayılardan ~ 100 kat daha yavaştır . Yorumum т+güvenli olarak kullanıldı (100 ekleyin), ancak 8+her durumda yeterli.
Grimmy

@ Berbat ayy, teşekkürler. 1'in sadece ilk 9 kareyi kontrol etmesi gerektiğinden 100'ün fazla olduğunu düşündüm.
Jonathan Allan

5

Retina 0.8.2 , 142 138 bayt

.?
$'¶$`#$&$'¶$`#$'¶$`$&
#
0$%'¶$%`1$%'¶$%`2$%'¶$%`3$%'¶$%`4$%'¶$%`5$%'¶$%`6$%'¶$%`7$%'¶$%`8$%'¶$%`9
A`^0
Dr`
\d+
$*
-2G`(\b1|11\1)+\b
%`1

Çevrimiçi deneyin! Açıklama:

.?
$'¶$`#$&$'¶$`#$'¶$`$&

Her bir basamak için a) onu kaldırmayı deneyin b) farklı bir basamakla önce gelen c) farklı bir basamakla değiştirerek. Şimdilik, farklı basamak a ile işaretlenmiştir #.

#
0$%'¶$%`1$%'¶$%`2$%'¶$%`3$%'¶$%`4$%'¶$%`5$%'¶$%`6$%'¶$%`7$%'¶$%`8$%'¶$%`9

Her potansiyel farklı basamak için, olası her basamak yerine koyun.

A`^0

Şimdi sıfır ile başlayan sayıları kaldırın.

Dr`

Çoğaltılan tüm numaraları kaldırın. (Bu sadece satırları boş bırakır.)

\d+
$*

Tekli'ye dönüştür.

-2G`(\b1|11\1)+\b

Son hariç tüm kare numaralarını sakla (her zaman girdi numarasıdır).

%`1

Kalan sayıları ondalığa çevirin.


5

R , 42 41 bayt

(9n)2

function(n,y=(1:(9*n))^2)y[adist(n,y)==1]

Çevrimiçi deneyin!

n91n1911009100(9n)2=81n2n>181n2>91nn=119191 bir kare değil, biz iyiyiz.

1(9n)2


4

Piton 2 , 173 167 149 148 147 144 139 138 bayt

lambda n,I=int:{(I(I(v)**.5)**2==I(v))*I(v)for v in[`n`[:i]+`j-1`[:j]+`n`[i+k:]or 0for j in range(11)for i in range(n)for k in 0,1]}-{0,n}

Çevrimiçi deneyin!

19 + 3 + 5 + 1 = 28 ! Jonathan Allan'a bayt teşekkürler .


48 tasarruf edin . [p for p in...]gereksizdir. Bir set (veya kopyalar) döndürebiliriz. '0'<v[:1]olabilir '1'<=v. Çok daha yavaş ama range(len(a)+1)olabilir range(n). Toplamı önlemek için ive i+1dilimleri için bir değişken kullanın . Bir lambda kullanın. Bir öncekinden 48 tasarruf EDIT.
Jonathan Allan

@Jonathan Allan: Ben zaten aynı değişikliklerden bazılarını yapmıştım; ama kesinlikle 18 bayt takdir!
Chas Brown


@Jonathan Allan: Güzel! Şimdi zar zor okunabilir :).
Chas Brown

1
@Jonathan Allan: Lol, sadece güncellemeyi bırakacağım - devam edemiyorum! :)
Chas Brown

3

Oracle SQL, 93 bayt

select level*level from t where utl_match.edit_distance(x,level*level)=1connect by level<10*x

SQL * PLus'ta test edin.

SQL> set heading off
SQL> with t(x) as (select 225 from dual)
  2  select level*level from t where utl_match.edit_distance(x,level*level)=1connect by level<10*x
  3  /

         25
        625
       1225
       2025
       4225
       7225

6 rows selected.

2

PHP , 62 bayt

for(;$argn*92>$n=++$i**2;levenshtein($argn,$n)==1&&print$n._);

Çevrimiçi deneyin!

Bu komut dosyası, Levenshtein girdi komşularını _bir arka ayırıcıyla ayrılmış olarak yazdırır ve hiçbir komşu bulunmazsa hiçbir şey yazdırmaz.

Mutlu bir şekilde PHP Levenshtein mesafe için yerleşik vardır ! input * 91Tüm geçerli Levenshtein komşuları (1 mesafesi) bu aralıkta olduğundan , bu komut dosyası 1'den tüm kare sayılarına döner. Ardından, girişle Levenshtein mesafesi 1 olan bu aralıktaki her sayıyı yazdırır.


2

JavaScript (V8) ,  129125123  bayt

Girişi dize olarak alır. Levenshtein komşularını STDOUT'a yazdırır.

s=>{for(t=9+s;t;t--)(t+='')**.5%1||(g=m=>m*n?1+g(m,--n)*(g(--m)-(s[m]==t[n++]))*g(m):m+n)(s.length,n=t.length)-1||print(t)}

Çevrimiçi deneyin!

Yorumlananlar

s => {                        // s = input
  for(                        // loop:
    t = 9 + s;                //   start with t = '9' + s
    t;                        //   repeat while t > 0
    t--                       //   decrement t after each iteration
  )                           //
    (t += '')                 //   coerce t to a string
    ** .5 % 1 ||              //   abort if t is not a square
    ( g =                     //   g is a recursive function to test whether the
                              //   Levenshtein distance between s and t is exactly 1
      m =>                    //   m = pointer into s (explicit parameter)
                              //   n = pointer into t (defined in the global scope)
        m * n ?               //     if both m and n are greater than 0:
          1 +                 //       add 1 to the final result and add the product of:
          g(m, --n) * (       //         - a recursive call with m and n - 1
            g(--m) -          //         - a recursive call with m - 1 and n - 1
            (s[m] == t[n++])  //           minus 1 if s[m - 1] = t[n - 1]
          ) *                 //
          g(m)                //         - a recursive call with m - 1 and n
        :                     //       else:
          m + n               //         stop recursion and return m + n
    )(s.length, n = t.length) //   initial call to g with m = s.length, n = t.length
    - 1 ||                    //   abort if the final result is not 1
    print(t)                  //   otherwise, print t
}                             //

SpiderMonkey'in olduğunu biliyordum print()ama Düğümün de olduğunu fark etmedim ...
Neil

@Neil Aslında, Düğümde mevcut değil. Bu sürümün tarayıcı sürümüne çok daha yakın olan V8'in bir kabuk yapısı olduğunu düşünüyorum.
Arnauld

2

Jöle , 53 38 bayt

D;Ɱ⁵ṭJœP,œṖjþ⁵Ẏṭ@ḢF${ʋʋ€$ƲẎ%⁵1ị$ƇḌƲƇḟ

Çevrimiçi deneyin!

Levenshtein mesafesi için yerleşik değildir, bu nedenle olası tüm 1 mesafe düzenlemelerini üretir ve ardından sıfır önde olanları hariç tutar ve sadece mükemmel kareleri tutar. Kopyaları filtrelemez (izin verildiği gibi).


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.