Przetwarzanie tekstu nr 1: dzielenie wyrazów

14

tło

Jest to pierwsza część 3-dołkowego pola golfowego poświęconego przetwarzaniu tekstu. Ogólny pomysł polega na tym, że jeśli weźmiesz tekst wejściowy i przejrzysz go przez wszystkie trzy wyzwania (z niewielką ilością kodu kleju), wypluje pięknie sformatowany akapit. W tym pierwszym wyzwaniu Twoim zadaniem jest dzielenie tekstu za pomocą podanych wzorców dzielenia wyrazów.

Wejście

Twój program pobierze dwa ciągi znaków: fragment tekstu i listę wzorców dzielenia wyrazów. Pierwsze wejście jest po prostu niepustym ciągiem drukowalnych znaków i spacji ASCII; nie będzie zawierać podziałów ani tyld ~. Drugie wejście to rozdzielona przecinkami lista słów, które składają się z rozdzielonych tyldą sylab małych znaków ASCII. Przykładem jest ex~cel~lent,pro~gram~ming,abil~i~ties.

Wynik

Twój program zmodyfikuje pierwsze wejście w następujący sposób. Każde słowo (maksymalny ciąg znaków alfabetycznych ASCII), którego dzielona wersja małych liter znajduje się na drugim wejściu, zostanie zastąpiona tą wersją dzieloną, ale wielkość liter zostanie zachowana. W powyższej przykładowej liście, jeśli tekst zawiera słowo Excellent, należy je zastąpić Ex~cel~lent; nie Excellentlynależy ich jednak modyfikować. Twój wynik będzie taki zmodyfikowany ciąg.

Szczegółowe zasady i punktacja

Możesz przyjąć następujące założenia dotyczące danych wejściowych:

  • Pierwsze wejście nie zawiera tyldy i nie ma spacji wiodących, końcowych ani powtarzających się. Nie jest pusty.
  • Drugie wejście zawiera co najmniej jedno słowo, a każde słowo zawiera co najmniej dwie sylaby. Każda sylaba jest niepusta.
  • Drugie wejście nie zawiera słowa występującego jako sylaba w innym słowie.

W razie potrzeby możesz zmienić kolejność dwóch danych wejściowych i opcjonalnie dodać jeden końcowy znak nowej linii do wyniku.

Możesz napisać funkcję lub pełny program. Wygrywa najniższa liczba bajtów, a standardowe luki są niedozwolone.

Przypadki testowe

Są one wymienione w formacie 1st input [newline] 2nd input [newline] output.

Excellent programming abilities, you work excellently!
ex~cel~lent,pro~gram~ming,abil~i~ties
Ex~cel~lent pro~gram~ming abil~i~ties, you work excellently!

Superman (sometimes incorrectly spelled "Super-man") is super #&%@ing strong.
su~per,some~times,in~cor~rectly,spell~ing
Superman (some~times in~cor~rectly spelled "Su~per-man") is su~per #&%@ing strong.

IncONsISTent caPItalizATIon!
in~con~sis~tent,cap~i~tal~iza~tion
In~cON~sIS~Tent caP~I~tal~izA~TIon!

Such short words.
awk~ward
Such short words.

Digits123 are456cool789.
dig~its,dig~i~tal,are~cool
Dig~its123 are456cool789.

magic magic
ma~gic
ma~gic ma~gic

Ewentualny błąd dzielenia wyrazów w tym wyzwaniu wynika z tego narzędzia dzielenia wyrazów .

