最短パングラマティックウィンドウ


15

このコードゴルフチャレンジで示されているように、パングラムはアルファベットの26文字すべてを含む文または抜粋です。ただし、パングラマティックウィンドウは、テキストの一部の形をしたパングラムであり、単語の途中で終了または開始する場合があり、大きな作品のどこかにあります。これらはどこでも自然に発生し、真のパングラムの適切なサブセットであるため、パングラマティックウィンドウが含まれているかどうかを確認するだけでは退屈になりますが、それも以前に行われました。

そのため、文字の長さに基づいて、特定のテキストにある最小のものを見つけることに興味があります!もちろん、可能な限り短いバイト単位のコードで、テーマに合わせます。

ルールとガイドライン

  • 文字列を入力として受け取り、入力に最小のパングラマティックウィンドウがある場合はそのウィンドウの文字列を返します。存在しない場合は、ブール値のFalseまたは空の文字列を返します。
  • 文字列がパングラマティックウィンドウであるかどうかは大文字と小文字を区別せず、26文字のみに依存し、句読点や数字、その他の奇数記号には依存しません。
  • 同様に、パングラマティックウィンドウの文字の長さは、単にすべての文字の数ではなく、文字の出現回数の合計だけです。返される値は、このカウントに基づいて最小でなければなりません。結局のところ、私たちは言語学者であり、プログラマーではありません。
  • ただし、パングラマティックウィンドウの出力は、同じ大文字と句読点などを含む、入力の正確な部分文字列である必要があります。
  • 同じ文字長の複数の最短パングラマティックウィンドウがある場合は、いずれかを返します。

テストケース

'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
最後のテストケースでは、なぜThe five boxing wizards jump quickly返されないのですか?
ブルー

1
2番目の場合、Q?の前にスペースを入れますか?文字数には追加されません。
ニール

2
@muddyfish期待される出力のみ26であるのに対し、それは、31個の文字を持っているので
マーティン・エンダー

4
素敵な最初の質問!
Rɪᴋᴇʀ

2
うん。すべきではない理由はありません。質問の精神で「真の」最小値をとるが、それは必要ではない。
-Reecer6

回答:


6

Pyth、20 16 14バイト

hol@GNf!-GrT0.:

説明:

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

ここで試してみてください!

正しい解決策がない場合、プログラムは標準出力への出力なしでエラーで終了します。


最初のコードブロックのコードを更新していないようです。また!-GrT0、フィルター条件の方が短いと思います。またl、ソートを適切に機能させる必要があると思います。
FryAmTheEggman

ああ、私は間違えた、私はリンクを意味した。あなたのリンクにはまだありますがl、それなしでは異なる結果が得られます。問題は文字が繰り返されることだと思いますが、100%確信はありません。
FryAmTheEggman

重要です-最適化に感謝します!
ブルー


2

ルビー、100バイト

ウィンドウが見つからない場合はnilを返します。

->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バイト

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のおかげで2バイト節約できました!

インデント

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>


使用できません[r=l="",...s].map((_,b,a)=>か?
ニール

@Neilありがとう、私はいつもmap関数の3番目のパラメーターを忘れています。
user81655

@ edc65はこれに勝ると思いますが、爆発した部分文字列のコードとパングラムテスターのコードをマージし、134バイトの関数になりました。
ニール

私のベストはこれまでに142
edc65

悲しいことに、私はそれを保存しようとは思わず、PCがクラッシュしたので、今は自分が何を持っているのかわかりません。今できることは138バイトです。
ニール

2

PowerShell v2 +、218バイト

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

ええ、サブストリング操作(組み込みはありません)は、実際にはPowerShellの強力なスーツではありません...

入力を受け取りparam($a)、新しい空のハッシュテーブルを設定します$z。これは、パングラムの部分文字列候補のストレージになります。

以下からの私のコードのわずかな変更を使用して分解図サブストリング、私たちは、構築、すべての入力のサブストリング。はい、1文字の句読点のみの部分文字列です。これはであり、ではありません。;-)

これらの部分文字列はすべて括弧でカプセル化され、で別のループにパイプされます|%{...}。一時的に$y現在のサブストリングに設定し、ヘルパーカウンターを設定し、便利な大文字のASCII文字コードで$j別のループを開始します65..90|%{...}。各内部ループは$y、取得してすべて大文字にし、.IndexOfその特定の文字を引き出します。-1見つからない場合はこれが返されるため+1、結果をに乗算する前に返し$jます。これにより、いずれかの文字が見つからない$j場合、ゼロに等しくなります。

