Natknąłem się na to pytanie na SO i pomyślałem, że będzie to fajne wyzwanie golfowe. Oto on:
Wyzwanie:
Napisz program, który czyta sekwencję ciągów znaków, po jednym w wierszu, i wyświetla listę wszystkich pozycji, w których każdy ciąg ma ten sam znak.
Wejście i wyjście:
Dane wejściowe składają się z co najmniej jednego wiersza drukowalnych znaków ASCII, które nie są spacjami, a po każdym następuje nowy wiersz. Państwo może założyć, że wszystkie linie wejściowe mają taką samą długość. Nowa linia nie powinna być uważana za część danych wejściowych (tzn. Nie należy wyprowadzać jej jako pasującego znaku).
Przykładowe dane wejściowe (bezwstydnie skradzione z pytania SO):
abcdefg
avcddeg
acbdeeg
Po odczytaniu danych wejściowych program powinien wydrukować pozycje każdej pasującej kolumny i zawarte w nich znaki. (Twój program może, ale nie musi, przestać czytać dalsze dane wejściowe, jeśli może wcześnie ustalić, że nie ma pasujących kolumn). Dowolny rozsądny format wyjściowy jest dozwolony; w szczególności możesz użyć indeksowania opartego na 0 lub na podstawie 1 dla pozycji.
Przykładowe dane wyjściowe dla powyższych danych wejściowych (przy użyciu indeksowania opartego na 0):
0: a
3: d
6: g
Punktacja:
To jest golf golfowy, więc wygrywa najkrótsza odpowiedź. W przypadku remisu ułamkowe znaki rozdzielające remisy mogą zostać przyznane za dodatkowe funkcje:
- ½½ znaki do prawidłowej obsługi wierszy wejściowych o nierównej długości. (Dane wyjściowe nie powinny zawierać pozycji poza końcem najkrótszej linii wejściowej.)
- ¼ znaków do poprawnej obsługi danych wejściowych składających się z dowolnych znaków Unicode zakodowanych w UTF-8.
Aby uzyskać inspirację, możesz znaleźć nierozwiązane rozwiązania w pytaniu SO (patrz wyżej).
Wyjaśnienia:
Po prostu łączenie pozycji i znaków, jak w
0a3d6g
, nie liczy się jako „rozsądny wynik”. Powinieneś zapewnić jakiś separator (na przykład spację) między każdym elementem wyniku, aby można go było jednoznacznie przeanalizować.Dane wejściowe będą dostarczane w standardowym strumieniu wejściowym (
stdin
) lub przy użyciu dowolnego mechanizmu wprowadzania plików tekstowych, który jest najbardziej naturalny dla wybranego języka. (Jeśli wybrany język nie ma naturalnego mechanizmu wprowadzania plików, rób wszystko, co wydaje się najbliższe duchowi.)Dane wejściowe kończą się, gdy nie ma już danych do odczytu (tj. Gdy wystąpi warunek końca pliku). Jeśli chcesz, to może wymagać, że wejście zostać rozwiązana przez pustą linię (które następnie nie należy liczyć jako część wkładu, oczywiście). Jeśli to zrobisz, proszę o tym wspomnieć w swojej odpowiedzi, aby inni mogli podać poprawne dane wejściowe do testów.
Każda linia wprowadzania, w tym ostatnia, kończy się znakiem nowej linii. Twoja odpowiedź nie może zgłaszać tego nowego wiersza jako pasującej kolumny. (W porządku, jeśli twoje rozwiązanie obsługuje również dane wejściowe, w których ostatni wiersz nie kończy się na nowej linii, ale nie jest to wymagane).
Odpowiedzi:
APL, 25 znaków
Jako interpretera użyłem Dyalog APL (wersja 13). Obsługuje zarówno dane wejściowe o nierównej długości, jak i znaki Unicode (UTF-8).
Przykłady:
Objaśnienie, nieco od prawej do lewej:
⍵
.0=⍴⍵:⍬
jest naszym pierwszym wyrażeniem i sprawdza, czy otrzymaliśmy pustą linię (tzn. skończymy). Wykorzystuje wartownik (znajomy konstrukt dla wielu programistów funkcjonalnych), aby warunkowo wykonać wyrażenie po prawej stronie jelita grubego. W takim przypadku, jeśli 0 jest równe kształtowi / długości (⍴
) odpowiedniego argumentu, zwracamy pusty set (⍬
).⋄
oddziela dwa wyrażenia w ramach funkcji. Jeśli poprzednie wyrażenie nie zostało ocenione (a zatem nic nie zwróciło), przechodzimy do następnego wyrażenia.∇
). Argumentem tej funkcji jest wiersz bez oceny danych wejściowych użytkownika, podany przez quote-quad (⍞
).⊂⍵,⍨¨⍳⍴⍵
tworzy pary dla każdego znaku w ciągu, gdzie pierwszym elementem każdej pary jest jego pozycja w ciągu, a drugim elementem jest znak.⍳⍴⍵
daje wektor od 1 do⍴⍵
lub długość ciągu wejściowego.⍵,⍨¨
stosuje funkcję zamiany konkatenacji (,⍨
) do każdego¨
elementu ( ) po jego lewej stronie (⍵
w tym przypadku danych wejściowych użytkownika) i prawej. Dojazdy do funkcji konkatenacji powoduje zamianę jej lewego i prawego argumentu.⊂
, abyśmy mogli rozróżnić linie wprowadzania.⍞
)./
) nasz wynikowy wektor wektorów par za pomocą funkcji przecięcia (∩
), uzyskując pary, które znajdują się we wszystkich wektorach podrzędnych.źródło
Golfscript (28 znaków)
Występują problemy z zestawem znaków podczas przesyłania przez Unicode, więc nie ma premii za ćwierć punktu.
źródło
J,
57514440 znakówDocieram tam powoli, ale na pewno. Myślę, że wciąż jest to dalekie od ideału.
Byłem pewien, że użycie haka byłoby odpowiedzią, ale niestety nie (44 znaki):
Mogę potrzebować zupełnie innej metody, aby skrócić.
źródło
Haskell, 64 znaków
Obsługuje linie o nierównej długości. Obsługa Unicode zależy od bieżących ustawień regionalnych.
Przykładowe dane wyjściowe:
źródło
Python 2, wynik 81,5 (
11694868382 bajtów minus bonus)źródło
[:-1]
nie jest to konieczne, chyba że usuwasz obcy nowy wiersz na końcu danych wejściowych (który wydaje się nawet nie występować w pytaniu).zip(*sys.stdin)
jest[('a', 'a', 'a'), ('b', 'v', 'c'), ('c', 'c', 'b'), ('d', 'd', 'd'), ('e', 'd', 'e'), ('f', 'e', 'e'), ('g', 'g', 'g'), ('\n', '\n', '\n')]
. Nie widzę sposobu na uniknięcie usuwania ostatniej krotki nowych linii. Proszę mnie poprawić, jeśli źle zrozumiałem. Dziękuję za opinię.[:-1]
. Np.zip([1,2,3,4],[1,2,3])=> [(1, 1), (2, 2), (3, 3)]
(Bash) Skrypty powłoki, 105 znaków
Jeśli ktoś ma do tego więcej sztuczek, prosimy o wypełnienie komentarza!
Wynik:
źródło
/tmp/cols.sh: line 2: [1: command not found
i nic więcej.[
; a $ {y: 3} spowoduje, że będzie działał tylko z dokładnie 3 liniami danych wejściowych. Naprawianie i optymalizowanie wydajności (100 znaków)while((++i%`tail -1 $1|wc -c`));do x=`cut -c$i $1`;((`uniq|wc -l`==1))<<<"$x"&&echo $i ${x: -1};done
i używanie wartości domyślnych powinno pozwolić zaoszczędzić jeszcze jeden,for((;++i<`tail -1 $1|wc -c`;))do
ale w bashu jest nierozwiązany błąd.Perl, 87 znaków (½½ char premia za remis)
Oto golfowa wersja mojego własnego rozwiązania z wątku SO :
W przeciwieństwie do wersji SO, ten używa indeksów opartych na 1 dla danych wyjściowych. Korzysta z funkcji Perl 5.10
say
, więc musi być uruchamiany zperl -M5.010
(lub zperl -E
).Podobnie jak w wersji tak, to uchwyty kod linie o zmiennej długości, a będzie obsługiwać dowolny wkład Unicode jeśli standardowe wejście i wyjście było w trybie UTF-8. Niestety, domyślnie nie są, chyba że określono niewolny
-CS
przełącznik wiersza poleceń. W ten sposób zarabia premię ½ ½ char, ale nie ¼.Edycja: +1 char, aby naprawić błąd: tylko dlatego, że ciągi wejściowe nie zawierają kanałów, nie oznacza, że nie mogą się skończyć
$a
(np"+" & "J" eq "\n"
.).źródło
chop
zamiastchomp
.m
na razie, to nie jest tak, że ma to jakikolwiek wpływ na rankingi w tej chwili. :)T-SQL
źródło
Scala
115107: (¼ do obsługi UTF-8)bez golfa, a
Source.fromFile ("f")
zamiaststdin
dla lepszej testowalności:Wynik:
Dzięki Garethowi za zmniejszenie rozmiaru 8 za użycie
stdin
.źródło
stdin
zamiastfromFile("f")
zapisać 8 znaków?VBA (
premia 307,25284 - 0,75 = 283,25)Wiem, że to już zostało wygrane, ale oto mój strzał (nie czytam pliku, tylko ciąg znaków - trzeba dodać io). Podoba mi się, że muszę używać
l()
rekurencyjnie. Zazwyczaj nie potrzebuję rekurencji w moim prawdziwym programowaniu. Zrobiłem tylko tyle testów, ale uważam, że obejmuje to punkt bonusowy Unicode. Zakłada również, żevbCr
jest to terminator linii. Z tego powodu może to nie zostać przetłumaczone na wszystkie systemy.Kod:
Przykładowe wejście / wyjście:
źródło
P, 32
stosowanie
K, 22
Powyższe rozwiązanie można zredukować do 22, pisząc je całkowicie w K, zamiast przekazywać funkcje K do interpretera Q, co zmniejsza liczbę wymaganych nawiasów.
źródło
PHP,
123127 :(Nie jestem z tego zadowolony (będą musiały zostać wprowadzone ulepszenia), ale oto:
Dowód to działa.
Jeśli ktoś może wymyślić bardziej sprytny sposób inicjowania $ a i $ b, daj mi znać. Początkowo miałem,
$a=$b=$n=''
a $ b w końcu było poprawne, ale[empty] & [anything] == [empty]
więc $ a nigdy nie miałem treści.Edycja: Musiałem naprawić obsługę nowego wiersza (+6), ale upuściłem zamykający tag (-2).
źródło
?>
. Zauważyłem jednak, że twój kod zawiera błąd: drukuje dodatkowe dopasowanie, jeśli wszystkie linie zawierają końcowy znak nowej linii, jak określono.JavaScript (125
134140)Demo: http://jsfiddle.net/Fv7kY/4/
Edycja 1 : Zmień kolejność pętli, aby uniknąć nawiasów klamrowych. Zainicjuj i,
[]
aby połączyć zs
. Przesuńw
przyrost wyrażenia.Edycja 2 : Ustaw
S=I
przechwytywanie ostatnio wprowadzonego słowa i zapisywanie za pomocąs[1]
. Połączr=1
i++c<S.length
. UstawC=s[c]
w wewnętrznej pętli i porównajC
z poprzednimi i następnymi słowami, aby skrócić wyrażenies[w][c]==s[w++][c]
do justs[w++][c]==C
. Zapisano w sumie 9 znaków. Także ustawione,w=r=...
ponieważ kiedy to prawda,w=1
to właśnie z tym musimy zainicjowaćw
.źródło
Rubin (71)
wynik:
źródło
t[i]
zt[i,1]
.Common Lisp,
183165 znakówCzytelny format:
Wprowadź to bezpośrednio do REPL i wprowadź linie, kończąc pustą linią.
źródło
C, 126 znaków
Patrzyłem na to, ale po prostu nie mogę go zmniejszyć. Konieczne może być nowe podejście.
(Brak punktów bonusowych; obsługuje linie różnej wielkości tylko wtedy, gdy pierwsza linia jest krótsza.)
źródło
C # z .NET 4 (280)
Wersja do odczytu
Oryginalna odpowiedź
using c = System.Console; klasa P {static void Main () {char [] a; var b = c.ReadLine (); a = b.ToCharArray (); while (b! = "") {for (int i = 0;Wersja do odczytu:
źródło
0: a 1: b 2: c 3: d 4: e 5: f 6: g 0: a 2: c 3: d 6: g 0: a 3: d 6: g
. Oczekiwany wynik to0: a 3: d 6: g
.python 122 znaków :
źródło
)
afor
. Zamiast tego…str(x[0]) for i,x…
możesz to zrobić…str(x[0])for i,x…
. Jest również wyposażony w górętuple(x) for
i.split()])) if
Rubin (242)
źródło
STDIN
(ARGF
lub po prostugets
).DO#
źródło