Эта задача является призом NinjaBearMonkey за победу в моих блоках Block Building Bot! вызов с представлением Черного рыцаря . Поздравляем NinjaBearMonkey!
Задача здесь довольно проста, но имеет множество возможных подходов. История гласит, что в мире Изометрических иллюзий существует 6 различных типов существ:
- Ниндзя, сокращенно
N
- Медведи, сокращенно
B
- Обезьяны, сокращенно
M
- NinjaBears, сокращенно
NB
- BearMonkeys, сокращенно
BM
- NinjaBearMonkeys, сокращенно
NBM
( NinjaBearMonkey , конечно, последний, самый мощный тип.)
Ваша задача - провести перепись этих существ, когда они выстроены в ряд, то есть, когда их строки сокращений объединены. Предостережение заключается в том, что вам нужно следить за тем, чтобы части некоторых существ не были переоценены как отдельные существа, которые выглядят одинаково. Существа будут выстроены так, что:
- Любой экземпляр
NBM
- 1 NinjaBearMonkey и 0 других существ. - Любой случай, за которым
NB
не следует,M
это 1 NinjaBear и 0 других существ. - Любому экземпляру,
BM
которому не предшествует,N
является 1 BearMonkey и 0 других существ. - В противном случае, экземпляры
N
,B
иM
одиночные Ninjas, медведи и обезьяны соответственно.
Строка читается слева направо.
Так, например, в линейке существ NBMMBNBNBM
есть 0 ниндзя, 1 медведь, 1 обезьяна, 1 ниндзя-медведь, 0 медведей-обезьян и 2 ниндзя-медведей-обезьян.
Вызов
Напишите программу или функцию, которая принимает строку символов N
, B
и M
, и печатает или возвращает, сколько из каждого из 6 типов существ присутствует в ней.
Вывод должен иметь форму
#N #B #M #NB #BM #NBM
с соответствующим количеством существ, заменяющим каждый #
знак. Все 6 отсчетов должны быть показаны через пробел, даже если они равны 0. Однако они могут быть в любом порядке (например, могут стоять #NBM
первыми).
Также:
- Строка ввода будет содержать только символы
N
,B
иM
. - Если вводится пустая строка, то все счетчики равны 0.
- Выходные данные могут дополнительно содержать один начальный и / или завершающий пробел и / или один завершающий символ новой строки.
Самая короткая подача в байтах побеждает.
Примеры
Вход: NB
Выход:0N 0B 0M 1NB 0BM 0NBM
Вход: NBM
Выход:0N 0B 0M 0NB 0BM 1NBM
Вход: NBMMBNBNBM
(пример сверху)
Выход:0N 1B 1M 1NB 0BM 2NBM
Вход: MBNNBBMNBM
Выход:1N 1B 1M 1NB 1BM 1NBM
Вход: NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM
Выход:17N 6B 14M 5NB 8BM 3NBM
NBMNBM
Будет вполне корректным вводом. Читая это слева направо, ясно, что есть 2 NinjaBearMonkeys.Ответы:
Pyth, 22 байта
Довольно хакерский способ сэкономить 1 байт, благодаря @Jakube.
Pyth, 23 байта
Демонстрация.
Печать в обратном порядке, с завершающим пробелом и без завершающего перевода строки.
.:"NBM")
Это все подстроки, размещает_
их в правильном порядке,/zN
подсчитывает вхождения и=:zNd
заменяет каждое вхождение каждой строки на пробел.источник
JavaScript ES6, 86 байт
(Я просто должен был ответить на это.) Он проходит через каждую подстроку
NBM
, начиная с более длинных, которые имеют более высокий приоритет. Он ищет каждое вхождение этой конкретной строки и удаляет ее (в этом случае его заменяют текущим счетчиком, чтобы он больше не совпадал). Наконец, каждая подстрока заменяется на число + строку.Этот фрагмент стека написан в ES5-эквиваленте приведенного выше кода, чтобы его было проще тестировать из любого браузера. Это также немного неопрятный код. Пользовательский интерфейс обновляется с каждым нажатием клавиши.
источник
'NBM<newline>BM<newline>...<newline>N'.replace(/./g, ...)'
, где<newline>
s - буквальные символы новой строки, а'
s - обратные метки, образующие строку шаблона ES6? Сохраняет два байта в регулярном выражении (.
не соответствует символам новой строки).Python 2, 78
Вариант ответа Виоса . Удовольствие от представления строки Python 2!
Косвенно подсчитывает вхождения подстроки, разделяя ее, подсчитывая части и вычитая 1. Вместо замены подстрок символом-заполнителем строка заменяется созданным списком
split
. Затем, когда мы берем его строковое представление, части разделяются пробелами и запятыми.источник
Рубин,
166807268 символовОбъяснение:
Подсчет производится в обратном порядке. Это потому, что более длинные ниндзя, медведи и обезьяны имеют преимущество перед более короткими.
Для
NBM
,BM
иNB
, последовательностиgsub!
извлекаются из исходной строки с блоком для подсчета количества этих последовательностей (да, функция изменяет свой аргумент).BNBMM
будет считаться ,NBM
иBM
вместо тогоB
,NBM
иM
(потому что , когдаNBM
будет удален, он бы поставилB
иM
вместе , и не было бы способ отличить его). Первоначально я возвращал одну символьную строку (.gsub!('NBM'){c+=1;?|}
), но я понял, что могу просто вернуть результат+=
(который является числом, поэтому он не может быть любымN
B
M
).ИТеперь это цикл (не знаю, почему я вообще об этом не задумывался), поэтому все делается так же.M
,B
иN
, я могу только,count
сколько их в строке (нет необходимости удалять их черезgsub!
).Аналогичное решение в страусе ,
5451 символ :К сожалению, недопустимое решение, так как в текущей версии Страуса есть ошибка (которая теперь исправлена, но после того, как эта проблема была опубликована).
источник
%w(NBM BM NB M B N)
и удалив разделение.Ява,
166162И с несколькими переносами строк:
Это работает довольно просто. Просто зациклите токены, заменив их точками и считая до тех пор, пока вход содержит некоторые. Сначала подсчитывает большие, чтобы маленькие не испортили.
Сначала я попытался заменить все сразу и посчитать разницу в длине, но таким образом потребовалось еще несколько символов :(
источник
println
утверждение одно больше, чем это. Я доволен этим, хотя: DString q[]=
наString[]q=
CJam,
363231 байтСпасибо @Optimizer за удаление 1 байта.
Попробуйте онлайн в интерпретаторе CJam .
Как это работает
источник
N*
->`
должно быть достаточно.R
153134118Это действительно дольше, но надеюсь, я смогу побриться немного. Вход STDIN и выход STDOUT.
Изменить Смена такта. Избавился от расщепленной струны и счетных частей. Теперь я заменяю детали строкой, которая короче детали. Разница между длинами строк собирается для вывода.
объяснение
Тестовый забег
источник
Pyth, 19 байт
Это смесь решения Python @ isaacg и невероятного трюка Python @ xnor.
Попробуйте онлайн: демонстрация или тестовая привязь
объяснение
источник
Юлия,
10697 байтЭто создает безымянную функцию, которая принимает строку в качестве входных данных и печатает результат в STDOUT с одним завершающим пробелом и без завершающего перевода строки. Чтобы назвать его, дайте ему имя, например
f=b->...
.Ungolfed + объяснение:
Примеры:
источник
Python 2,
93888984 байтаПринимая простой подход.
Звоните вот так:
Вывод выглядит так:
источник
in
.SAS,
144 142 139129Использование (добавлено 7 байт для sysparm):
или
Использование:
Результат:
источник
cats('s/',z,'/x/')
вместо'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;
. Поскольку вы уже читаете изsysparm
, вы можете просто запустить его как шаг данных. И если вы работаете в пакетном режиме, вам не нужноrun;
.%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 байта
Не самый короткий, но что еще можно ожидать от PHP?
Чтобы использовать его, установите ключ на COOKIE, POST, GET, SESSION ...
Apporach является основным:
Легко, правда?
источник
JavaScript,
108116 байтПросто прямой подход, ничего особенного
источник
All 6 counts must be shown, separated by spaces, even when they are 0.
. Контрольный пример:N
Perl, 46
источник
SpecBAS - 164
Использует тот же подход, что и многие другие. Строка 4 продолжает циклически повторять строку (начиная с самой большой), заменяя ее, если найдена.
У SpecBAS есть несколько приятных штрихов к оригинальному ZX / Sinclair BASIC (просмотр списков, поиск символов), которые я до сих пор выясняю.
источник
C
205186184 байтаНемного другой подход, основанный на состоянии машины. где
t
находится государство.расширенный
Тестовая функция
источник
for(;;*s++){...}
вместо того, чтобыdo{...}while(*s++);
сохранить несколько байтов? Кроме того, вам не нужен символ перевода строки вprintf
.for(;*s;s++)
. Но мне нужно было зацикливаться на этом последнем нулевом символе. Хороший призыв к сохранению\n
, который не требуется.С, 146
источник
Haskell - 177 байт (без импорта)
(Извините за интернет-некромантию здесь.)
На платформе Haskell нет поиска строк без импорта, и я хотел показать и использовать тот факт, что искомые строки - это все подстроки одной (без повторений), так что группирование символов может быть выполнено путем определения пар, которым разрешено следовать друг за другом, что
f
здесь и происходит.Мне все еще нужен полный список
l
в конце, чтобы проверить на равенство и отобразить точно так, как требуется, но не будет, если бы задачей было только сообщить количество возможных случаевwords
в любом порядке.источник
Баш - 101
Передайте строку в качестве первого аргумента.
Объяснил немного:
источник
RS , 275 байт
Живая демоверсия и тесты.
Работа проста, но немного странна:
Это творчески использует группы, чтобы включить ввод, как:
в
Следующая строка:
Это заменяет последовательности заглавных букв на подчеркивания.
Это просто вставляет знак фунта в начале строки.
Это начало крутой части. Он в основном берет последовательности строчных букв и подчеркиваний, преобразует их в заглавные буквы, группирует их и помещает перед фунтом, который был вставлен. Целью фунта является управление последовательностями, которые уже были обработаны.
Фунт повторно вставляется в начале строки.
Заглавные буквы заменяются их текстовыми эквивалентами с соответствующими значениями. Из-за ошибки в rs (я не хотел рисковать, исправляя ее и получая дисквалификацию), пустые последовательности конвертируются в
(^^)
, что заменяется на 0 в строке от второй до последней. Самая последняя строка просто удаляет фунт.источник
KDB (Q), 76 байт
объяснение
Тест
источник
Haskell: 244 байта
источник
p
иs
только один раз, поэтому нет необходимости давать ему имя (->a#[]=[]:a#"NBM"
, то же самое дляp
). Кстати:words"N B M NB BM NBM"
вместо списка строк сохраняются дополнительные байты. Этоimport
только потомуintercalate
, что короче, т. Е. Заново внедри его:...putStrLn.tail.((' ':)=<<)$map...
и избавься отimport
. Поместите всех охранников|
в определении#
в одну строку и используйте1<2
вместоTrue
:...#(b:m)|a==b=...l#m|1<2=[]...
...?
может быть определена короче со списком понимания:c?t=sum[1|x<-c,x==t]
. Опять же , вы используете?
только один раз, так что используйте тело непосредственно:...show(sum[1|x<-l#[],x==t])
.