これがまさにそのifすべてです。場合は$j、ゼロでないすべての文字が少なくとも部分文字列に一度発見されたことを意味している$y私達は私達の候補プールにそれを追加する必要があるので、。私たちは取ることによって、そう$yして-replace私たちにその部分文字列の文字長を取得し、何もないすべての非文字を、INGの。それをハッシュテーブルのインデックスとして使用します$z保存$yします。これには、同じ文字長の部分文字列を元の文字列の「最も遠い」部分文字列で上書きするという癖がありますが、文字長だけを心配しているため、これはルールで許可されています。

最後に、ソート$zして最小のものを引き出す必要があります。私たちは、使用する必要が.GetEnumeratorでソートするために呼び出しをオブジェクトの内部 $z、そしてsort上でそれらをName選択する、(上からすなわち、長インデックス)[0](すなわち、最短)第1に、そしてその出力.Value(すなわち、サブストリング)。そのような部分文字列が収まらない場合、これはにインデックスを付けよCannot index into a null arrayうとしてエラー()を投げ、$z何も出力しません。これはPowerShellでは偽です。(以下の3番目のテストケースには、[bool]これを示すための明示的なキャストがあります)

テストケース

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バイト

これは大変でしたが、インポートせずに本当に楽しかったです。

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]

はるかに少ないゴルフ:

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

驚き、驚き:本当に遅いです。


2

Oracle SQL 11.2、461バイト

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;

ゴルフをしていない

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

sビューには、文字入力を分割して、各文字の位置を返します。

再帰ビューvは、入力
のすべての部分文字列を返しますsは部分文字列
f は部分文字列の最初の文字の
位置l現在の部分文字列に追加された最後の文字の位置

cビューは、一度、アルファベット、1つの文字を返します。

aビューは、1つの文字列として連結アルファベットを返します。

SELECT s,f,SUM(SIGN(INSTR(LOWER(s),c))
各サブストリングに存在する個別の文字の数を返し、サブストリング内の文字の位置を返します。存在し
INSTRない場合は
SIGN0、位置> 0の場合は1、位置= 0の場合は0を返します

WHERE x=26
アルファベット全体を含む部分文字列をフィルタリングします

TRANSLATE(LOWER(s),' '||a,' ')
部分文字列からすべての文字を削除します

LENGTH(s)-NVL(LENGTH(TRANSLATE(LOWER(s),' '||a,' ')
文字の長さは、部分文字列の長さから文字なしのサブトレースの長さを引いたものです

SELECT MIN(s)KEEP(DENSE_RANK FIRST ORDER BY LENGTH(s)-NVL(LENGTH(TRANSLATE(LOWER(s),' '||a,' ')),0))
文字数が少ない部分文字列のみを保持します。
複数ある場合は、文字列の昇順でソートされた最初のものが保持されます


2

Pythonの3、171、167、163、157、149バイト。

DSMのおかげで4バイト節約されました。
RootTwoのおかげで8バイト節約されました。

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

文字の数に基づいてソートすることは私を殺している。

テストケース:

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()重要な機能に必要だとは思わないでください。
RootTwo

@RootTwoおっと、そうだね。ありがとう。
モーガンスラップ

1

PowerShell(v4)、198 156バイト

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]

テストケース

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!

オリジナルの非ゴルフの説明

これは、あらゆるサイズのスライディングウィンドウを作成するブルートフォースのネストループです。

.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

ウィンドウごとに、文字のみをフィルタリングし(デフォルトでは大文字と小文字を区別しない正規表現一致)、一意のフィルターを介して残りの文字を実行し、パングラムテストとして26の一意の文字があるかどうかを確認します。

パングラムを含むすべてのウィンドウは、(デュプを含む文字数、開始インデックス、句読点を含むウィンドウの長さ)のトリプレットに変換されます。 。

PowerShellは、例外をスローする代わりに、$ nullを便利に返します。

NB。新しい156バイトは同じアプローチですが、パイプラインをより多く使用するように書き直されました。

$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。私はそれを書いてゴルフをしなかったので、ゴルフのないバージョンが機能するかどうかわかりません、それはただの説明のためです。


0

Haskell、123バイト

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

関数を定義しますh。これは、パングラマティックウィンドウがない場合、または最小ウィンドウを持つ1つの要素リストがある場合に空のリストを返します。使用例:

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

使い方:

          [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!
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.