Kısaltmaların genelleştirilmesi


14

Bir kelime listesinin ve kısaltmalarının bir girdisi verildiğinde, kısaltmaların oluşturulabileceği kalıbı çıktılayın.

Örnek girdisini ele alalım

potato ptao
puzzle pzze

örnek olarak (yani, kısaltması potatois ptaove kısaltması puzzleis pzze).

Elde etmek mümkün olan tüm yolları düşünün ptaodan potato. Olası bir yol birinci, üçüncü, dördüncü ve altıncı harfleri almaktır 1346. Fakat tve okelime birden çok kez geçen, orada üretmek için birden fazla diğer olası yolları ptaogelen potato: 1546, 1342, ve 1542.

Benzer bir şekilde, not bu pzzeoluşturulabilir puzzleherhangi biri ile 1336, 1346, 1436, 1446. Bu iki kısaltmanın ortak özelliği olan tek örüntü 1346; bu nedenle, bu girdi için çıktı bu olmalıdır. Birden fazla olası desen mümkünse, herhangi birini, bir kısmını veya tümünü (en az bir tane) çıktı alabilirsiniz.

Şunu varsayabilirsiniz:

  • Girilen kelimeler ve kısaltmalar yalnızca küçük harf içerir.

  • Girişte en az bir kelime / kısaltma çifti var.

  • Her kısaltmanın karşılık gelen sözcüğünden oluşturulması mümkündür.

  • Her kısaltmayı oluşturan en az bir örnek her zaman olacaktır.

  • Her kelimenin maksimum uzunluğu 9 karakterdir.

Giriş aşağıdakilerden herhangi biri olarak alınabilir:

  • 2 boyutlu dizi / liste / tuples dizisi / vb. [[word, abbr], [word, abbr], ...]

  • düz 1 boyutlu dizi / liste [word, abbr, word, abbr, ...]

  • küçük harf olmayan herhangi bir tek karakterle ayrılmış tek dize "word abbr word abbr"

  • karma / ilişkisel dizi / vb. {word => abbr, word => abbr, ...}

Bu giriş seçeneklerinden herhangi birinde, / abbr kelimesinin sırasını da değiştirmenize izin verilir (lütfen yazınızdaki giriş biçimini tam olarak açıklayın).

Çıktı tek bir sayı, rakam olmayanlar tarafından ayrılmış bir dize veya bir dizi / liste / grup / vb. Olarak verilebilir. sayı.

Bu , bayt cinsinden en kısa kod kazanacaktır.

Test senaryoları (yalnızca birden fazla desen çalışıyorsa results1 sonuç vermeniz gerektiğini unutmayın):

In                                Out
--------------------------------------------------------
potato ptao puzzle pzze         | 1346
aabbcc abc fddeef def           | 246
prgrmming prgmg puzzles pzzlz   | 14353
aaaaa a bbbb b ccc c dd d e e   | 1
aaaaa a bbbb b ccc c            | 1, 2, 3
abcxyz zbcyax                   | 623514
abcxyz acbbacbcbacbbac          | 132213232132213
potato ptao                     | 1346, 1546, 1342, 1542
a aaaaa                         | 11111

Sadece anladığımdan emin olmak için kısaltma işlemi harfleri yeniden sıralayabilir mi?
xnor

@xnor Test durumlarının çoğunda görüldüğü gibi düzeltin.
Kapı tokmağı

2B dizinin başka bir yönü olabilir mi? Her satır, her satır değil, bir çift kelime / kısaltma içerecektir
Luis Mendo

@DonMuesli Hayır, yapamaz.
Kapı tokmağı

Sıfır indeksleme kullanabilir miyiz, bu yüzden 1346 yerine 0235 yazdırın?
Denker

Yanıtlar:


3

Pyth, 19 bayt

mhh@Fd.TmmxkmbhdedQ

Burada deneyin!

Aşağıdaki biçimde bir liste alır:

[["word","abbr"],["word","abbr"],...]

1 elemanlı bir listede yer alan sıfır temelli indekslerin listesi olarak çıktıyı veren alternatif 17 bayt çözümü:

m@Fd.TmmxkmbhdedQ

açıklama

Misal: [["potato", "ptao"],["puzzle", "pzze"]]

İlk olarak, kısaltmadaki her karakteri, kelimedeki tüm oluşumların endekslerinin bir listesini eşleştiriyoruz.

[[[0], [2, 4], [3], [1, 5]], [[0], [2, 3], [2, 3], [5]]]

Sonra bize veren bu listeyi

[[[0], [0]], [[2, 4], [2, 3]], [[3], [2, 3]], [[1, 5], [5]]]

Yani her bir kısaltmanın her bir karakterinin indeksleri tek bir listede bir aradadır.

Öyleyse, tüm bu listelerde ortak bir dizin bulmamız gerekir:

