En Kısa Pangrammatik Pencere


15

Pangram, bu kod golf mücadelesinde gösterildiği gibi, alfabenin yirmi altı harfinin tümünü içeren bir cümle veya alıntıdır . Ancak pangramatik bir pencere , daha büyük bir işin içinde bir yerde bulunan, bir kelimenin yarısına kadar bitebilen veya başlayabilen bir metin bölümü biçimindeki bir pangramdır. Bunlar doğal olarak her yerde, gerçek pangramların uygun alt kümeleri olarak gerçekleşir, bu yüzden bir şeyin pangramatik bir pencere içerdiğini doğrulamak sıkıcı olurdu ve daha önce yapıldı.

Yani, harf uzunluğuna göre belirli bir metinde en küçük olanı bulmak istiyoruz! Tabii ki, temayı sığdırmak için bayt cinsinden mümkün olan en kısa kodda.

Kurallar ve Yönergeler

  • Girdi olarak bir dize alın ve varsa girişteki en küçük pangrammatik pencerenin dizesini döndürün. Yoksa, bir Boolean False veya boş bir dize döndürün.
  • Bir dizenin pangramatik bir pencere olup olmadığı büyük / küçük harfe duyarlı değildir ve yalnızca 26 harfe bağlıdır, herhangi bir noktalama işareti, sayı veya diğer tek sembollere bağlı değildir.
  • Benzer şekilde, pangramatik bir pencerenin harf uzunluğu , sadece her karakterin sayısı değil, yalnızca harflerin kaç kez göründüğünün toplam sayısıdır . Döndürülen değer bu sayıya göre en küçük olmalıdır. Sonuçta biz dilbilimciyiz, programcı değil.
  • Bununla birlikte, bir pangramatik pencerenin çıktısı, aynı büyük harf ve noktalama işaretlerini vb. İçeren girdinin tam bir alt dizesi olmalıdır.
  • Aynı harf uzunluğuna sahip birden çok kısa pangrammatik pencere varsa, bunlardan herhangi birini döndürün.

Test Durumları

'This isn't a pangram.'
==> False

'Everyone knows about that infamous Quick-Brown-Fox (the one who jumped over some lazy ignoramus of a dog so many years ago).'
==> 'Quick-Brown-Fox (the one who jumped over some lazy ig'

'"The five boxing wizards jump quickly." stated Johnny, before beginning to recite the alphabet with a bunch of semicolons in the middle. "ABCDEFGHI;;;;;;;;;;;;;;;JKLMNOPQRSTUVWXYZ!" he shouted to the heavens.'
==> 'ABCDEFGHI;;;;;;;;;;;;;;;JKLMNOPQRSTUVWXYZ'

1
Son test vakası için neden The five boxing wizards jump quicklyiade edilmiyor ?
Mavi

1
İkinci durum için, önceki alanın önüne izin veriliyor Qmu? Harf sayısına eklenmez.
Neil

2
@muddyfish 31 harfi olduğu için, beklenen çıktı sadece 26.
Martin Ender

4
Güzel bir ilk soru!
Rɪᴋᴇʀ

2
Evet. Olmaması için hiçbir sebep yok. Sorunun ruhunda "gerçek" minimumları almak , ama gerekli değildir.
Reecer6

Yanıtlar:


6

Pyth, 20 16 14 bayt

hol@GNf!-GrT0.:

Açıklama:

             .: - substrings of input()
      f!-GrT0   - filter to ones which contain the alphabet
 ol@GN          - sort by number of alphabetical chars
h               - ^[0]

      f!-GrT0   - filter(lambda T:V, substrings)
          rT0   -    T.lower()
        -G      -   alphabet-^
       !        -  not ^

 o              - sort(^, lambda N:V)
   @GN          -   filter_presence(alphabet, N)
  l             -  len(^)

Burada deneyin!

Doğru bir çözüm olmadığında, program stdout'a çıkış olmadan bir hata ile çıkar.


İlk kod bloğundaki kodu güncellememişsiniz gibi görünüyor. Ayrıca !-GrT0filtre durumu için daha kısa olduğuna inanıyorum. Ben de ltür düzgün çalışması için gerekli olduğunu düşünüyorum .
FryAmTheEggman

Oh, yanlış telaffuz ettim, bağlantıyı kastetmiştim. Bağlantınızda hala var lve onsuz farklı sonuçlar elde edersiniz . Sorunun tekrarlanan mektuplar olduğuna inanıyorum, ancak% 100 emin değilim.
FryAmTheEggman