Zgarb
źródło
Zakładam, że wejście jest standardowym 7-bitowym ASCII, a nie jakąś rozszerzoną wersją 8-bitową?
orlp
Czy można założyć, że jakikolwiek znak niealfanumeryczny nie będzie się liczył jako zmiana słowa (np. #programming!Drugie wejście będzie nadal miało wpływ na drugie słowo pro~gram~ming)? Czy liczby też się nie liczą (tzn. Czy dozwolone są tylko znaki alfabetyczne)?
cole
@orlp Tak, dane wejściowe składają się ze standardowych drukowalnych znaków ASCII wymienionych tutaj .
Zgarb
@Cole Znaki niealfabetyczne nie są częścią słów (patrz drugi przypadek testowy). Cyfry liczą się jako niealfabetyczne, dodam o tym przypadek testowy.
Zgarb
Czy mogę założyć maksymalną liczbę sylab w jednym słowie?
Qwertiy,

Odpowiedzi:

5

Pip, 60 54 bajtów

Fwa^`([A-Za-z]+)`O{aQ'~?'~w@++y}M(LCwQ_RM'~FIb^',Yv)|w

Repozytorium GitHub dla Pip

Pobiera dane wejściowe jako argumenty wiersza poleceń (co wymaga cudzysłowów wokół danych wejściowych 1, zakładając, że zawiera spacje). Nie jest drukowany końcowy znak nowej linii (dodaj znak xna końcu programu, aby go dodać).

Nieco niepohamowany, z komentarzami:

 ; Split 1st input on runs of letters, including the separators in the results
a^:`([A-Za-z]+)`
 ; Split 2nd input on commas
b^:',
 ; Iterate over the words w in that list
Fwa {
  ; Filter b for entries that match the current word (lowercase, with tildes removed)
 m:(LCw EQ _RM'~)FIb
  ; We expect this to be a list of 0 or 1 elements
  ; If it has one, m gets that element (the hyphenation pattern); if it's empty, m gets nil
 i:-1
 m:m@i
  ; Map this function to each character of pattern m: if it's tilde, return tilde;
  ; otherwise, return corresponding character of w
 m:{aEQ'~ ? '~ w@++i}Mm
  ; Output the result, unless it was nil (falsey), in which case output the original word
 Om|w
}

Przykładowy przebieg:

C:\Users\dlosc> pip.py hyphens.pip "IncONsISTent caPItalizATIon!" in~con~sis~tent,cap~i~tal~iza~tion
In~cON~sIS~Tent caP~I~tal~izA~TIon!
DLosc
źródło
8

Siatkówka , 88 bajtów

+is`(?<![a-z~])([a-z~]+)(?=([a-z]+)+[^a-z~].*(?<=[\n,]\1(?(2)!)(?<-2>~\2)+[\n,]))
$1~
\n.*
<empty>

Dla celów zliczania każda linia przechodzi do osobnego pliku, \njest zastępowana rzeczywistymi znakami nowej linii i <empty>jest pustym plikiem. Dla wygody możesz uruchomić powyższy kod z jednego pliku (gdzie <empty>jest pusta linia), jeśli używasz -sflagi interpretera.

Martin Ender
źródło
2

JavaScript ES6, 117 141 znaków

f=(t,p)=>p.split`,`.map(p=>t=t.replace(RegExp("((?:^|[^a-z])"+p.replace(/~/g,")(")+")(?=$|[^a-z])","ig"),(...x)=>x.slice(1,-2).join("~")))&&t

Test:

document.querySelector(".question pre").textContent.split("\n\n").map(t=>(t=t.split("\n"))&&f(t[0],t[1])==t[2])
// Array [ true, true, true, true, true ]
Qwertiy
źródło
Możesz użyć eval zamiast konstruktora RegExp. Szablony ciągów mogą również zaoszczędzić kilka bajtów
Downgoat
1

JavaScript (ES6), 173 169

Podstawowe wyszukiwanie wyrażeń regularnych i zamień

(a,b)=>(b.split`,`.map(s=>a=a.replace(eval(`/(^|[^a-z])(${s.replace(/~/g,"")})(?=[^a-z]|$)/gi`),(_,n,o)=>(x=0,n+s.split``.map((q,i)=>(q=='~'&&++x?q:o[i-x])).join``))),a)

Skrzypce

Edycja: Naprawiono błąd dla przypadku testowego magic magic,ma~gic

DankMemes
źródło
Źle: f("magic magic", "ma~gic")zwraca"ma~gic magic"
Qwertiy
@Qwertiy naprawiony. Jakoś naprawienie go zaoszczędziło mi też 4 bajty!
DankMemes,
0

Perl, 146

$a=<>;$d=$_=~s/~//rg,$a=~s/(?<!\pL)$d(?!\pL)/h($&,$_)/gie for(split/,|\n/,<>);
print$a;
sub h{($g,$h)=@_;while($h=~/~/g){substr($g,"@-",0)='~'}$g}

Tylko pierwsza próba, wiele rzeczy można skrócić - będzie kontynuowana jutro!

Jarmex
źródło