Temukan semua awalan yang tidak ambigu dari serangkaian string


12

Untuk tantangan ini, Anda harus mengimplementasikan Abbrevmodul Ruby dalam kode sesedikit mungkin.

Tantangan

  • Input akan berupa apa pun bahasa Anda sebagai array (array, daftar, urutan, dll.) Dari string. Anda dapat menulis suatu fungsi, atau Anda dapat menerima kata-kata yang dipisahkan koma di STDIN.

  • Anda kemudian harus menghitung set awalan yang tidak ambigu untuk string tersebut. Ini berarti Anda harus mengembalikan hash (atau peta, objek, dll.) Singkatan ke string aslinya.

    • "Awalan" adalah substring dari string asli yang dimulai pada awal string. Misalnya, "pref" adalah awalan dari kata "prefix."

    • Sebuah ambigu prefix adalah salah satu yang hanya bisa berarti satu kata. Misalnya, jika input Anda adalah car,cat, maka cabukan awalan yang tidak ambigu karena bisa berarti "mobil" atau "kucing."

    • Pengecualian untuk aturan ini adalah bahwa kata selalu merupakan awalan dari dirinya sendiri. Misalnya, jika Anda memiliki input seperti car,carpet, car:carharus di output Anda.

  • Anda kemudian dapat mengembalikan hash / map / object / etc. dari fungsi Anda (atau lakukan yang setara dalam bahasa Anda), atau cetak untuk STDOUT key:valueberpasangan dalam bentuk f:foo,fo:foo,.... (Pasangan nilai kunci juga dapat dipisahkan oleh spasi putih jika membuat kode Anda lebih pendek.)

Uji kasus

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

Aturan

  • Input tidak akan mengandung elemen duplikat.

  • Output Anda mungkin dalam urutan apa pun; Anda tidak perlu mengatasinya.

  • Anda tidak boleh menggunakan Abbrevmodul / fungsi / hal bawaan seperti Ruby.

  • Ini adalah , jadi kode terpendek dalam byte akan menang!


Apakah stdout harus persis format itu? Atau bisa saya lakukan key:value\nkey:value\nkey:value...?
undergroundmonorail

4
Daripada mendefinisikan kembali singkatan kata, Anda bisa menggunakan awalan dengan makna standarnya. Dan saya pikir jelas menyampaikan properti yang diinginkan dari kunci lebih efektif daripada unik , yang intuisi pertama saya adalah bahwa Anda hanya menginginkan satu awalan per kata input.
Peter Taylor

@PeterTaylor Ide bagus; diedit.
Gagang Pintu

1
Bisakah seseorang mencetak kunci yang sama beberapa kali (dengan nilai yang sama)?
xnor

Jawaban:


1

APL (46)

(Ya, rangkaian aplikasi APL cocok dalam satu byte, dengan ruang yang tersisa.)

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

Ini adalah fungsi yang mengambil daftar string, dan mengembalikan matriks 2-oleh-N, di mana setiap baris berisi awalan yang tidak ambigu dan kata itu milik:

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

