Wyzwanie to jest nagrodą NinjaBearMonkey za wygraną w moje stada robotów Block Building! wyzwanie z poddaniem się Czarnego Rycerza . Gratulacje NinjaBearMonkey!
Wyzwanie tutaj jest dość proste, ale ma wiele możliwych podejść. Historia głosi, że w świecie Isometric Illusions istnieje 6 różnych rodzajów stworzeń:
- Ninja, w skrócie
N
- Niedźwiedzie, w skrócie
B
- Małpy, w skrócie
M
- NinjaBears, w skrócie
NB
- BearMonkeys, w skrócie
BM
- NinjaBearMonkeys, w skrócie
NBM
( NinjaBearMonkey jest oczywiście ostatnim, najpotężniejszym typem.)
Twoim zadaniem jest wykonanie spisu tych stworzeń, gdy są one ustawione obok siebie, tj. Kiedy ich łańcuchy skrótów są połączone. Zastrzeżenie polega na tym, że musisz uważać, aby nie przeliczyć części niektórych stworzeń jako osobnych stworzeń, które wyglądają podobnie. Stworzenia ustawią się tak, że:
- Każde wystąpienie
NBM
to 1 NinjaBearMonkey i 0 innych stworzeń. - Każde wystąpienie, po którym
NB
nie następuje,M
to 1 NinjaBear i 0 innych stworzeń. - Każda instancja, której
BM
nie poprzedza,N
to 1 BearMonkey i 0 innych stworzeń. - W przeciwnym razie przypadki
N
,B
iM
są to pojedyncze Ninjas, niedźwiedzie, małpy i odpowiednio.
Linia jest odczytywana od lewej do prawej.
Na przykład w linii stworzeń NBMMBNBNBM
jest 0 Ninja, 1 Niedźwiedź, 1 Małpa, 1 NinjaBear, 0 BearMonkeys i 2 NinjaBearMonkeys.
Wyzwanie
Napisz program lub funkcję, która pobiera ciąg znaków N
, B
oraz M
, i wypisuje lub zwraca liczbę każdego z 6 typów stworzeń w nim obecnych.
Dane wyjściowe powinny mieć formę
#N #B #M #NB #BM #NBM
z odpowiednią liczbą stworzeń zastępujących każdy #
znak. Wszystkie 6 liczb musi być pokazanych, oddzielonych spacjami, nawet gdy są one równe 0. Jednak mogą być w dowolnej kolejności (np. #NBM
Mogą być pierwsze).
Również:
- Ciąg wejściowy będzie zawierać tylko znaki
N
,B
iM
. - Jeśli wprowadzony zostanie pusty ciąg, wszystkie liczby będą wynosić 0.
- Dane wyjściowe mogą opcjonalnie zawierać pojedyncze początkowe i / lub końcowe spacje i / lub pojedyncze końcowe znaki.
Najkrótsze przesłanie w bajtach wygrywa.
Przykłady
Wejście: NB
Wyjście:0N 0B 0M 1NB 0BM 0NBM
Wejście: NBM
Wyjście:0N 0B 0M 0NB 0BM 1NBM
Dane wejściowe: NBMMBNBNBM
(przykład z góry) Dane
wyjściowe:0N 1B 1M 1NB 0BM 2NBM
Wejście: MBNNBBMNBM
Wyjście:1N 1B 1M 1NB 1BM 1NBM
Wejście: NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM
Wyjście:17N 6B 14M 5NB 8BM 3NBM
NBMNBM
byłoby całkowicie poprawnym wejściem. Czytając go od lewej do prawej, wyraźnie widać 2 NinjaBearMonkeys.Odpowiedzi:
Pyth, 22 bajty
Dość hackerski sposób na zaoszczędzenie 1 bajtu dzięki @Jakube.
Pyth, 23 bajty
Demonstracja.
Drukuje w odwrotnej kolejności, z końcową spacją i bez nowej linii.
.:"NBM")
jest wszystkimi podciągami,_
ustawia je we właściwej kolejności,/zN
liczy wystąpienia i=:zNd
zastępuje w miejscu każde wystąpienie danego ciągu spacją.źródło
JavaScript ES6, 86 bajtów
(Musiałem tylko na to odpowiedzieć.) Przechodzi przez każdy podciąg
NBM
, zaczynając od dłuższych, które mają wyższy priorytet. Wyszukuje każde wystąpienie tego konkretnego ciągu i usuwa go (w tym przypadku zastępuje go bieżącą liczbą, aby nie było ponownie dopasowane). W końcu zastępuje każdy podciąg liczbą i łańcuchem.Ten fragment kodu jest zapisany w odpowiedniku powyższego kodu w ES5, aby ułatwić testowanie z dowolnej przeglądarki. Jest to również nieznacznie zmieniony kod. Interfejs użytkownika aktualizuje się za każdym naciśnięciem klawisza.
źródło
'NBM<newline>BM<newline>...<newline>N'.replace(/./g, ...)'
, gdzie<newline>
s to dosłowne znaki nowej linii, a'
s odwrotne, tworząc ciąg szablonu ES6? Zapisuje dwa bajty w wyrażeniu regularnym (.
nie pasuje do nowego wiersza).Python 2, 78
Wariant odpowiedzi Vioz . Zabawa z reprezentacjami ciągów Python 2!
Zlicza występowanie podciągów pośrednio, dzieląc je, zliczając części i odejmując 1. Zamiast zastępowania podciągów symbolem wypełniacza, zastępuje ciąg przez utworzoną listę
split
. Następnie, gdy weźmiemy reprezentację ciągu, części są oddzielone spacjami i przecinkami.źródło
Rubin,
166807268 znakówWyjaśnienie:
Liczenie odbywa się w odwrotnej kolejności. Jest tak, ponieważ dłuższe ninje, niedźwiedzie i małpy mają pierwszeństwo przed krótszymi.
Dla
NBM
,BM
iNB
, sekwencje sągsub!
poza oryginalnym ciągiem z blokiem, aby policzyć, ile z tych sekwencji istnieje (tak, funkcja modyfikuje swój argument).BNBMM
byłyby liczone jakoNBM
iBM
zamiastB
,NBM
iM
(bo gdyNBM
zostaną usunięte, to umieścićB
iM
razem i nie byłoby sposobem na to rozróżnienie). Pierwotnie zwróciłem ciąg jednego znaku (.gsub!('NBM'){c+=1;?|}
), ale zdałem sobie sprawę, że mogę po prostu zwrócić wynik+=
(który jest liczbą, więc nie może to być żadenN
B
M
).DlaTeraz jest pętla (nie wiem, dlaczego nie pomyślałem o tym w pierwszej kolejności), więc są wykonywane w ten sam sposób.M
,B
iN
, mogę po prostucount
określić, ile z nich jest w ciągu (nie trzeba ich usuwać przezgsub!
).Podobne rozwiązanie w Strusiu ,
5451 znaków :Niestety nie jest to poprawne rozwiązanie, ponieważ w obecnej wersji strusia występuje błąd (który został już naprawiony, ale po opublikowaniu tego wyzwania).
źródło
%w(NBM BM NB M B N)
i usuwając podział.Java,
166162I z kilkoma podziałami linii:
Działa to po prostu. Wystarczy zapętlić tokeny, zamieniając je kropkami i licząc, dopóki dane wejściowe zawierają niektóre. Najpierw liczą się te duże, więc maluchy się nie psują.
Początkowo próbowałem zastąpić wszystko naraz i licząc różnicę długości, ale w ten sposób zabrało to kilka znaków :(
źródło
println
samo oświadczenie jest większe. Jestem z tego jednak zadowolony: DString q[]=
naString[]q=
CJam,
363231 bajtówDzięki @Optimizer za grę w golfa z 1 bajtu.
Wypróbuj online w interpretatorze CJam .
Jak to działa
źródło
N*
->`
powinno wystarczyć.R,
153134118Trwało to naprawdę szybko, ale mam nadzieję, że uda mi się ogolić kilka. Wejście to STDIN i wyjście do STDOUT.
Edytuj Zmiana tack. Pozbyłem się podzielonego sznurka i liczenia części. Teraz zastępuję części sznurkiem o jeden krótszym niż część. Różnica między długościami łańcuchów jest zbierana dla danych wyjściowych.
Wyjaśnienie
Testowe uruchomienie
źródło
Pyth, 19 bajtów
Jest to połączenie rozwiązania Pyth @ isaacg i niesamowitej sztuczki Python @ xnor.
Wypróbuj online: Demonstracja lub Uprząż testowa
Wyjaśnienie
źródło
Julia,
10697 bajtówTworzy to nienazwaną funkcję, która pobiera ciąg jako dane wejściowe i drukuje wynik do STDOUT z pojedynczym końcowym odstępem i bez końcowego znaku nowej linii. Aby to nazwać, nadaj mu nazwę, np
f=b->...
.Niegolfowane + wyjaśnienie:
Przykłady:
źródło
Python 2,
93888984 bajtówPrzyjmując proste podejście.
Zadzwoń tak:
Dane wyjściowe są takie:
źródło
in
.SAS,
144 142 139129Użycie (dodano 7 bajtów dla sysparm):
lub
Stosowanie:
Wynik:
źródło
cats('s/',z,'/x/')
zamiast's/'||strip(z)||'/x/'
.macro a i="&sysparm";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;%
data;i="&sysparm";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;
. Ponieważ już czytaszsysparm
, możesz równie dobrze uruchomić go jako krok danych. A jeśli działasz wsadowo, nie potrzebujeszrun;
.%macro a(i);i="&i";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;%mend;
PHP4.1, 92 bajty
Nie najkrótszy, ale czego jeszcze można oczekiwać od PHP?
Aby z niego skorzystać, ustaw klucz w COOKIE, POST, GET, SESSION ...
Apporach jest prosty:
Łatwe, prawda?
źródło
JavaScript,
108116 bajtówProste podejście, nic szczególnego
źródło
All 6 counts must be shown, separated by spaces, even when they are 0.
. Przypadek testowy:N
Perl, 46
źródło
SpecBAS - 164
Stosuje to samo podejście, co wiele innych. Wiersz 4 ciągle zapętla ciąg (od największego), zastępuje go, jeśli zostanie znaleziony.
SpecBAS ma kilka miłych akcentów w stosunku do oryginalnego ZX / Sinclair BASIC (przewijanie list, znajdowanie postaci), którego wciąż szukam.
źródło
C,
205186184 bajtówTrochę inne podejście oparte na maszynie stanu. gdzie
t
jest państwo.Rozszerzony
Funkcja testowa
źródło
for(;;*s++){...}
zamiastdo{...}while(*s++);
zapisywać niektóre bajty? Ponadto nie potrzebujesz znaku nowej linii wprintf
.for(;*s;s++)
. Ale musiałem zapętlić się z tym ostatnim znakiem zerowym. Dobre wezwanie do oszczędzania\n
, które nie jest wymagane.C, 146
źródło
Haskell - 177 bajtów (bez importu)
(Przepraszam za nekromancję internetową tutaj.)
Platforma Haskell nie ma wyszukiwania ciągów bez importu, a ja chciałem pochwalić się i wykorzystać fakt, że wszystkie wyszukiwane ciągi są podciągami jednego (bez powtórzeń), aby można było grupować znaki, identyfikując pary, które mogą podążajcie za sobą, co
f
tutaj się dzieje.Nadal potrzebuję pełnej listy,
l
aby sprawdzić równość i wyświetlić dokładnie tak, jak jest to wymagane, ale nie zrobiłbym tego, gdyby wyzwaniem było tylko zgłoszenie liczby możliwych zdarzeńwords
w dowolnej kolejności.źródło
Bash - 101
Przekaż ciąg jako pierwszy argument.
Wyjaśniono trochę:
źródło
rs , 275 bajtów
Demo i testy na żywo.
Działania są proste, ale trochę dziwne:
To twórczo wykorzystuje grupy do zmiany danych wejściowych takich jak:
w
Następna linia:
Zastępuje to ciągi wielkich liter podkreśleniami.
To po prostu wstawia znak funta na początku linii.
To początek fajna część. Zasadniczo pobiera sekwencje małych liter i znaków podkreślenia, konwertuje je na wielkie litery, grupuje je razem i umieszcza przed wstawionym funtem. Celem funta jest zarządzanie sekwencjami, które zostały już przetworzone.
Funt jest ponownie wstawiany na początku wiersza.
Wielkie litery są zastępowane ich odpowiednikami tekstowymi z odpowiednimi liczbami. Z powodu błędu w rs (nie chciałem ryzykować jego naprawy i dyskwalifikacji), puste sekwencje są konwertowane na
(^^)
, które są zastępowane przez 0 w wierszu od ostatniego do ostatniego. Ostatnia linia po prostu usuwa funta.źródło
KDB (Q), 76 bajtów
Wyjaśnienie
Test
źródło
Haskell: 244 bajty
źródło
p
is
tylko raz, więc nie musisz nadawać jej nazwy (->a#[]=[]:a#"NBM"
, to samo dlap
). BTW:words"N B M NB BM NBM"
zamiast listy ciągów zapisuje dodatkowe bajty.import
Jest tylko dlaintercalate
, to krótsze te re-wdrożyć go:...putStrLn.tail.((' ':)=<<)$map...
i pozbyćimport
. Umieść wszystkich strażników|
w definicji#
w jednym wierszu i użyj1<2
zamiastTrue
:...#(b:m)|a==b=...l#m|1<2=[]...
...?
mogą być zdefiniowane krótszy z listowego:c?t=sum[1|x<-c,x==t]
. Znowu używasz?
tylko raz, więc należy używać ciała bezpośrednio:...show(sum[1|x<-l#[],x==t])
.