Cửa sổ Pangrammatic ngắn nhất


15

Một pangram là một câu hoặc đoạn trích có chứa tất cả hai mươi sáu chữ cái của bảng chữ cái, như được thể hiện trong thử thách golf mã này . Tuy nhiên, một cửa sổ pangrammatic là một pangram ở dạng một số đoạn văn bản, có thể kết thúc hoặc bắt đầu giữa chừng một từ, được tìm thấy ở đâu đó trong một tác phẩm lớn hơn. Những điều này tự nhiên xảy ra ở khắp mọi nơi, là tập hợp con của pangram thực sự, vì vậy chỉ cần xác minh nếu một cái gì đó chứa một cửa sổ pangrammatic sẽ nhàm chán và nó cũng đã được thực hiện trước đó.

Vì vậy, chúng tôi quan tâm đến việc tìm ra cái nhỏ nhất có trong một đoạn văn bản nhất định dựa trên độ dài chữ cái của nó! Trong mã ngắn nhất có thể tính bằng byte, tất nhiên, để phù hợp với chủ đề.

Nội quy và hướng dẫn

  • Nhận một chuỗi làm đầu vào và trả về chuỗi của cửa sổ pangrammatic nhỏ nhất trong đầu vào nếu có. Nếu không có, trả về Boolean false hoặc chuỗi rỗng.
  • Cho dù một chuỗi có phải là một cửa sổ pangrammatic hay không không phân biệt chữ hoa chữ thường và chỉ phụ thuộc vào 26 chữ cái, không phải bất kỳ dấu câu hoặc số hoặc ký hiệu lẻ nào khác.
  • Tương tự, độ dài chữ cái của cửa sổ pangrammatic là tổng số có bao nhiêu lần xuất hiện của các chữ cái trong đó, và không chỉ đơn giản là số lượng của mỗi ký tự. Giá trị trả về phải nhỏ nhất dựa trên số này. Chúng tôi là những nhà ngôn ngữ học, không phải là lập trình viên.
  • Tuy nhiên, một đầu ra của một cửa sổ pangrammatic phải là một chuỗi con chính xác của đầu vào, có cùng cách viết hoa và dấu câu, v.v.
  • Nếu có nhiều cửa sổ pangrammatic ngắn nhất có cùng độ dài chữ cái, hãy trả lại bất kỳ một trong số chúng.

Các trường hợp thử nghiệm

'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
Đối với trường hợp thử nghiệm cuối cùng, tại sao không được The five boxing wizards jump quicklytrả lại?
Màu xanh

1
Đối với trường hợp thứ hai, bạn có cho phép không gian trước Q? Nó không thêm vào số lượng thư.
Neil

2
@muddyfish Bởi vì nó có 31 chữ cái, trong khi sản lượng dự kiến ​​chỉ có 26.
Martin Ender

4
Câu hỏi đầu tiên rất hay!
Rɪᴋᴇʀ

2
Vâng. Không có lý do gì nó không nên. Lấy tối thiểu "đúng" theo tinh thần của câu hỏi, nhưng không cần thiết.
Reecer6

Câu trả lời:


6

Bình thường, 20 16 14 byte

hol@GNf!-GrT0.:

Giải trình:

             .: - 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(^)

Hãy thử nó ở đây!

Khi không có giải pháp chính xác, chương trình sẽ thoát với lỗi không xuất ra thiết bị xuất chuẩn.


Bạn dường như chưa cập nhật mã trong khối mã đầu tiên. Cũng !-GrT0là ngắn hơn cho các điều kiện bộ lọc, tôi tin. Tôi cũng nghĩ rằng bạn cần phải llàm cho sắp xếp công việc đúng.
FryAmTheEggman

Oh, tôi sai chính tả, tôi có nghĩa là liên kết. Trong liên kết của bạn, bạn vẫn có l, và không có nó, bạn sẽ nhận được kết quả khác nhau . Tôi tin rằng vấn đề là các chữ cái lặp đi lặp lại, nhưng tôi không chắc chắn 100%.
FryAmTheEggman

Vì vậy, nó có vấn đề - và cảm ơn vì đã tối ưu hóa!
Màu xanh


2

Ruby, 100 byte

