Znajdź wszystkie jednoznaczne prefiksy zestawu ciągów

12

Aby sprostać temu wyzwaniu, musisz zaimplementować Abbrevmoduł Ruby w możliwie najmniejszym kodzie.

Wyzwanie

  • Dane wejściowe będą takie, jak Twój język, jako tablica (tablica, lista, sekwencja itp.) Ciągów. Możesz napisać funkcję lub zaakceptować słowa rozdzielane przecinkami na STDIN.

  • Następnie musisz obliczyć zestaw jednoznacznych prefiksów dla tych ciągów. Oznacza to, że musisz zwrócić skrót (lub mapę, obiekt itp.) Skrótów do ich oryginalnych ciągów.

    • „Przedrostek” jest podciągiem oryginalnego ciągu rozpoczynającego się na początku łańcucha. Na przykład „pref” to przedrostek słowa „prefix”.

    • Jednoznaczne prefiks to taki, który może oznaczać tylko jedno słowo. Na przykład, jeśli dane wejściowe to car,cat, cato nie jest to jednoznaczny przedrostek, ponieważ może oznaczać „samochód” lub „kot”.

    • Wyjątkiem od tej reguły jest to, że słowo jest zawsze przedrostkiem samego siebie. Na przykład, jeśli masz dane wejściowe, takie jak car,carpet, car:carmusi być w danych wyjściowych.

  • Następnie możesz zwrócić skrót / mapę / obiekt / itp. z funkcji (lub wykonaj odpowiednik w swoim języku) lub wydrukuj go do STDOUT key:valueparami w formie f:foo,fo:foo,.... (Pary klucz-wartość można również oddzielić białymi spacjami, jeśli skraca to kod).

Przypadki testowe

Input  code,golf,going
Output c:code,co:code,cod:code,code:code,gol:golf,golf:golf,goi:going,goin:going,going:going

Input  pie
Output p:pie,pi:pie,pie:pie

Input  pie,pier,pierre
Output pie:pie,pier:pier,pierr:pierre,pierre:pierre

Input  a,dog
Output a:a,d:dog,do:dog,dog:dog

Zasady

  • Dane wejściowe nie będą zawierać zduplikowanych elementów.

  • Twój wynik może być w dowolnej kolejności; nie musisz tego sortować.

  • Nie możesz używać wbudowanego Abbrevmodułu / funkcji / czegoś takiego jak Ruby.

  • To jest , więc wygra najkrótszy kod w bajtach!

Klamka
źródło
Czy stdout musi mieć dokładnie ten format? Czy mogę zrobić key:value\nkey:value\nkey:value...?
metro
4
Zamiast redefiniować skrót słowa, możesz po prostu użyć przedrostka o jego standardowym znaczeniu. I myślę, że jednoznacznie przekazuje pożądaną właściwość klawiszy bardziej skutecznie niż niepowtarzalną , dla której moją pierwszą intuicją było to, że chciałeś tylko jednego prefiksu na słowo wejściowe.
Peter Taylor
@PeterTaylor Dobry pomysł; edytowane.
Klamka
1
Czy można wydrukować ten sam klucz wiele razy (o tej samej wartości)?
xnor

Odpowiedzi:

1

APL (46)

(Tak, zestaw znaków APL mieści się w bajcie, z miejscem na zapas).

{↑{∆/⍨2=⍴∆←(⊂⍵),∆/⍨⊃¨⍵∘⍷¨∆}¨∪⊃,/{↑∘⍵¨⍳⍴⍵}¨∆←⍵}

Jest to funkcja, która pobiera listę ciągów znaków i zwraca macierz 2 na N, w której każdy wiersz zawiera jednoznaczny przedrostek i słowo, do którego należy:

{↑{∆/⍨2=⍴∆←(⊂⍵),∆/⍨⊃¨⍵∘⍷¨∆}¨∪⊃,/{↑∘⍵¨⍳⍴⍵}¨∆←⍵}'code' 'golf' 'going'
 c      code  
 co     code  
 cod    code  
 code   code   
 gol    golf  
 golf   golf  
 goi    going 
 goin   going 
 going  going 