[[0], [2], [3], [5]]

Bu benim yukarıdaki 17 baytlık çözümümün çıktısı. Bu daha sonra dönüşür [1,3,4,6].

Kod dökümü

mhh@Fd.TmmxkmbhdedQ # Q = giriş

m Q # d ile harita girişi
        m ed # her kısaltmayı k ile eşleştir
            mbhd # kelimeyi karakter listesine eşle
         mxk # her bir kısaltma karakterini bir indeks listesine eşler
      .T # Devrik
    Fd # Her öğeyi katla
   @ # ve mevcudiyet üzerine filtre
 hh # Sonucun ilk öğesini al ve artır

Daha dmönce olan hakkı da silemediniz @mi?
Kapı tokmağı

@ Kapı tokmağı yapabilirim. Bunu tespit ettiğiniz için teşekkürler!
Denker

3

MATL , 29 bayt

!"@Y:!=2#fX:wX:h]N$v1XQtv4#X>

Giriş, aşağıdaki biçimde bir 2D dizidir:

{'potato' 'ptao'; 'puzzle' 'pzze'}

Çevrimiçi deneyin! ( bağlantılı kod, bu yanıtın gönderilmesinden bu yana dildeki değişiklikler nedeniyle bazı değişiklikler içerir )

!       % take input. Transpose
"       % for each column
  @Y:   %   push column. Unpack the two strings and push them onto the stack
  !     %   transpose second string
  =     %   matrix with all pairwise matchings of characters in word and abbreviation
  2#f   %   find row and col indices of those matchings
  X:    %   transform into column vector
  wX:   %   swap, transform into column vector
  h     %   concat into a two-col matrix
]       % end for
N$v     % concatenate all matrices containing the indices
1       % push 1
XQ      % build matrix adding 1 for each (row,col) index
tv      % concat vertically with itself, so that it has at least two rows.
        % This forces the following function to work on each col.
4#X>    % arg max of each col: position that produces a match in all pairs.
        % If there are several maximizers in each col this gives the first

Kod, bazı ilgili (ve uzun!) Numaralar gerektiriyordu

  • find( f) Tarafından üretilen vektörlerin yönünün giriş şekline bağlı olarak değişmesini önleyin . Bunlar ifadelerdir X:wX:: her iki çıkışı da sütun vektörleri olmaya zorlar.
  • min( X>) İşlevinin "ilk tekil olmayan boyutta çalışma" varsayılan davranışını önleyin . Bunlar ifadelerdir tv: en az iki satır sağlamak için kendisinin bir kopyasını kapat);

2

Perl, 46 45 42 bayt

İçin +1 içerir -p

Girdiyi STDIN üzerinde sıralı kelimeler olarak verin, ör.

perl -p abbrev.pl
prgrmming
prgmg
puzzles
pzzlz

İle STDIN sonlandır ^Dveya ^Zya da her türlü sisteminizde ihtiyaç vardır

abbrev.pl:

s#.#${${--$_.$.%2}.=$&}||=-$_#eg;$_ x=eof

açıklama

Bu girdiyi düşünün (kavramsal program, bu program için gerçek giriş yolu değil):

potatoes     ptao
puzzle       pzze

Bir sütun kimliğine göre dizine eklenen tam dizelerin dikey sütunlarını temsil eden program oluşturma dizeleri

id1    pp     -> 1
id2    ou     -> 2
id3    tz     -> 3
id4    az     -> 4
...

Kısaltmalar için de aynısını yapar, ancak farklı bir kimlik kullanarak

ID1    pp     -> 1
ID2    tz     -> 3
ID3    az     -> 4
ID4    oe     -> 6

Bu -pseçenek kullanılarak kelimeler tek tek işlenemez . Sütun dizeleri, her sözcük yürürken tekrarlanan birleşmeler kullanılarak oluşturulur s#.# ...code.. #eg, bu nedenle her sütun tekrarlanabilir bir kimliğe ihtiyaç duyar. Ben sütun numarası eksi satır numarası modulo 2 kullanın. Sütun numarası, --$_sadece kullanımı nedeniyle a-zsayısal bir bağlamda 0 olarak değerlendirmek için garanti edilen geçerli sözcük olarak başlayan kullanılarak oluşturulabilir . Böylece anladım -1, -2, -3, .... Gerçekten 1, 2, 3, ...kullanmak $_++isterdim , ama kullanmak normal bir sayısal sayaç yerine perl sihirli dize artışını tetikler. Ben do kullanmak istiyorum$_ ve başka bir değişken değil, çünkü herhangi bir başka değişken çok fazla bayt alan her döngüde sıfıra başlatmak zorunda kalacaktım.