Trả về nil nếu không tìm thấy cửa sổ.

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

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

Đã lưu 2 byte nhờ @Neil!

Thụt lề

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>


Bạn không thể sử dụng [r=l="",...s].map((_,b,a)=>?
Neil

@Neil Cảm ơn, tôi luôn quên tham số thứ ba trong maphàm.
dùng81655

Tôi nghĩ rằng @ edc65 có thể đánh bại điều này mặc dù, tôi đã hợp nhất mã cho các chuỗi con đã nổ của anh ta với mã đó cho trình kiểm tra pangram của anh ta và kết thúc bằng một hàm 134 byte.
Neil

Tốt nhất của tôi là 142 cho đến nay
edc65

Đáng buồn là tôi đã không nghĩ sẽ cứu nó và PC của tôi bị hỏng nên bây giờ tôi không biết mình có gì; tốt nhất tôi có thể làm bây giờ là 138 byte.
Neil

2

PowerShell v2 +, 218 byte

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

Vâng, do đó, thao tác chuỗi con (không có bất kỳ tích hợp nào) không thực sự phù hợp với PowerShell ...

Chúng tôi nhận đầu vào param($a)và thiết lập một hashtable trống mới $z. Đây sẽ là nơi lưu trữ của chúng tôi các chất nền pangrammatic ứng cử viên.

Sử dụng một sửa đổi nhỏ của mã của tôi từ Substrings , chúng tôi xây dựng tất cả các chuỗi con của đầu vào. Đúng, thậm chí chỉ có một dấu chấm câu. Đây là , không phải . ;-)

Tất cả các chuỗi con được đóng gói trong parens và được dẫn vào một vòng lặp khác với |%{...}. Chúng tôi tạm thời đặt thành $ychuỗi con hiện tại của mình, đặt bộ đếm trợ giúp $jvà bắt đầu một vòng lặp khác 65..90|%{...}, thuận tiện qua mã char ASCII cho chữ in hoa. Mỗi vòng lặp bên trong, chúng tôi lấy $y, làm cho tất cả chữ hoa và rút ra .IndexOfchar cụ thể đó. Vì điều này sẽ trở lại -1nếu không tìm thấy, chúng tôi +1kết quả trước khi nhân nó vào $j. Điều này đảm bảo rằng nếu bất kỳ một ký tự nào không được tìm thấy, $jsẽ bằng không.

Đó là chính xác những gì iflà tất cả về. Nếu $jkhác không, điều đó có nghĩa là mọi chữ cái được tìm thấy ít nhất một lần trong chuỗi con $y, vì vậy chúng ta cần thêm nó vào nhóm ứng cử viên của mình. Chúng tôi làm như vậy bằng cách lấy $yvà lấy -replacemọi chữ cái không có gì, điều đó giúp chúng tôi có độ dài chữ cái của chuỗi con đó. Chúng tôi sử dụng nó làm chỉ mục vào hashtable $zvà lưu trữ $ytại chỉ mục đó. Điều này có nghĩa là các chuỗi con ghi đè có cùng độ dài chữ cái với chuỗi xuất hiện "xa nhất" trong chuỗi gốc, nhưng điều đó được các quy tắc cho phép, vì chúng ta chỉ quan tâm đến độ dài chữ.

Cuối cùng, chúng ta cần sắp xếp $zvà rút ra nhỏ nhất. Chúng ta phải sử dụng các .GetEnumeratorcuộc gọi để sắp xếp trên đối tượng bên trong $z , sau đó sortnhững người trên Name(ví dụ, chỉ số chiều dài từ trên cao), chọn [0]một thứ (ví dụ, ngắn nhất), và xuất của nó .Value(ví dụ, các chuỗi con). Nếu không có chuỗi con nào phù hợp, điều này sẽ gây ra lỗi ( Cannot index into a null array) khi nó cố gắng lập chỉ mục vào $zvà không tạo ra gì, đó là falsey trong PowerShell. (trường hợp thử nghiệm thứ ba dưới đây có một diễn viên rõ ràng [bool]để thể hiện điều này)

Các trường hợp thử nghiệm

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 byte

Điều này thật khó khăn, nhưng thực sự thú vị mà không cần nhập khẩu.

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]

