Jakie są sprytne (krótkie i idiomatyczne) podejścia do pobierania listy ciągów i zwracania pojedynczego, poprawnie interpunkcyjnego ciągu zbudowanego z listy, z każdym cytowanym elementem.
To przyszło mi do głowy podczas eksperymentów z Groovy , dla których moje zbyt dosłowne, ale ilustrujące rozwiązanie jest
def temp = things.collect({"\'${it}\'"})
switch (things.size()) {
case 1:
result = temp[0]
break
case 2:
result = temp.join(" and ")
break
default:
result = temp.take(temp.size()-1).join(", ") + ", and " + temp[-1]
break
}
To znaczy, czy ['1']
powinien ustąpić '1'
, ['1','2']
powinien ustąpić '1 and 2'
[zobacz, co tam zrobiłem?] I ['1','2','3']
powinien ustąpić '1, 2, and 3'
.
Mam kilka dobrych odpowiedzi dla Groovy, ale chciałbym zobaczyć, co potrafią inne języki.
Jakie są zwięzłe sprytne podejścia w różnych językach, które wykorzystują cechy i idiomy tych języków?
['we invited the stripper','JFK','Stalin']
Odpowiedzi:
CSS,
132116115 bajtówPokaż fragment kodu
CSS nie pojawia się zbyt często w golfowym kodzie, ponieważ może formatować tylko tekst, ale tak naprawdę działa w tym wyzwaniu i pomyślałem, że fajnie byłoby to zrobić. Zobacz go w akcji za pomocą powyższego fragmentu (kliknij „Pokaż fragment kodu”).
Lista powinna znajdować się w połączonym pliku HTML z każdym elementem otoczonym
<a>
znacznikami i oddzielonymi podziałami linii. Elementy listy powinny być jedynymi elementami w ich elemencie nadrzędnym, npWyjaśnienie
Rozważmy powyższą wersję bez golfisty. Jeśli nie wiesz, jak działa CSS, wszystko poza nawiasami klamrowymi jest selektorem, który określa zestaw elementów HTML, do których mają zastosowanie deklaracje w nawiasach klamrowych. Każda para deklaracji selektora nazywana jest regułą . (Jest to bardziej skomplikowane, ale wystarczy to wyjaśnienie.) Przed zastosowaniem jakiegokolwiek stylu lista wydaje się być oddzielona tylko spacjami.
Chcemy dodawać przecinki po każdym słowie oprócz ostatniego, z wyjątkiem list dwóch słów, które nie otrzymują przecinków. Pierwszy selektor „
a:not(:last-child):nth-child(n+2):after
wybiera wszystkie elementy oprócz pierwszego i ostatniego.:nth-child(n+2)
jest krótszym sposobem powiedzenia:not(:first-child)
i działa w zasadzie poprzez wybranie elementów, których indeks (od 1) jest większy lub równy 2. (Tak, nadal mnie trochę myli. Dokumenty MDN mogą pomóc).Teraz musimy tylko wybrać pierwszy element, aby uzyskać przecinek, jeśli łącznie są trzy lub więcej elementów.
a:nth-last-child(n+3):after
działa jak:nth-child
, ale licząc od tyłu, więc zaznacza wszystkie elementy oprócz dwóch ostatnich. Przecinek przyjmuje sumę dwóch zestawów, a my używamy:after
pseudoelementu, aby dodaćcontent
bezpośrednio po każdym wybranym elemencie.Druga zasada jest łatwiejsza. Musimy dodać „i” przed ostatnim elementem na liście, chyba że jest to pojedynczy element. Innymi słowy, musimy wybrać ostatni element poprzedzony innym elementem.
+
to sąsiedni selektor rodzeństwa w CSS.źródło
<li>
.<li>
byłoby idealne, ale dodałoby to dwa dodatkowe znaki do selektorów. Wybrałem,<a>
ponieważ jest to jedna litera i nie stosuje własnego formatowania.Haskell:
81, 7774 znakówFunkcje Haskell: Dopasowywanie wzorów
źródło
f[x,y,z]
f["a","b","c"]
ma być,"a, b, and c"
ale tak jest"a,b and c"
y++", and "++z
przezf[y++",",z]
:)Ruby, 47 bajtów
Wyjaśnienie
$*
).$*
ma trzeci element ($*[2]
nie zwraca zera), weź wszystkie elementy minus ostatni i zamień je w łańcuch rozdzielany przecinkami za pomocąArray#*
. Na koniec dodaj dodatkowy przecinek, ciąg" and "
i ostatni argument wiersza poleceń.$*
nie ma trzeciego elementu, podano dwa, jeden lub zero argumentów. Argumenty można bezpiecznie połączyć z ciągiem" and "
i uzyskać poprawny wynik.źródło
Python 2 (61)
Główną sztuczką jest odcięcie części końcowego łącznika
", and "
dla jednego i dwóch elementów. Po pierwsze, wszystko jest wycięte, a po dwa przecinek jest usuwany. Odbywa się to poprzez wycinanie[8-7*len(s):]
(zauważając, żes
jest to jeden raz po nimpop
).Niestety,
d
nie można go po prostu zastąpić jego wyrażeniem, inaczejpop
byłoby to zbyt późno.źródło
s
zs=input()
i wyjąć pierwszą linię, jeśli się nie mylę. Zapisuje 2 znaki.s
wielokrotnie.CSS,
62 znaki112 znakówInspirowane innymi wpisami, nawet krótszymi. Zauważ, że wymaga to, aby elementy A nie były oddzielone białymi spacjami:
http://jsfiddle.net/olvlvl/1Ls79ocb/
Naprawiono „jeden i dwa”, jak wskazał Dennis:
http://jsfiddle.net/olvlvl/1Ls79ocb/3/
źródło
Perl (wer. 5.10+) -
37353428do uruchomienia z
perl -ape
rozdzieloną listą spacjiSTDIN
.Dane wyjściowe dla różnych danych wejściowych:
źródło
s/(\S+)$/and $1/
$
kotwicy w swojej edycji, więc wejściefoo bar baz
staje sięfoo, and bar, baz
. Możesz także usunąć jedną ze spacji, wykonującs/( \S+)$/ and$1/
$#F>1
jak@F>2
ogolił jednego więcej. Przepraszam za wszystkie sugestie dotyczące mikro ulepszeń, po prostu bardzo podoba mi się ta odpowiedź :)echo -n ... | wc -c)
. Jeśli przegapisz spację, zanim(\S+)
uzyskasz 33 znaki, ale jeśli wstawisztest this
, dostaniesztest and this
(dwie spacje potest
), więc bez więcej Myślę, że to nie takJavaScript (63)
l=a.length;l>2&&(a[l-1]='and '+a[l-1]);a.join(l>2?', ':' and ')
Skrzynie:
a = [1]
=>1
a = [1, 2]
=>1 and 2
a = [1, 2, 3]
=>1, 2, and 3
Zastrzeżenie: zmodyfikuje to ostatni element w tablicy o długości> 2.
źródło
&&
GNU sed - 69 znaków, w tym 1 dla
-r
flagiPobiera listę rozdzieloną spacjami (dość idiomatyczną dla skryptów powłoki).
Przykład
źródło
1 and 2
zamiast1, 2
Python 2 -
71, 7068Liczba znaków, w tym zarówno, jak
input
iprint
.źródło
Rubinowy, 57 bajtów
Łączę ciąg z,
,
a następnie zamieniam ostatni przecinek w ciągu naand
(i opcjonalny przecinek w zależności od długości listy).źródło
Kobra - 60
List<of T>.join
Funkcja Cobry pozwala określić inny separator dla dwóch ostatnich elementów listy, co czyni go tak krótkim.źródło
Perl - 59
Łączy listę z przecinkami, a jeśli lista zawiera więcej niż jeden element, albo dodaje
' and'
po ostatnim przecinku (jeśli długość> = 3), albo zastępuje go ostatnim przecinkiem (jeśli długość == 2).źródło
PHP,
192167146136 znaków:Na podstawie funkcji, którą napisałem lata temu na http://www.christopherbloom.com/2011/05/21/join-implode-an-array-of-string-values-with-formatting/
źródło
Partia - 151 bajtów
Uwaga; trzeba zadzwonić skrypt z
cmd
ze/v
zbioru jako switchon
, to tak nie mam na to zbyt długisetLocal enableDelayedExpansion
w skrypcie. W przeciwnym razie dodaj 30 do liczby bajtów i wywołaj skrypt normalnie.źródło
Groovy,
47 4357 znaków, JavaScript ES6 56 znakówGroovy:
Ponieważ tablica jest wypełniona znaków, możemy zastąpić
a.size>1
przeza[1]
JavaScript, ES6:
W obu przypadkach założono, że zmienna a ma omawianą tablicę.
źródło
PHP,
8684 znakówPo zainicjowaniu tablicy zaczynamy odliczać:
Prettified:
Ostatni element na liście został zmodyfikowany. Powinno to być OK, ponieważ w PHP przypisania tablic i wywołania funkcji wykonują kopie.
źródło
CJam,
35302827 bajtówJest to program, który czyta ze STDIN i drukuje do STDOUT. Wypróbuj online.
Jak to działa
Przykładowy przebieg
źródło
Arkusze Google,
67686792 bajtówDane wejściowe zaczynają się od komórki
A1
i są kontynuowane w dół, mimo że istnieje wiele wpisów.JOIN
scala je wszystkie w ciąg znaków z przecinkiem między nimi.FILTER
usuwa wszelkie niepuste znaki, dzięki czemu nie kończą się nieskończonymi przecinkami na końcu.SUBSTITUTE
zastępuje ostatni przecinek (znaleziony przezCOUNTA
zliczenie niepustych danych wejściowych).Nie jest to zbyt ekscytujące, ale można to zrobić w pojedynczej komórce.
źródło
)
z tej formuły dla -1 bajtów; Cholera, to była najszybsza edycja, jaką kiedykolwiek widziałem +1A:A>""
należy przekonwertować naA:A<>""
to i nie wprowadza się pominięcia przecinka oxford w przypadku tylko 2 obiektów>""
. Szybka korekta, którą zrobiłem wcześniej, najwyraźniej nie została przetestowana. Nie podoba mi się kierunek, w którym poszło ...JavaScript (ES6) 60
Zakładając, że nie ma pustych ciągów w tablicy wejściowej
Przetestuj w konsoli FireFox / Firebug
Wydajność
źródło
node --harmony
z szeregiem ciągówvar a = 'abcdefgh'.split('');
, ale po prostu tam jest...
i wydaje się, że nic nie robi. Również +1 za użycie unikalnej funkcji ES6()=>
.f=(a,b=a.pop())=>a[0]?a.join(', ')+', and '+b:b
jest również poprawny i 13 bajtów krótszy.JavaScript -
6056716763Nie do końca idiomatyczne podejście, ale dobrze się pisałem i lubię wyrażenia regularne.
Zakładając, że tablica jest przechowywana w
var a
:Skrócony przez proste sprawdzenie indeksu
[2]
: (yay boolean coercion)Najwyraźniej jestem do kitu i pominąłem test pojedynczego wejścia. Oto poprawiona wersja:
Ogoliłem 2 znaki, odwracając moje booleany i 3 kolejne, przenosząc przestrzeń z konkatenacji do ówczesnej / trzeciej pierwszej trójki:
Dzięki @tomsmeding za przypomnienie mi, że nie muszę zmuszać moich booleanów, ponieważ JS robi to za mnie. Uświadomiłem sobie również, że zapomniałem usunąć nawiasy oddzielające pierwszą trójskładnikową od konkatenacji wewnątrz
join()
:Czy zrobiłem to dobrze? Obowiązkowe nowe przeprosiny dla golfistów.
źródło
!!
;a[2]?A:B
już działa. Może trzeba odwrócić swoje wartości logicznych ponownie .a[i]
odpowiada prawdzie . Cóż prawie. Zakładam, że jeśli otrzymasz 2 wejścia, twoja tablica ma długość dwa. Następniea[2]===undefined
iundefined
oceniafalse
. EDYCJA: chodziło mi o twoją edycję :)Golfscript -
31393430Witaj świecie! Jestem lurkerem od dawna, plakatu po raz pierwszy. Oto moje 30-bajtowe rozwiązanie w Golfscript (biorąc pod uwagę, że tablica taka jak [1 2 3] jest już na stosie).
Wyniki są właściwe dla wszystkich przypadków testowych.
EDYCJA: Weź to, CJam!
źródło
Xojo,
527183 znakówZauważ, że UBound jest o jeden mniejszy niż długość tablicy.
źródło
Excel VBA, 108 bajtów
Anonimowa funkcja bezpośredniego okna VBE, która pobiera dane wejściowe jako tablicę rozdzielaną spacjami od zakresu
A1
i danych wyjściowych do bezpośredniego okna VBE.źródło
Rakieta 87
źródło
Python 62 znaki
Zakładając, że i jest listą ciągów:
źródło
C # 102 Chars
źródło
Julia (53)
Pobiera argumenty ze STDIN i wysyła do STDOUT
Rozwiązanie za pomocą Base.join (przedmioty, delim [, ostatni])
Edytować:
Przypadki testowe
1
1 i 2
1, 2 i 3
źródło
1, 2, and 3
, nie1, 2 and 3
.Rant (108)
Nie golfowany:
Stosowanie:
Wypróbuj online
źródło
Pyth, 28
Przykłady:
źródło
TypeError: can only concatenate list (not "str") to list
). Działa dobrze z najnowszą wersją.PHP - 72
Skonfiguruj wejście:
A potem proces:
źródło