Modulo 2 satır numarası, tam kelimenin kimliklerinin ve kısaltma kimliklerinin çakışmadığından emin olmak içindir. Tam sözcüklerin hepsi aynı uzunlukta olmadığından, birleştirilmiş dize üzerinde bir sütun numarası olması için bir dizede tam sözcüğü ve kısaltmayı kullanamayacağımı fark ettim, bu yüzden abbeviated kelime sütunları sıralı olmaz. Ayrıca kısaltılmış kelimeyi ilk sıraya koyamıyorum (hepsi aynı uzunlukta) çünkü tam kelimelerin ilk sütununun sayımının 1 olması gerekiyor.

Sütun dizeleri oluşturmak için katı olmayan bir başvuru yoluyla perl genel ad alanı kötüye:

${--$_.$.%2}.=$&

Sonra her bir sütun dizesini perl global ad alanını tekrar kötüye kullanarak dizinin göründüğü ilk sütun numarasıyla eşleştiriyorum (daha önce belirtilen eşleme) (ancak küresellerin birbiriyle etkileşime girmemesi için adların çakışamayacağına dikkat edin):

${${--$_.$.%2}.=$&} ||= -$_

Reddetmek zorundayım $_çünkü yukarıda açıkladığım gibi sütunları sayıyorum -1, -2, -3, .... ||=Makyaj emin sadece belirli bir sütunun ilk ortaya aksi önceki sütun numarası korunur, yeni bir sütun numarası alır ve değer olarak geri döndü. Bu, özellikle her kısaltılmış sözcük için gerçekleşecektir, çünkü şartname, tam kelimelerde önceden görünecek bir sütun olduğunu garanti eder. Bu nedenle, en son kısaltılmış kelimede, her harf, tüm kısaltılmış kelimelerin sütununa karşılık gelen tam kelimedeki sütun numarası ile değiştirilir. Dolayısıyla, son değiştirmenin sonucu, istenen nihai sonuçtur. Bu nedenle, yalnızca girişin sonunda olursak yazdırın:

$_ x=eof

Sütun dizini ataması, sütun henüz tam olarak oluşturulmadığı veya bazı kelimeler daha kısa olduğu ve tam sütun uzunluğuna ulaşmadığı için eksik sütunlar için girişler oluşturur. Kısaltılmış her kelimede gereken sütunların, mümkün olan maksimum uzunluğa (halihazırda görülen çiftlerin sayısı) sahip olan tam kelimelerden bir düzeltme sütununa sahip olması garanti edildiğinden, bu ekstra girişler hiçbir zaman yanlış eşleşmelere neden olmaz.


1

Haskell, 74 bayt

import Data.List
foldl1 intersect.map(\(w,a)->mapM(`elemIndices`(' ':w))a)

Girdi biçimi, dize çiftlerinin bir listesidir, örneğin:

*Main > foldl1 intersect.map(\(w,a)->mapM(`elemIndices`(' ':w))a)  $ [("potato","ptao"),("puzzle","pzze")]
[[1,3,4,6]]

Nasıl çalışır: mapM(aynı sequence . map) ilk olarak her çifti (w,a)kısaltmadaki harflerin indeks listelerine dönüştürür ( ' ':Haskell'in doğal 0 tabanlı dizinini 1 tabanlıya sabitler), örneğin ("potato", "ptao") -> [[1],[3,5],[4],[2,6]]tüm kombinasyonlarının bulunduğu bir listeye konumdaki eleman alt ilisteden çizilir i, örn [[1,3,4,2],[1,3,4,6],[1,5,4,2],[1,5,4,6]]. foldl1 intersectbu tür liste listelerinin kesişimini bulur.


0

ES6, 92 bayt

(w,a)=>[...a[0]].map((_,i)=>[...w[0]].reduce((r,_,j)=>w.some((s,k)=>s[j]!=a[k][i])?r:++j,0))

Girdiyi bir kelime dizisi ve bir kısaltma dizisi olarak kabul eder. 1 tabanlı endekslerden oluşan bir dizi döndürür (bu bana 2 baytlık dammit'e mal olur). Birden fazla çözüm olması durumunda, en yüksek endeksler döndürülür.


0

Python 3, 210 bayt

Burada üst puanları gören etkileyici bir cevap değil, ama bu gerçekten Python ile yaptığım en çılgın liste anlayışından bazıları. Yaklaşım oldukça ileridir.

 def r(p):
    z=[[[1+t[0]for t in i[0]if l==t[1]]for l in i[1]]for i in[[list(enumerate(w[0])),w[1]]for w in p]]
    return[list(set.intersection(set(e),*[set(i[z[0].index(e)])for i in z[1:]]))[0]for e in z[0]]

İşlev, girdiyi her zaman 2: D dizesi gibi bekler [[word, abbr],...]ve tamsayıların bir listesini döndürür.

Ps: Ayrıntılı bir açıklama yakında

Ps2: Daha fazla golf önerileri bekliyoruz!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.