Ít chơi gôn hơn:

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

Ngạc nhiên, ngạc nhiên: nó thực sự rất chậm.


2

Oracle SQL 11.2, 461 byte

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;

Không chơi gôn

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

Khung snhìn chia nhỏ đầu vào theo các ký tự và cũng trả về vị trí của từng ký tự.

Khung nhìn đệ quy vtrả về mọi chuỗi con của
s đầu vào là chuỗi con
f vị trí của ký tự đầu tiên của chuỗi con
l vị trí của ký tự cuối cùng được thêm vào chuỗi con hiện tại

Khung cnhìn trả về bảng chữ cái, mỗi chữ cái một

Khung anhìn trả về bảng chữ cái được nối với nhau dưới dạng một chuỗi

SELECT s,f,SUM(SIGN(INSTR(LOWER(s),c))
Trả về cho mỗi chuỗi con số lượng chữ cái riêng biệt có trong nó
INSTRtrả về vị trí của một chữ cái trong chuỗi con, 0 nếu không xuất hiện
SIGNtrả về 1 nếu pos> 0, 0 nếu pos = 0

WHERE x=26
Lọc chuỗi con chứa toàn bộ bảng chữ cái

TRANSLATE(LOWER(s),' '||a,' ')
Xóa mọi chữ cái khỏi chuỗi con

LENGTH(s)-NVL(LENGTH(TRANSLATE(LOWER(s),' '||a,' ')
Độ dài trong các chữ cái là độ dài của chuỗi con trừ đi độ dài của phép trừ không có chữ cái

SELECT MIN(s)KEEP(DENSE_RANK FIRST ORDER BY LENGTH(s)-NVL(LENGTH(TRANSLATE(LOWER(s),' '||a,' ')),0))
Chỉ giữ lại chuỗi con với số lượng chữ cái nhỏ hơn.
Nếu có nhiều hơn một, chuỗi đầu tiên, được sắp xếp theo chuỗi tăng dần, sẽ được giữ


2

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

Đã lưu 4 byte nhờ DSM.
Đã lưu 8 byte nhờ RootTwo.

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

Phải sắp xếp dựa trên số lượng chữ cái đang giết chết tôi.

Các trường hợp thử nghiệm:

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

Đừng nghĩ .upper()là cần thiết trong chức năng chính.
RootTwo

@RootTwo Rất tiếc, yup, bạn đã đúng. Cảm ơn.
Morgan Thrapp

1

PowerShell (v4), 198 156 byte

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]

Các trường hợp thử nghiệm

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!

Lời giải thích của người ban đầu

Đó là một vòng lặp lồng nhau mạnh mẽ làm cho các cửa sổ trượt ở mọi kích cỡ:

.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

Đối với mỗi cửa sổ, nó chỉ lọc các chữ cái (trường hợp regex không phân biệt theo trường hợp), chạy các ký tự còn lại thông qua một bộ lọc duy nhất, kiểm tra xem có 26 ký tự duy nhất làm thử nghiệm pangram không.

Tất cả các cửa sổ với pangram được chuyển thành bộ ba (số lượng chữ cái bao gồm bản sao, chỉ số bắt đầu, độ dài cửa sổ bao gồm dấu chấm câu) , được sắp xếp để tìm ngắn nhất theo tổng số ký tự, ký tự đầu tiên được chọn và chuỗi đầu ra được tạo từ đó .

Có rất nhiều chỉ mục bên ngoài giới hạn của chuỗi, mà PowerShell trả về một cách hữu ích $ null cho, thay vì đưa ra các ngoại lệ.

Lưu ý 156 byte mới là cách tiếp cận tương tự, nhưng được viết lại để sử dụng đường ống nhiều hơn nữa.

$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 ''
}

Lưu ý không chắc chắn phiên bản không có tác dụng, bởi vì tôi đã không viết rằng sau đó chơi nó, nó chỉ để giải thích.


0

Haskell, 123 byte

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

Xác định một hàm h, trả về danh sách trống nếu không có cửa sổ pangrammatic hoặc danh sách một thành phần với cửa sổ tối thiểu. Ví dụ sử dụng:

*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"]

Làm thế nào nó hoạt động:

          [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!
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.