Bu yüzden önemli - ve optimizasyon için teşekkürler!
Mavi


2

Yakut, 100 bayt

Pencere bulunmazsa nil değerini döndürür.

->s{r=0..s.size
(r.map{|i|s[i,r.find{|j|(?a..?z).all?{|c|s[i,j]=~/#{c}/i}}||0]}-['']).min_by &:size}

2

JavaScript (ES6), 139 138 136 bayt

s=>[r=l="",...s].map((_,b,a)=>a.map((c,i)=>i>b&&(t+=c,z=parseInt(c,36))>9&&(v++,n+=!m[z],m[z]=n<26||l&&v>l||(r=t,l=v)),t=m=[],v=n=0))&&r

@Neil sayesinde 2 bayt kaydedildi!

senetli

var solution =

s=>
  [r=l="",...s].map((_,b,a)=> // b = index of start of window to check
    a.map((c,i)=>
      i>b&&(
        t+=c,
        z=parseInt(c,36)
      )>9&&(
        v++,
        n+=!m[z],
        m[z]=
          n<26||
          v>l&&l||(
            r=t,
            l=v
          )
      ),
      t=m=[],
      v=n=0
    )
  )
  &&r
<textarea cols="70" rows="6" id="input">Everyone knows about that infamous Quick-Brown-Fox (the one who jumped over some lazy ignoramus of a dog so many years ago).</textarea><br /><button onclick="result.textContent=solution(input.value)">Go</button><pre id="result"></pre>


Kullanamaz mısın [r=l="",...s].map((_,b,a)=>?
Neil

@Neil Teşekkürler, işlevdeki üçüncü parametreyi her zaman unuturum map.
user81655

@ Edc65 olsa da yenebilir düşünüyorum, ben onun patladı alt dizeleri için kod onun pangram test cihazı ile birleştirdi ve 134 bayt işlevi ile sona erdi.
Neil


Ne yazık ki kaydetmeyi düşünmedim ve bilgisayarım çöktü, şimdi ne olduğumu bilmiyorum; şimdi yapabileceğim en iyi şey 138 byte.
Neil

2

PowerShell v2 +, 218 bayt

param($a)$z=@{};(0..($b=$a.length-1)|%{($i=$_)..$b|%{-join$a[$i..$_]}})|%{$y=$_;$j=1;65..90|%{$j*=$y.ToUpper().IndexOf([char]$_)+1};if($j){$z[($y-replace'[^A-Za-z]').Length]=$y}}
($z.GetEnumerator()|sort Name)[0].Value

Evet, bu yüzden alt dize manipülasyonu (herhangi bir yerleşik yok) gerçekten PowerShell'in güçlü kıyafeti değil ...

Girdi alıyor param($a)ve yeni bir boş hashtable ayarlıyoruz$z . Bu, aday pangrammatik alt dizeleri depolamamız olacak.

Benim kod hafif modifikasyonu kullanılarak Ayrılmış alt dizeleri , biz inşa tüm giriş substrings. Evet, tek karakterli noktalama işaretleri içeren alt dizeler bile. Bu , değil . ;-)

Bu alt dizelerin tümü parens içinde kapsüllenir ve başka bir döngüye |%{...} . Geçici olarak $ymevcut alt dizemize ayarladık, bir yardımcı sayaç ayarladık $jve 65..90|%{...}büyük harfler için ASCII karakter kodları üzerinden uygun bir şekilde başka bir döngü başlattık . Her iç döngü, $yhepsini alır , büyük harf yaparız ve .IndexOfbelirli karakteri çıkarırız. Bu -1bulunmazsa geri döneceğinden +1, sonucu çarpmadan önce elde ederiz $j. Bu, herhangi bir karakter bulunmazsa $jsıfıra eşit olmasını sağlar .

Bu tam olarak bununla ifilgili. $jSıfır değilse , bu, her harfin alt dize içinde en az bir kez bulunduğu anlamına gelir $y, bu yüzden bunu aday havuzumuza eklememiz gerekir. Biz alarak bunu $yve -replacebize bu alt dizeyi mektubu uzunlukta alır hiçbir şey olmayan her harfi, ing. Bunu, hashtable $zve $yindex dizininde saklamak için dizin olarak kullanırız. Bu, orijinal dizede "en uzak" olanla aynı harf uzunluğundaki alt dizelerin üzerine yazma tuhaflığına sahiptir, ancak kurallara izin verilir, çünkü yalnızca harf uzunluğu ile ilgileniyoruz.

Son olarak, $zen küçüğünü sıralamamız ve çıkarmamız gerekiyor . Biz kullanmak zorunda .GetEnumeratorüzerinde tür amacıyla çağrı içi nesneler $z , sonrasort üzerinde bu Nameseçilmesi, (yukarıdan yani uzunluk indeksi) [0](yani, en kısa) inci birini ve onun çıkışının .Value(yani alt dize). Böyle bir alt dize uygun değilse, Cannot index into a null arraydizin oluşturmaya çalıştığında bu bir hata ( ) atar$z ve PowerShell'de falsey olan hiçbir şey çıkarmaz. (aşağıdaki üçüncü test durumunda,[bool] bunu gösterecek )

Test Durumları

PS C:\Tools\Scripts> .\golfing\shortest-pangrammatic-window.ps1 '"The five boxing wizards jump quickly." stated Johnny, before beginning to recite the alphabet with a bunch of semicolons in the middle. "ABCDEFGHI;;;;;;;;;;;;;;;JKLMNOPQRSTUVWXYZ!" he shouted to the heavens.'
ABCDEFGHI;;;;;;;;;;;;;;;JKLMNOPQRSTUVWXYZ!" 

PS C:\Tools\Scripts> .\golfing\shortest-pangrammatic-window.ps1 'Everyone knows about that infamous Quick-Brown-Fox (the one who jumped over some lazy ignoramus of a dog so many years ago).'
Quick-Brown-Fox (the one who jumped over some lazy ig

PS C:\Tools\Scripts> [bool](.\golfing\shortest-pangrammatic-window.ps1 "This isn't a pangram.")
Cannot index into a null array.
At C:\Tools\Scripts\golfing\shortest-pangrammatic-window.ps1:2 char:1
+ ($z.GetEnumerator()|sort Name)[0].Value
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

False

2

Haskell, 180 bayt

Bu zor, ama ithalat olmadan gerçekten eğlenceliydi.

l=['a'..'z']
u=['A'..'Z']
f&[]=[];f&x=x:f&f x
g#h=(.g).h.g
f x|v<-[y|y<-(tail&)=<<(init&x),and$zipWith((`elem`y)#(||))l u]=last$[]:[z|z<-v,all((length.filter(`elem`l++u))#(<=)$z)v]

Çok daha az golf:

lowerCase = ['a'..'z']
upperCase = ['A'..'Z']

f & x = takeWhile (not . null) $ iterate f x

(#) = flip on

subStrings x = (tail &) =<< (init & x)

pangram p = and $ zipWith ((`elem` p) # (||)) lowerCase upperCase

leqLetters x y = (length . filter (`elem` lowerCase ++ upperCase)) # (<=)

fewestLetters xs = [ x | x <- xs, all (leqLetters x) xs]

safeHead [] = ""
safeHead xs = head xs

f x = safeHead . fewestLetters . filter pangram . subStrings

Sürpriz, sürpriz: Gerçekten yavaş.


2

Oracle SQL 11.2, 461 bayt

WITH s AS (SELECT SUBSTR(:1,LEVEL,1)c,LEVEL p FROM DUAL CONNECT BY LEVEL<=LENGTH(:1)),v(s,f,l)AS(SELECT c,p,p FROM s UNION ALL SELECT s||c,f,p FROM v,s WHERE p=l+1),c AS(SELECT CHR(96+LEVEL)c FROM DUAL CONNECT BY LEVEL<27),a AS(SELECT LISTAGG(c)WITHIN GROUP(ORDER BY 1) a FROM c)SELECT MIN(s)KEEP(DENSE_RANK FIRST ORDER BY LENGTH(s)-NVL(LENGTH(TRANSLATE(LOWER(s),' '||a,' ')),0))FROM(SELECT s,f,SUM(SIGN(INSTR(LOWER(s),c)))x FROM v,c GROUP BY s,f),a WHERE x=26;

Un-golfed

WITH s AS (SELECT SUBSTR(:1,LEVEL,1)c,LEVEL p FROM DUAL CONNECT BY LEVEL<=LENGTH(:1))
,v(s,f,l) AS
(
  SELECT c,p,p FROM s
  UNION ALL
  SELECT s||c,f,p FROM v,s WHERE p=l+1 
)
,c AS(SELECT CHR(96+LEVEL)c FROM DUAL CONNECT BY LEVEL<27)
,a AS(SELECT LISTAGG(c)WITHIN GROUP(ORDER BY 1) a FROM c)
SELECT MIN(s)KEEP(DENSE_RANK FIRST ORDER BY LENGTH(s)-NVL(LENGTH(TRANSLATE(LOWER(s),' '||a,' ')),0))
FROM(SELECT s,f,SUM(SIGN(INSTR(LOWER(s),c)))x FROM v,c GROUP BY s,f),a
WHERE x=26

sGörünüm karakterleri girdi böler ve aynı zamanda her karakterin konumunu döndürür.

Özyinelemeli görünüm v, girişlerin her alt dizesini
, alt dizenin
ilk karakterinin konumu olan alt dize döndürür
konumu l geçerli alt dizeye eklenen son karakterin konumu olarak

cGörünümü bir anda alfabe, bir harfi döndürür

aGörünümü tek bir dize birleştirilmiş alfabeyi döndürür

SELECT s,f,SUM(SIGN(INSTR(LOWER(s),c))
Her alt dize için içinde bulunan ayrı harflerin sayısını
INSTRdöndürür, alt dizedeki bir harfin konumunu döndürür,
SIGNyoksa 0, pos> 0 ise 1, pos = 0 ise 0 döndürür

WHERE x=26
Alfabenin tamamını içeren alt dizeyi filtreler

TRANSLATE(LOWER(s),' '||a,' ')
Alt dizedeki her harfi siler

LENGTH(s)-NVL(LENGTH(TRANSLATE(LOWER(s),' '||a,' ')
Harf cinsinden uzunluk, alt dizenin uzunluğu eksi harfsiz alt dizinin uzunluğudur

SELECT MIN(s)KEEP(DENSE_RANK FIRST ORDER BY LENGTH(s)-NVL(LENGTH(TRANSLATE(LOWER(s),' '||a,' ')),0))
Yalnızca küçük harf sayısına sahip alt dizeyi tutar.
Birden fazla varsa, ilki artan olarak dizilmiş olarak sıralanır.


2

Python 3, 171, 167, 163, 157 , 149 bayt.

DSM sayesinde 4 bayt tasarruf etti.
RootTwo sayesinde 8 bayt tasarruf etti.

lambda x,r=range:min([x[i:j]for i in r(len(x))for j in r(len(x))if{*map(chr,r(65,91))}<={*x[i:j].upper()}]or' ',key=lambda y:sum(map(str.isalpha,y)))

Harf sayısına göre sıralama yapmak beni öldürüyor.

Test senaryoları:

assert f("This isn't a pangram.") == ' '
assert f("Everyone knows about that infamous Quick-Brown-Fox (the one who jumped over some lazy ignoramus of a dog so many years ago).") == ' Quick-Brown-Fox (the one who jumped over some lazy ig', f("Everyone knows about that infamous Quick-Brown-Fox (the one who jumped over some lazy ignoramus of a dog so many years ago).")
assert f('"The five boxing wizards jump quickly." stated Johnny, before beginning to recite the alphabet with a bunch of semicolons in the middle. "ABCDEFGHI;;;;;;;;;;;;;;;JKLMNOPQRSTUVWXYZ!" he shouted to the heavens.') == '. "ABCDEFGHI;;;;;;;;;;;;;;;JKLMNOPQRSTUVWXYZ', f('"The five boxing wizards jump quickly." stated Johnny, before beginning to recite the alphabet with a bunch of semicolons in the middle. "ABCDEFGHI;;;;;;;;;;;;;;;JKLMNOPQRSTUVWXYZ!" he shouted to the heavens.')

.upper()Anahtar fonksiyonda gerekli olduğunu düşünmeyin .
RootTwo

@RootTwo Oops, evet, haklısın. Teşekkürler.
Morgan Thrapp

1

PowerShell (sürüm 4), 198156 bayt

param($s)
-join(@(1..($y=$s.Length)|%{$w=$_
0..$y|%{(,@($s[$_..($_+$w)]))}}|?{($_-match'[a-z]'|sort -U).Count-eq26}|sort -Pr {($_-match'[a-z]').count})[0])


# Previous 198 byte golf
$a,$b,$c=@(1..($s="$args").Length|%{$w=$_
0..($s.Length-$w)|%{if((($t=$s[$_..($_+$w)]-match'[a-z]')|sort -u).Count-eq26){(,@($t.Length,$_,$w))}}}|sort -pr{$_[0]})[0]
(-join($s[$b..($b+$c)]),'')[!$a]

Test Durumları

PS C:\> .\PangramWindow.ps1 "This isn't a pangram."


PS C:\> .\PangramWindow.ps1 'Everyone knows about that infamous Quick-Brown-Fox (the one who jumped over some lazy ignoramus of a dog so many years ago).'
Quick-Brown-Fox (the one who jumped over some lazy ig

PS C:\> .\PangramWindow.ps1 '"The five boxing wizards jump quickly." stated Johnny, before beginning to recite the alphabet with a bunch of semicolons in the middle. "ABCDEFGHI;;;;;;;;;;;;;;;JKLMNOPQRSTUVWXYZ!" he shouted to the heavens.'
ABCDEFGHI;;;;;;;;;;;;;;;JKLMNOPQRSTUVWXYZ!

Orijinalin açıklanamayan açıklaması

Her boyuttaki sürgülü pencereleri yapan kaba kuvvet iç içe bir döngüdür:

.SubString(0, 1) -> slide window over the string
.SubString(0, 2) -> slide window over the string
..
.SubString(0, string.Length) -> slide window over the string

Her pencere için yalnızca harfleri filtreler (varsayılan olarak büyük / küçük harfe duyarsız regex eşleşmesi), kalan karakterleri benzersiz bir filtreden geçirir, pangram testi olarak 26 benzersiz karakter olup olmadığını kontrol eder.

Pangramlı tüm pencereler, genel karakter sayısına göre en kısa olanı bulmak için sıralanan üçüncüye (dupes, başlangıç ​​dizini, noktalama işareti dahil pencere uzunluğu) üçlüye dönüşür , ilki seçilir ve bundan çıkış dizesi .

Dizenin sınırları dışında, PowerShell'in istisnalar atmak yerine yararlı olarak $ null döndürdüğü bir çok dizinleme vardır.

NB. yeni 156 baytlık aynı yaklaşımdır, ancak boru hattını çok daha fazla kullanmak için yeniden yazılmıştır.

$string = "$args"

# increasing window widths, outer loop
$allPangramWindows =  foreach ($windowWidth in 1..$string.Length) {

    # sliding windows over string, inner loop
    0..($string.Length - $windowWidth) | ForEach {

        # slice window out of string, returns a char array
        $tmp = $string[$_..($_+$windowWidth)]

        # filter the char array to drop not-letters
        $tmp = $tmp -match '[a-z]'

        # Drop duplicate letters
        $tmpNoDupes = $tmp | sort -Unique

        # If we're left with a 26 character array, this is a pangrammatic window. Output
        # a PowerShell-style tuple of count of letters, start index, width.
        if($tmpNoDupes.Count -eq 26){
            (,@($tmp.Length,$_,$windowWidth))
        }
    }
}

# Force the result into an array (to handle no-results), sort it
# by the first element (num of letters in the window, total)
$allPangramWindows = @( $allPangramWindows | sort -Property {$_[0]} )

# take element 0, a window with the fewest letters
$windowCharCount, $windowStart, $WindowEnd = $allPangramWindows[0]

# uses the results to find the original string with punctuation and whitespace
if ($windowLen) {
    $string[$windowStart..($windowStart + $windowLen)] -join ''
}

NB. ungolfed versiyonunun çalıştığından emin değilim, çünkü o zaman golf yazmadım, sadece fuar için.


0

Haskell, 123 bayt

import Data.Lists
import Data.Char
h x=take 1$sortOn((1<$).filter isAlpha)[e|e<-powerslice x,['a'..'z']\\map toLower e==""]

hPangrammatik pencere veya minimum pencereli bir öğe listesi varsa boş listeyi döndüren bir işlev tanımlar . Kullanım örneği:

*Main>  h "'The five boxing wizards jump quickly.' stated Johnny, before beginning to recite the alphabet with a bunch of semicolons in the middle. 'ABCDEFGHI;;;;;;;;;;;;;;;JKLMNOPQRSTUVWXYZ!' he shouted to the heavens."
[". 'ABCDEFGHI;;;;;;;;;;;;;;;JKLMNOPQRSTUVWXYZ"]

Nasıl çalışır:

          [e|e<-powerslice x                  ]  -- for all continuous subsequences
                                                 -- e of the input  
                ,['a'..'z']\\map toLower e==""   -- keep those where the list
                                                 -- difference with all letters is
                                                 -- empty, i.e. every letter appears
                                                 -- at least once
    sortOn((1<$).filter isAlpha)                 -- sort all remaining lists on
                                                 -- their length after removing all
                                                 -- non-letters -> (1<$) see below
take 1                                           -- take the first, i.e. the minimum


calculating the length of a list: we're not interested in the length itself, but
in the relative order of the length. (1<$) replaces each element in a list with
the number 1, e.g. "abc" -> "111", "abcd" -> "1111", etc. Such '1'-strings have
the same order as the length of the original list. One byte saved!
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.