最小文字列セグメントサイズを計算する


8

バイナリのスペースを節約するための一般的な最適化は、1つのリテラルが別のリテラルである文字列リテラルをマージすることです。たとえば、文字列リテラルを含むバイナリ

a: foobar
b: bar
c: barbaz
d: foobarbaz
e: baz

次の文字列リテラルプール(-terminatorを#表す\0)が含まれる場合があります。

foobar#foobarbaz#

記号でabc、およびd文字列プールの先頭からの相対次の値を持ちます:

a:  0
b:  3
c: 10
d:  7
e: 13

このタスクでは、特定の入力文字列セットの文字列プールの最小サイズを計算する必要があります。

入力

入力は、それぞれが32〜127の範囲の最大80のASCII文字(改行を含まない)と、その後に単一の改行文字で構成される、最大999の一連の文字列です。

出力

各入力文字列(終端の改行を含む)がその文字列の部分文字列になるような最短の文字列を見つけます。出力は、その最も短い文字列の長さになります。文字列は出力せず、長さのみを出力します。

得点

この課題はコードゴルフであり、標準の抜け穴が適用されます。オクテットで最小長のソリューションが優先されます。

  1. 入力:

    foobar
    bar
    barbaz
    foobarbaz
    baz
    

    #改行を表す最短の文字列:

    foobar#foobarbaz#
    

    長さ:17

  2. 入力:

    foobar
    foobaz
    foobarbaz
    barbaz
    

    #改行を表す最短の文字列:

    foobar#foobaz#foobarbaz#
    

    長さ:24


1
80文字のテストケースが良いでしょう。また、「オクテット」と「バイト」の違いはありますか?それ以外の場合は、obscurer用語を使用する利点が何であるかわかりません。
Martin Ender 2015年

1
@MartinBüttner一部のマシンでは、1バイトのビット数が8ビットより多い場合と少ない場合があります(KnuthのMIXを参照)。オクテットは、8ビットの数量を指す標準的な単語です。バイトは、作業している特定のマシンの最小アドレス単位を指します。80文字の制限がそこにあるため、固定配列で作業できるため、「これは非常に長い入力で壊れるので無効です」とは言えません。
FUZxxl 2015年

1
すべての入力文字列はペアで区別されますか?
Alexey Burdin

@AlexeyBurdin No.
FUZxxl 2015年

回答:


4

Pyth、20 18バイト

hljb-{.zsmteM./d.z

デモンストレーション。

{ 重複が許可されていない場合は削除できます。

説明:

hljb-{.zsmteM./d.z
                .z     The input, as a list of strings.
         m             Map each strings to
             ./d       all possible partitions of the string into separate strings.
           eM          take the last element of each, giving all suffixes.
          t            Remove the first suffix, giving all suffixes other than
                       the string itself.
        s              Sum, combining the list of lists into a single list.
    -{.z               From the set of input strings, remove all suffixes.
                       This is the list of strings in the minimal segment.
  jb                   Join the strings together on newlines.
 l                     Take the length of the resulting string.
h                      Add one and print.

3

CJam、22バイト

qN%_&Nf+:G{Gs\/,3<},s,

オンラインでお試しください。

使い方

qN%   e# Split the input from STDIN at linefeeds, discarding the last, empty chunk.
_&    e# Intersect the array with itself to remove duplicates.
Nf+   e# Append a linefeed to each chunk.
:G    e# Save the result in G.
{     e# Filter; for each chunk in G:
  Gs  e#   Flatten the array of strings G.
  \/  e#   Split at occurrences of G.
  ,3< e#   Compare the resulting number of chunks with 3.
},    e#   Keep the chunk iff the comparision pushed 1 (true).
s,    e# Flatten the resulting array of strings and push the result's length.

1

Python 2、132

ちょうどレースを始めるために:

def f(s):
    l=set(s.split('\n'))
    for x in l:
        for y in l:
            if x!=y and x.endswith(y):l.remove(y)
    return sum(len(x)+1 for x in l)

できます:

>>> f(r'''foobar
foobaz
foobarbaz
barbaz''')
24
>>> f(r'''foobar
bar
barbaz
foobarbaz
baz
''')
17

1

Haskell、101 85バイト

import Data.List
length.unlines.(\l->[x|x<-nub l,x`notElem`((tails.tail)=<<l)]).lines

名前のない関数。使用例:

*Main>  length.unlines.(\l->[x|x<-nub l,x`notElem`((tails.tail)=<<l)]).lines $ "foobar\nbar\nfoobaz"
14

仕組み:入力文字列を改行で分割します。単語リストから重複を削除しますl。単語を保つxことがの言葉のすべての尾のリストにない場合は、残りのリストからlx途中(および最後に)の改行でそれらを結合して1つの文字列にし、その長さを数えます。

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