Wyjaśnienie:

  • ∆←⍵: zapisz odpowiedni argument w .
  • {↑∘⍵¨⍳⍴⍵}¨∆: dla każdego elementu pobierz możliwe prefiksy tego elementu:
    • ⍳⍴⍵: uzyskaj listę od 1do
    • ↑∘⍵¨: dla każdej z tych liczb uzyskaj tyle elementów z .
  • ∪⊃,/: połącz listy razem i weź unikalne wartości.
  • {... : dla każdego unikalnego prefiksu:
    • ∆/⍨⊃¨⍵∘⍷¨∆: wybierz słowa zaczynające się od tego prefiksu
    • (⊂⍵),: dołącz także prefiks i konkatenuj
    • ∆/⍨2=⍴∆←: zwraca listę tylko wtedy, gdy są dwa elementy (przedrostek i jedno pasujące słowo)
  • : zamień listę krotek w macierz
marinus
źródło
Link jest teraz zerwany ...
user202729 27.04.18
3

Python 2.7 - 146 141 bajtów

l=raw_input().split(',')
for w in l:
 for a in range(len(w)):
    e=w[:a+1]
    if e==w or len(filter(lambda b:b.startswith(e),l))==1:print e+':'+w

Zauważ, że wcięcie w liniach 4 i 5 nie jest 4 spacjami, to efekt uboczny interpretera znakowania SE. To dosłowny znak tabulacji, więc tylko jeden bajt.

Nie jest to technicznie zgodne ze specyfikacją, ale zmienię to, jeśli Klamka wyjaśni. Używa znaku nowej linii zamiast przecinków, aby oddzielić dane wyjściowe. Na przykład:

$ python2 abbreviations.py <<< code,golf,golfing
c:code
co:code
cod:code
code:code
golf:golf
golfi:golfing
golfin:golfing
golfing:golfing

Nowość: udało mi się pozbyć 5 znaków, przypisując sprawdzany ciąg do zmiennej e. Oznacza to, że mam tylko wpisać ezamiast w[:a]trzy razy. Oznacza to również, że zapisuję postacie, robiąc e=w[:a+1]i zmieniając ...range(1,len(w)+1)na range(len(w)).


Wyjaśnienie:

l=raw_input().split(',') # Gets a line of input from stdin and splits it at every ',' to make a list
for w in l: # For each word in that list...

 for a in range(1,len(w)+1): # For each number a from 1 to the length of that word...

    if (w[:a]==w # w[:a] gets the string w up to the ath index. For example, 'aeiou'[:3] == 'aei'.
                 # We're testing every possible w[:a] to see if it's a unique abbreviation.
                 # However, a word is always its own abbreviation, so we hardcode that in by testing
                 # if w[:a] is the same as w.

or len(filter( # filter takes a function and an iterable as an argument, and returns a list of every
               # element of that iterable where that_function(that_element) returns a True-y value

lambda b:b.startswith(w[:a]),l) # We define an anonymous function that returns True for any string
                                # that begins with our current w[:a]. We filter for words that return
                                # True.

)==1): # If exactly one word returns True for this, it's a unique abbreviation!

     print w[:a]+':'+w # Print the abbreviation, a colon, and the full word.
podziemny monorail
źródło
Możesz użyć sum(b.startswith(e) for b in l)zamiastlen(filter(lambda b:b.startswith(e),l))
Niklas B.,
Możesz także skrócić b.startswith(e)do b.find(e)==0lub b[:a+1]==ei sprawdzić <2liczbę zamiast ==1.
xnor
e=""\n for a in w:\n\te+=afor a in range(len(w)):\n\te=w[:a+1]
Rób
Stworzyłem tutaj wersję bez poprawek dla każdego, kto jej potrzebuje gist.github.com/stuaxo/c371b2d410191a575b763b74719856c8
Stuart Axon
3

J - 47 znaków

(,.~~.@,~[:(#~1-1({.\e."_1]\.){."1)@;(<\,.<)&.>)

J traktuje łańcuchy jako wektory znaków, co oznacza, że ​​kiedy próbuje utworzyć listę łańcuchów, w rzeczywistości tworzy tablicę znaków, więc końce są wypełniane spacjami. Rozwiązanie J nazywa się pudełkiem , więc ta funkcja przyjmuje jako argument pudełkowaną listę ciągów, aby zachować długość.

   'code';'golf';'going'
+----+----+-----+
|code|golf|going|
+----+----+-----+

Ponadto J nie ma typu skrótu, więc najbliższa mu jest dwukolumnowa tabela elementów, na przykład ciągi w ramkach. Jeśli jest to niedopuszczalne i muszę domyślnie użyć formularza klucz-wartość, mogę sformatować dane wyjściowe do tego formularza łącznie w 67 znakach :

;@|.@,@((<&>',:'),."1,.~~.@,[:(#~1-1({.\e."_1]\.){:"1)@;(<,.<\)&.>)

Wyjaśnienie przez wybuch:

(,.~~.@,[:(#~1-1({.\e."_1]\.){."1)@;(<\,.<)&.>) NB. unambiguous prefixes
                                    (     )&.>  NB. for each string:
                                     <\         NB.   take all prefixes
                                       ,.<      NB.   pair each with string
        [:                         ;            NB. gather up "partial" hashes
          (#~1-                  )@             NB. remove those rows where:
               1({.\        ){."1               NB.   each key
                    e."_1                       NB.   is an element of
               1(        ]\.){."1               NB.   the rest of the keys
 ,.~                                            NB. hash each word to itself
       ,                                        NB. add these rows to hash
    ~.@                                         NB. remove duplicate rows

Przykłady:

   (,.~~.@,[:(#~1-1({.\e."_1]\.){."1)@;(<\,.<)&.>) 'pie';'pier';'pierre'
+------+------+
|pie   |pie   |
+------+------+
|pier  |pier  |
+------+------+
|pierre|pierre|
+------+------+
|pierr |pierre|
+------+------+
   NB. 1-char words have to be made into lists with ,
   (,.~~.@,[:(#~1-1({.\e."_1]\.){."1)@;(<\,.<)&.>) (,'a');'dog'
+---+---+
|a  |a  |
+---+---+
|dog|dog|
+---+---+
|d  |dog|
+---+---+
|do |dog|
+---+---+
   NB. "key:value," format, reversed order to save chars
   ;@|.@,@((<&>',:'),."1,.~~.@,[:(#~1-1({.\e."_1]\.){:"1)@;(<,.<\)&.>) 'code';'golf';'going'
goin:going,goi:going,gol:golf,cod:code,co:code,c:code,going:going,golf:golf,code:code,
algorytmshark
źródło
2

Haskell 96 87

import Data.List
i=inits
f a=a>>= \x->[(y,x)|y<-i x,y/="",y`notElem`(a>>=i)\\i x||y==x]

Wersja bez golfa:

 import Data.List
 f a = concatMap (\x ->
     [(y, x) |
      y <- inits x,
      y /= "",
      y `notElem` concatMap inits a \\ inits x || y == x]
     ) a

Przykład:

> f ["pi","pier","pierre"]
[("pi","pi"),("pier","pier"),("pierr","pierre"),("pierre","pierre")]

Użyłem initsfunkcji, która znajduje wszystkie prefiksy listy / łańcucha. Czy to się liczy jako oszustwo?

lortabak
źródło
1
Możesz zastąpić concatMapprzez (=<<), który jest w Preludium. Oszczędza ci 10 znaków.
Rhymoid
@ Rhymoid Dziękujemy. Usunąłem, concatMapale nie mogę zapisać więcej niż 9 znaków.
lortabac
Och, czekaj, masz rację; Haskell uważa >>=\ za pojedynczy leksem. Przepraszam za to ...
Rhymoid
2

Python 3 (97)

c=','
S=c+input()
for w in S.split(c):
 e=w
 while e:e<w<w*S.count(c+e)or print(e+':'+w);e=e[:-1]

Iterujemy nad prefiksami każdego słowa na wejściu, wypisując odpowiednią parę prefiksów / słów, jeśli pojawia się dokładnie raz lub dotyczy całego słowa. Korzystamy z zachowania zwarciowego or(i printjest funkcją), aby drukować tylko wtedy, gdy spełniony jest jeden z tych warunków.

whilePętla wielokrotnie odcina ostatniego znaku, aby utworzyć krótsze prefiksy, kończące gdy szczątki pustych ciągów. To jedyny raz, kiedy indeksujemy lub kroimy w cokolwiek.

Liczymy wystąpienia przedrostka ena wejściu, wyszukując Spodciągi w oryginalnym ciągu wejściowym oddzielonym przecinkami ','+e. Przed wejściem poprzedzamy przecinek. To dodanie powoduje dodatkowy pusty element łańcucha, gdy my split, ale nie ma to żadnego efektu, ponieważ nie ma niepustych podciągów.

Aby sprawdzić przypadek, gdy podciąg ejest całym słowem w, porównujemy je za pomocą operatora porównania ciągów. Porównuje to leksykograficznie, więc krótsze prefiksy są mniejsze. Podwójna porównanie nie powiedzie się, jeśli albo e==walbo S.count(c+e)<2.

Gdyby wydruki w formularzu e,wbyły dozwolone, zapisałbym znak, pisząc e+c+wzamiast tego.

Podziękowania dla podziemnego kolejki linowej, od którego odpowiedzi oparłem moją ogólną strukturę kodu.

xnor
źródło
(e<w)*S.count(c+e)>1można zagrać w golfa, e<w<w*S.count(c+e)aby zapisać 2 postacie.
isaacg
@isaacg Thanks! Dodałem twoją optymalizację.
xnor
1

Ruby, 114

def f(l);h={};l.each{|w|w.size.times{|i|k=w[0..i];h[k]=h[k]&&0||w}};h.delete_if{|k,v|v==0};l.each{|w|h[w]=w};h end

Nie golfowany:

def f(list)
  hash = {}
  list.each do |word|
    word.size.times do |i|
      key = word[0..i]
      h[key] = (hash[key] && 0) || word
    end
  end
  hash.delete_if{|key, value| v==0}
  list.each{|word| hash[word] = word}
  hash 
end
dtldarek
źródło
1

k4 (70)

niezbyt golfa; jestem pewien, że może być krótszy

całkiem podobny do J impl. powyżej, myślę - w zasadzie po prostu zbiera wszystkie (właściwe) prefiksy, ponownie usuwa słowa z prefiksów (aby obsłużyć "car"/ "carpet"case), grupuje je w klasy równoważności, wybiera klasy z tylko jednym elementem, redukuje je z list do ciągi i dodaje na mapie ciągi do siebie.

f:{(x!x),*:'{(&1=#:'x)#x}{x@=y@:&~y in x}.,/'+{1_'(c#,x;(!c:#x)#\:x)}'x}

niektóre przypadki testowe

zwróć uwagę, że w k/ q, ciąg znaków jest listą znaków, więc ciąg zawierający tylko jeden znak musi zostać oznaczony jako taki przy użyciu ,funkcji unary ; & mmwrt listę ciągów zawierających tylko jeden ciąg

te wykorzystują qdydaktycznego showfunkcja, która ma wbudowane formatowania dla niektórych struktur danych, aby wynik był bardziej czytelny:

  .q.show f("code";"golf";"going")
"code" | "code"
"golf" | "golf"
"going"| "going"
,"c"   | "code"
"co"   | "code"
"cod"  | "code"
"gol"  | "golf"
"goi"  | "going"
"goin" | "going"
  .q.show f@,"pie"
"pie"| "pie"
,"p" | "pie"
"pi" | "pie"
  .q.show f("pie";"pier";"pierre")
"pie"   | "pie"
"pier"  | "pier"
"pierre"| "pierre"
"pierr" | "pierre"
  .q.show f(,"a";"dog")
,"a" | ,"a"
"dog"| "dog"
,"d" | "dog"
"do" | "dog"
  .q.show f("car";"carpet")
"car"   | "car"
"carpet"| "carpet"
"carp"  | "carpet"
"carpe" | "carpet"
Aaron Davies
źródło
1

JavaScript - 212

w=prompt(o=[]).split(",");w.map(function(k,l){for(i=0;++i<k.length;){p=k.slice(0,i);if(w.filter(function(r,t){return t!=l}).every(function(r){return r.indexOf(p)}))o.push(p+":"+k)}o.push(k+":"+k)});console.log(o)

Początkowe golfa.

Wejście:

code,golf,going

Wynik:

["c:code", "co:code", "cod:code", "code:code", "gol:golf", "golf:golf", "goi:going", "goin:going", "going:going"]

Matt
źródło
1

Perl, 93 77

Z nowymi liniami i wcięciem dla czytelności:

sub f{
    (map{
        $h{$x}=[($x=$`.$&,$_)x!$h{$x}]while/./g;
        $_,$_
    }@_),map@$_,values%h
}

Trochę za późno i za długo, ale cieszę się, że w końcu spadło poniżej 100. Funkcja zwraca listę, którą można przypisać do zmiennej skrótu:

%h = f(qw/code golf going pie pier pierre/);
print "$_ $h{$_}\n" for sort keys %h;

i

perl prefix.pl
c code
co code
cod code
code code
goi going
goin going
going going
gol golf
golf golf
pie pie
pier pier
pierr pierre
pierre pierre

W rzeczywistości zwrócona lista nie jest jeszcze filtrowana - budowa skrótu jest zakończona w momencie jej przypisania, tj. Funkcji zewnętrznej. JEŻELI nie jest wystarczająco czysty / sprawiedliwy, dodaj 3, aby policzyć i umieść zawartość funkcji w nawiasach klamrowych, przygotowując +- wtedy funkcja zwraca „prawdziwe” odwołanie do skrótu.

użytkownik 2846289
źródło
1

P: 44 bajty

{x!p@'(?0,&:)'p in\:&1=#:'=,/p:`$(-1_)\'$x}

UWAGI

  • Język Q ma wewnętrzny rdzeń nazwany wewnętrznie K4 (używany w tej odpowiedzi i innej poprzedniej odpowiedzi na to pytanie)

  • Aby przetestować kod, pobierz interpreter (kx.com, bezpłatny do użytku niekomercyjnego, obsługa systemów Windows, Linux, Mac)

Tłumacz ustny dopuszcza dwie składnie:

  • pełne (bardziej czytelne nazwy, odrębne nazwy dla moands i diadów, więcej bibliotek, ...). Załaduj plik źródłowy z rozszerzeniem q lub interaktywnym tłumaczem

  • kompaktowy (funkcjonalny rdzeń wewnętrzny, operatory jednoliterowe, ta sama litera dla obu zastosowań monad / diad, ...). Załaduj plik źródłowy z rozszerzeniem k lub interaktywny interpreter w trybie k (napisz \ po znaku zachęty). W tym trybie należy przetestować kod

Kod definiuje lambda (funkcja anonimowa). Aby nadać nazwę funkcji, potrzebujemy prefiksu name: (np. F: {..}), więc wymaga 46 bajtów

TEST

(przyjmując nazwaną funkcję: w przeciwnym razie zastąp kod f kodem)

f `code`golf`going

`code`golf`going!(`code`cod`co`c;`golf`gol;`going`goin`goi)

zwraca słownik (klucze składniowe! wartości). Klucze są listą symboli (symbol `symb`symb ..) i są wartościami listy symboli. Jeśli wykonamy sentente w interaktywnym tłumaczu, mamy wygodniejszą prezentację (każdy klucz i skojarzenie wartości w innym wierszu)

code | `code`cod`co`c
golf | `golf`gol
going| `going`goin`goi

WYJAŚNIENIE

x jest domyślnym argumentem dla lambda

$x konwertuj listę symboli na listę ciągów

(-1_)\ iteruje każdy element listy symboli

(odczytuje jak dla każdego ciągu oblicza prefiksy (przy iteracji po jedzeniu spada ostatni znak ciągu (-1_), aż do pustego ciągu)

$ ponownie przekształca się w listę symboli (lista wszystkich prefiksów)

p: i przypisuje do p

,/ zrównaj wszystko (łączy i tworzy jednopoziomową strukturę)

= klasyfikuj -> dla każdego unikalnego prefiksu, przypisuje odpowiednie słowa

#:' oblicza długość (liczbę słów powiązanych z każdym prefiksem)

1= true, jeśli długość = 1 (jednoznacznie), false w przeciwnym razie

& gdzie -> indeks elementów prawdziwych

p in\: określa dla wszystkich prefiksów, jeśli są one w jednoznacznych prefiksach

(..)' stosuje (..) do każdej wartości po prawej stronie (jednoznaczny prefiks)

?0,&: -> wyraźne 0 konkatenowane gdzie (aby poradzić sobie ze słowami jako przedrostkiem)

p@ przekształcić indeksy w symbole

x!.. zbuduj słownik z x (słowami) jako kluczami i .. jako wartościami

Czytaj jako:

  • Konstruuj i zwraca słownik ze słowami w postaci kluczy i wartości ..

  • ... wartości indeksów w różnych pozycjach 0 (wszystkie słowa) i gdzie jednoznaczny przedrostek

  • ... jednoznaczne obliczone jako przedrostki, które pojawiają się tylko przy jednym słowie (lista słów powiązana z każdym symbolem ma długość 1)

  • ... wyświetla listę wynikającą z klasyfikacji wszystkich niepowtarzalnych symboli odpowiednimi słowami

  • ... prefiksy obliczane przez powtarzanie upuszczania ostatniego znaku każdego słowa

J. Sendra
źródło
1

PHP 7.0, 67 bajtów (dodaje wyzwanie)

for(;a&$c=$s[++$k]??($s=$argv[++$i])[$k=+$t=!1];)echo$t.=$c,":$s,";

pobiera dane wejściowe z argumentów wiersza poleceń; drukuje przecinek końcowy; biegać z -nr.

do nowszej PHP , dodać jeden bajt: Wymień &asię ""<.

dla starszych PHP użyj tych 70 bajtów:

PHP, 70 bajtów

for(;a&$s=$argv[++$i];)for($k=+$t="";a&$c=$s[$k++];)echo$t.=$c,":$s,";
Tytus
źródło
1

Brachylog , 23 bajty

∋Xa₀Y;?↔⟨∋a₀⟩ᶜ1∧Y;X|∋gj

Wypróbuj online!

Pobiera dane wejściowe jako listę za pośrednictwem zmiennej wejściowej i generuje listę [key, value]par za pomocą zmiennej wyjściowej. Każdy ciąg wejściowy, który nie jest przedrostkiem innego ciągu wejściowego, zostanie wygenerowany dwukrotnie jako przedrostek samego siebie, chociaż nagłówek na TIO ukrywa to, używając do uzyskania pełnej listy zamiast .

 X                         X
∋                          is an element of
                           the input variable
    Y                      and Y
  a₀                       is a prefix of
 X                         X.
             ᶜ             The number of ways in which
        ⟨∋  ⟩              an element can be selected from
     ;?↔⟨   ⟩              the input variable
    Y; ↔⟨ a₀⟩              such that it has Y as a prefix
              1            is equal to 1.
               ∧Y          Y is not necessarily 1,
                   |       and the output variable
                Y;X        is the list [Y, X].
                   |       If every choice from the first rule has been taken already,
                           the output variable is
                    ∋      an element of
                   |       the input variable
                     gj    paired with itself.
Niepowiązany ciąg
źródło
Jeśli duplikaty danych wyjściowych nie są tolerowane, dodaj trzy bajty, aby owinąć całość {}ᵘ, chyba że istnieje krótszy sposób, aby albo wykluczyć coś z przedrostka samego siebie, albo wygenerować każdą niezbędną parę wyjściową bez dodatkowej reguły ∋gj.
Niepowiązany ciąg
1

APL (Dyalog Classic) , 38 bajtów

dzięki Erik the Outgolfer za przypomnienie, żebym użył jednobajtowego kodowania znaków

{⊃,/⍵{b,¨⍨(⊂¨⍵~⊃,/a~⊂⍵)∪b←⊂⊂⍺}¨a←,⍵}

Wypróbuj online!

ngn
źródło
1
Um ... Nie widzę tutaj żadnych złych postaci, których nie można użyć z SBCS
Adáma
bez zauważenia, ponownie wybrałem niewłaściwą wersję interpretera ... dziękuję za zmniejszenie o połowę mojej liczby bajtów :)
ngn
0

Python (127)

Więc nie mogłem skomentować @undergroundmonorail, ale pomyślałem, że przyjęcie słownika byłoby lepsze? Jestem pewien, że dzięki zrozumieniu listy / słownika można by go ogromnie zmniejszyć, ale nie może sprawić, żeby działał z wyskakiwaniem ze słownika.

i=raw_input().split(",")
d = {}
for x in i:
    for c in range(1,len(x)+1):
        if x[:c] in d:
            del d[x[:c]]
        else:
            d[x[:c]]=x
print d

Wydruk wygeneruje słownik, nieuporządkowany.

EDYCJA: Ahh spóźniłem się na samochód: samochód / samochód: dywan kryteria. Może kontrola długości?

jaybee3
źródło
Być może coś mi brakuje, ale wydaje się, że naprzemiennie dodaje i usuwa wpis prefiksu za każdym razem, gdy się napotyka, więc czy nie pojawiłby się dwuznaczny prefiks, jeśli występuje w 3 słowach?
xnor
0

Groovy - 212 znaków

Gra w golfa:

c="collectEntries";f="findAll";def g={def h=[:].withDefault{[]};it.each{def w->w.size().times{ h[w[0..it]] << w}};(h."$f"{k,v->v.size()==1}."$c"{k,v->[k,v[0]]}).plus(h."$f"{k,v->v.contains(k)}."$c"{k,v->[k,k]})}

przykładowe dane wyjściowe:

println g(["code","golf","going"])

[c:code, co:code, cod:code, code:code, gol:golf, golf:golf, goi:going, goin:going, going:going]

Nie golfowany:

def g = { def list ->
    def hash = [:].withDefault{[]}
    list.each {
        def word -> word.size().times{ hash[word[0..it]] << word }
    }

    def map = hash.findAll{ k,v -> v.size() == 1 }.collectEntries{ k,v -> [k,v[0]] }
    map.plus(hash.findAll{ k,v -> v.contains(k) }.collectEntries{ k,v -> [k,k] }
    map
}
Michael Easter
źródło
0

Zsh , 95 bajtów

local -A m
for w;{m[$w]=$w;x=
for c (${(s::)w})x+=$c&&[ ${(M)@:#$x*} = $w ]&&m[$x]=$w
}
local m

Wypróbuj online!

Jedynym sposobem na „zwrócenie” tablicy asocjacyjnej w Bash / Zsh jest zadeklarowanie jej bez localsłowa kluczowego, a następnie uzyskanie dostępu do niej w zakresie nadrzędnym. Pozwoliłoby to zaoszczędzić jeden bajt. Jednak we / wy za pośrednictwem zmiennych jest zasadniczo niezadowolony, więc zamiast tego wypisujemy definicję tablicy.

local -A m                          # declare m as associative
                                    # "local" is shorter than "typeset"/"declare"
for w;{                             # for each word
    m[$w]=$w                        # the word is a prefix of itself
    x=                              # ensure x is empty
    for c (${(s::)w})               # for each character in the word
        x+=$c &&                    # append to x (building a prefix
          [ ${(M)@:#$x*} = $w ] &&  # if the only match is the word itself:
          m[$x]=$w                  # ... then x is a prefix of w
}
local m                             # print m
Funkcja Gamma
źródło
0

Rubinowy , 84 bajtów

Właśnie zauważyłem, że istnieje już rozwiązanie Ruby, no cóż. Zasadniczo poprawia to stare rozwiązanie, wybierając mądrzejsze prefiksy (eliminując potrzebę dodawania każdego słowa jako „prefiksu” na końcu) i licząc prefiksy, aby sprawdzić unikalność przed dodaniem ich do skrótu, zamiast nadpisywania wartości za pomocą manekin, jeśli istnieje duplikat, a następnie kasowanie wpisu.

->w{h={};w.map{|e|(1..e.size).map{|i|w.count{|d|d[0,i]==e[0,i]}<2?h[e[0,i]]=e:0}};h}

Wypróbuj online!

Wartość tuszu
źródło