Penjelasan:

  • ∆←⍵: simpan argumen yang tepat di .
  • {↑∘⍵¨⍳⍴⍵}¨∆: untuk setiap elemen , dapatkan awalan yang mungkin dari elemen itu:
    • ⍳⍴⍵: dapatkan daftar dari 1hingga panjang
    • ↑∘⍵¨: untuk masing-masing angka itu, dapatkan banyak elemen dari .
  • ∪⊃,/: menyatukan daftar dan mengambil nilai-nilai unik.
  • {... : untuk setiap awalan unik:
    • ∆/⍨⊃¨⍵∘⍷¨∆: pilih kata-kata yang dimulai dengan awalan itu
    • (⊂⍵),: juga melampirkan awalan, dan menyatukan
    • ∆/⍨2=⍴∆←: hanya mengembalikan daftar jika ada dua elemen (awalan dan satu kata yang cocok)
  • : ubah daftar tupel menjadi matriks

Tautan ini rusak sekarang ...
user202729

3

Python 2.7 - 146 141 byte

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

Perhatikan bahwa lekukan pada baris 4 dan 5 bukan 4 spasi, itu adalah efek samping dari penerjemah markdown SE. Itu karakter tab literal, jadi hanya satu byte.

Secara teknis ini tidak sesuai dengan spesifikasi, tetapi saya akan mengubahnya jika Doorknob mengklarifikasi. Ini menggunakan baris baru, bukan koma untuk memisahkan output. Sebagai contoh:

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

Baru: Saya dapat menghilangkan 5 karakter dengan menetapkan string yang saya periksa ke variabel e. Ini berarti bahwa saya hanya perlu mengetik, ebukan w[:a]tiga kali. Ini juga berarti saya menyimpan karakter dengan melakukan e=w[:a+1]dan mengubah ...range(1,len(w)+1)ke range(len(w)).


Penjelasan:

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.

Anda bisa menggunakan sum(b.startswith(e) for b in l)sebagai gantilen(filter(lambda b:b.startswith(e),l))
Niklas B.

Anda juga dapat menyingkat b.startswith(e)menjadi b.find(e)==0atau b[:a+1]==e, dan memeriksa <2jumlah alih-alih ==1.
xnor

Juga lakukan e=""\n for a in w:\n\te+=adaripada for a in range(len(w)):\n\te=w[:a+1]menghemat 10 karakter
WorldSEnder

Saya telah membuat versi ungolphed di sini untuk siapa saja yang membutuhkannya gist.github.com/stuaxo/c371b2d410191a575b763b74719856c8
Stuart Axon

3

J - 47 char

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

J melihat string sebagai hanya vektor karakter, yang berarti bahwa ketika mencoba membuat daftar string, ia akhirnya membuat tabel karakter, sehingga ujungnya diisi dengan spasi. Solusi J untuk ini disebut kotak , jadi fungsi ini mengambil sebagai argumen daftar kotak string, sehingga dapat mempertahankan panjang.

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

Juga, J tidak memiliki tipe hash, jadi yang paling dekat dengan itu adalah tabel dua kolom item, misalnya string kotak, misalnya. Jika itu tidak dapat diterima dan saya harus default ke bentuk nilai kunci, saya dapat memformat ulang output ke formulir ini dalam total 67 karakter :

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

Penjelasan demi ledakan:

(,.~~.@,[:(#~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

Contoh:

   (,.~~.@,[:(#~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,

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]

Versi tidak disatukan:

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

Contoh:

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

Saya menggunakan initsfungsi, yang menemukan semua awalan daftar / string. Apakah ini dianggap sebagai kecurangan?


1
Anda dapat mengganti concatMapdengan (=<<), yang ada di Prelude. Menghemat 10 karakter.
Rhymoid

@Rhyoid Terima kasih. Saya dihapus concatMaptetapi saya tidak dapat menyimpan lebih dari 9 karakter.
lortabac

Oh, tunggu, kamu benar; Haskell menganggapnya >>=\ sebagai leksem tunggal. Maaf tentang itu ...
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]

Kami mengulangi awalan setiap kata dalam input, mencetak awalan yang sesuai / pasangan kata jika salah satu muncul tepat sekali atau untuk seluruh kata. Kami memanfaatkan perilaku hubungan arus pendek or(dan printmenjadi fungsi) untuk mencetak hanya jika salah satu dari kondisi ini terpenuhi.

The whileLoop berulang kali memotong karakter terakhir untuk membuat prefiks lebih pendek dan lebih pendek, mengakhiri ketika sisa-sisa string kosong. Ini adalah satu-satunya saat kami mengindeks atau mengiris apa pun.

Kami menghitung kemunculan awalan edalam input dengan mencari string input yang dipisahkan koma asli Suntuk substring ','+e. Kami menambahkan koma ke string input terlebih dahulu. Penambahan ini menyebabkan elemen string ekstra kosong ketika kita split, tetapi ini tidak berpengaruh karena tidak memiliki substring kosong.

Untuk memeriksa kasus ketika substring eadalah seluruh kata w, kami membandingkannya menggunakan operator perbandingan string. Ini membandingkan secara leksikografis, sehingga awalan yang lebih pendek lebih kecil. Perbandingan ganda gagal jika salah satu e==watau S.count(c+e)<2.

Jika hasil cetak dalam bentuk e,wdiizinkan, saya akan menyimpan karakter dengan menulis e+c+wsebagai gantinya.

Kredit untuk undergroundmonorail dari yang jawabannya saya berdasarkan struktur kode saya secara keseluruhan.


(e<w)*S.count(c+e)>1dapat di-golf e<w<w*S.count(c+e)untuk menghemat 2 karakter.
isaacg

@isaacg Terima kasih! Saya telah menambahkan optimasi Anda.
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

Tidak Disatukan:

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

1

k4 (70)

tidak terlalu golf; Saya yakin itu bisa lebih pendek

sangat mirip dengan J impl. di atas, saya pikir - pada dasarnya hanya mengumpulkan semua awalan (yang tepat), menghapus kata-kata dari awalan lagi (untuk menangani kasus "car"/ "carpet"), mengelompokkan mereka ke dalam kelas kesetaraan, memilih kelas dengan hanya satu elemen, mengurangi mereka dari daftar ke string, dan menambahkan di peta dari string ke diri mereka sendiri.

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

beberapa kasus uji

perhatikan bahwa dalam k/ q, string adalah daftar karakter, jadi string yang hanya berisi satu karakter perlu ditandai seperti itu menggunakan ,fungsi unary ; & mmwrt daftar string yang hanya berisi satu string

Penggunaan ini q's showfungsi, yang telah built-in format untuk beberapa struktur data, untuk membuat hasil yang lebih mudah dibaca:

  .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"

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)

Golf awal.

Memasukkan:

code,golf,going

Keluaran:

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


1

Perl, 93 77

Dengan baris baru dan lekukan agar mudah dibaca:

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

Sedikit terlambat dan terlalu lama, tapi saya senang akhirnya sampai di bawah 100. Fungsi mengembalikan daftar yang dapat ditugaskan ke variabel hash:

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

dan

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

Sebenarnya, daftar yang dikembalikan belum difilter - konstruksi hash selesai pada saat penugasannya yaitu fungsi luar. JIKA itu tidak cukup bersih / adil, tambahkan 3 untuk menghitung dan memasukkan konten fungsi ke kurung kurawal, tambahkan sebelumnya +- lalu fungsi mengembalikan referensi hash 'benar'.


1

T: 44 Bytes

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

CATATAN

  • Bahasa Q memiliki inti dalam bernama internal K4 (digunakan dalam jawaban ini dan jawaban lain sebelumnya untuk pertanyaan ini)

  • Untuk menguji kode, unduh juru bahasa (kx.com, gratis untuk penggunaan non-komersial, dukungan untuk Windows, Linux, Mac)

Penerjemah mengakui dua sintaks:

  • verbose (lebih banyak nama yang bisa dibaca, nama berbeda untuk moand dan diad, lebih banyak perpustakaan, ...). Muat file sumber dengan ekstensi q, atau interpreter interaktif

  • kompak (inti dalam fungsional, operator satu huruf, huruf yang sama untuk keduanya menggunakan monad / diad, ...). Muat file sumber dengan ekstensi k, atau juru bahasa interaktif dalam mode k (tulis \ saat diminta). Kode harus diuji dalam mode ini

Kode mendefinisikan lambda (fungsi anonim). Untuk memberi nama pada fungsi tersebut, kita memerlukan nama awalan: (ex f: {..}), jadi perlu 46 Bytes

UJI

(dengan asumsi fungsi bernama: jika tidak ganti f untuk kode)

f `code`golf`going

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

mengembalikan kamus (kunci sintaks! nilai). Kunci adalah daftar simbol (`symb`symb ..), dan nilai daftar daftar simbol. Jika kami mengeksekusi sentente di interpreter interaktif, kami memiliki presentasi yang lebih nyaman (setiap kunci dan nilai asosiasi pada baris yang berbeda)

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

PENJELASAN

x adalah argumen implisit ke lambda

$x konversi daftar simbol ke daftar string

(-1_)\ beralih di setiap elem dari daftar simbol

(dibaca sebagai untuk setiap string menghitung awalan (saat makan iterasi menjatuhkan karakter terakhir dari string) (-1_), hingga string kosong)

$ mentransformasikan ke daftar simbol lagi (daftar semua awalan)

p: dan ditugaskan ke hal

,/ meruntuhkan semua (menggabungkan dan menciptakan struktur satu tingkat)

= mengklasifikasikan -> untuk setiap awalan unik, mengaitkan kata-kata yang sesuai

#:' menghitung panjang (jumlah kata yang terkait dengan setiap awalan)

1= true jika length = 1 (unambiguous), false sebaliknya

& di mana -> indeks elemen sejati

p in\: menentukan untuk semua awalan jika mereka dalam awalan jelas

(..)' berlaku (..) untuk setiap nilai di sebelah kanan (awalan jelas)

?0,&: -> berbeda 0 disatukan di mana (untuk mengatasi kata-kata sebagai awalan itu sendiri)

p@ mengubah indeks menjadi simbol

x!.. buat kamus dengan x (kata) sebagai kunci, dan .. sebagai nilai

Baca sebagai:

  • Buat dan kembalikan kamus dengan kata-kata sebagai kunci, dan nilai-nilai ..

  • ... nilai indeks pada posisi berbeda 0 (semua kata) dan awalan yang tidak ambigu

  • ... tidak ambigu dihitung sebagai awalan yang hanya muncul di satu kata (asosiasi daftar kata untuk setiap simbol memiliki panjang satu)

  • ... daftar yang dihasilkan dari mengklasifikasikan semua simbol unik dengan kata-kata yang sesuai

  • ... awalan dihitung dengan mengulangi karakter terakhir dari setiap kata


1

PHP 7.0, 67 byte (mengunggah tantangan)

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

mengambil input dari argumen baris perintah; mencetak tanda koma; jalankan bersama -nr.

untuk PHP yang lebih baru , tambahkan satu byte: Ganti &adengan ""<.

untuk PHP yang lebih lama, gunakan 70 byte ini:

PHP, 70 byte

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

1

Brachylog , 23 byte

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

Cobalah online!

Mengambil input sebagai daftar melalui variabel input, dan menghasilkan daftar [key, value]pasangan melalui variabel output. Setiap string input yang bukan merupakan awalan dari string input lain akan dihasilkan sebagai awalan dari dirinya sendiri dua kali, meskipun header pada TIO menyembunyikan ini dengan menggunakan untuk mendapatkan daftar lengkap sebagai gantinya .

 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.

Jika duplikat dalam output tidak ditoleransi, tambahkan tiga byte untuk membungkus semuanya {}ᵘ, kecuali ada beberapa cara yang lebih pendek untuk mengecualikan bentuk sesuatu menjadi awalan itu sendiri, atau menghasilkan setiap pasangan output yang diperlukan tanpa aturan tambahan ∋gj.
String Tidak


1

APL (Dyalog Classic) , 38 byte

terima kasih Erik Outgolfer untuk mengingatkan saya untuk menggunakan pengkodean karakter byte tunggal

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

Cobalah online!


1
Um ... Saya tidak melihat salah satu karakter buruk yang tidak dapat Anda gunakan dengan AdBC SBCS di sini ...: P
Erik the Outgolfer

tanpa memperhatikan, saya telah memilih versi penerjemah yang salah lagi ... terima kasih telah mengurangi separuh jumlah byte saya :)
ngn

0

Python (127)

Jadi saya tidak bisa mengomentari @undergroundmonorail, tapi saya pikir mengambil pendekatan kamus akan lebih baik? Saya yakin dengan beberapa daftar / kamus pemahaman itu dapat dikurangi dengan sangat baik, tetapi tidak bisa membuatnya bekerja dengan muncul dari dikt.

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

Hasil cetak akan menampilkan kamus, tidak disusun.

EDIT: Ahh Saya merindukan mobil: mobil / mobil: kriteria karpet. Mungkin cek panjang?


Mungkin saya kehilangan sesuatu, tetapi ini tampaknya secara bergantian menambah dan menghapus entri awalan setiap kali ditemukan, jadi bukan awalan ambigu yang muncul jika muncul dalam 3 kata?
xnor

0

Groovy - 212 karakter

Golf:

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

contoh output:

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

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

Tidak Disatukan:

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
}


0

Zsh , 95 byte

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

Cobalah online!

Satu-satunya cara untuk "mengembalikan" array asosiatif di Bash / Zsh adalah dengan mendeklarasikannya tanpa localkata kunci dan kemudian mengaksesnya dalam lingkup induk. Ini akan menghemat satu byte. Namun, I / O via variabel umumnya disukai, jadi kami mencetak definisi array sebagai gantinya.

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

0

Ruby , 84 byte

Hanya perhatikan sudah ada solusi Ruby yang ada, oh well. Ini pada dasarnya meningkatkan solusi lama dengan memilih awalan dengan cara yang lebih cerdas (menghilangkan kebutuhan untuk menambahkan setiap kata sebagai "awalan" di akhir) dan menghitung awalan untuk memeriksa keunikan sebelum menambahkannya ke hash, alih-alih menimpa nilai dengan tiruan jika ada duplikat dan kemudian menghapus entri.

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

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.