Для заданной строки из N, S, E и W выведите направление (угол по часовой стрелке от севера в градусах) с точностью до 5 десятичных знаков.
В традиционных обозначениях компаса строка состоит только из 2 из этих символов (например, NNW или ESE). Здесь вы также должны принять строки, которые содержат все 4 (например, WNNNSE) . Использование только 2 символов позволяет людям интуитивно понять смысл. Разрешение 4 символов делает чтение ужасным, но позволяет использовать более короткие способы описания направления с заданной точностью.
(Как указано в комментариях пользователя user2357112 , оказывается, что вы можете доказать, что для любого данного подшипника строка из 4 символов будет точно такой же длины, что и строка из 2 символов, поэтому я основал эту проблему на ложном предположении. Надеюсь, это отсутствие практической цели не умаляет вашего удовольствия от вызова ...)
Точный метод описан ниже и эквивалентен традиционной записи (он расширяет ее, а не изменяет).
вход
- Ввод представляет собой одну строку, содержащую только символы
NESW
. - Ввод может быть последовательностью символов, если вы предпочитаете, при условии, что это не включает какую-либо предварительную обработку. Например, использование вложенного списка
[N, [E, [S, [W]]]]
для определения порядка обработки не допускается. - Взятие разных персонажей не допускается. Вы не можете взять строку
1234
вместоNESW
.
Выход
- Выходными данными должно быть десятичное число или строковое представление единицы (не рациональное / дробь).
- Конечные нули отображать не нужно. Если подшипник есть
9.00000
, то результат9
также считается правильным до 5 десятичных знаков. - Выход находится в диапазоне [0, 360). То есть, включая 0, но исключая 360.
- Корректность проверяется путем округления вывода до 5 десятичных знаков. Если подшипник 0,000005, округляется до 0,00001. Выходы 0.00001 и 0.000005 являются правильными.
- Вывод в научной записи для некоторых входов является приемлемым. Например,
1e-5
вместо0.00001
.
преобразование
- Единичный символ компас точки
N
,E
,S
иW
соответствуют 0, 90, 180 и 270 градусов соответственно. - Добавление одного из них к строке приводит к тому, что подшипник делит пополам подшипник одиночного символа и подшипник исходной строки.
- Выбирается ближайший из двух возможных биссектрис, так что NE представляет 45 градусов, а не 225 градусов.
- Это однозначно, за исключением случаев, когда угол деления пополам составляет 180 градусов. Поэтому
NS
,SN
,WE
иEW
соответствуют неопределенным подшипникам, а вход никогда не закончатся ни в одном из них. Однако они могут появляться где-либо еще во входной строке, так как это не вызывает двусмысленности. - Если последние два символа идентичны, последний символ будет избыточным, так как бисекция возвратит тот же самый символ. Поскольку это ничего не добавляет к нотации, ваш код не должен обрабатывать это. Поэтому
NN
,EE
,SS
иWW
соответствуют неопределенным подшипникам, а вход никогда не закончатся ни в одном из них. Однако они могут появляться где-либо еще во входной строке.
Примеры
N: 0
E: 90
S: 180
SE: halfway between S and E: 135
NSE: halfway between N and SE: 67.5
NNSE: halfway between N and NSE: 33.75
NNNSE: halfway between N and NNSE: 16.875
NNNNSE: halfway between N and NNNSE: 8.4375
Контрольные примеры
Представление действительно только в том случае, если оно дает правильный вывод для всех тестовых случаев. Обратите внимание, что контрольные примеры расширяют границы того, что может быть обработано с двойной точностью. Для языков, которые по умолчанию имеют одинарную точность, вам, вероятно, потребуется потратить байты на указание двойной точности, чтобы получить правильные выходные данные.
Результаты тестового набора показаны округленными до 5 десятичных знаков, а также с произвольной точностью. Оба являются действительными выходами.
WNE 337.5 337.5
WEN 337.5 337.5
WEWEWEWEWEWEWEWEWEWEWEN 330.00001 330.000007152557373046875
NESWNESWNESWNESWNESWNESWNESW 90 89.99999932944774627685546875
NNNNNNNNNNNNNNNNNNNNNNNE 0.00001 0.0000107288360595703125
NNNNNNNNNNNNNNNNNNNNNNNW 359.99999 359.9999892711639404296875
SNNNNNNNNNNNNNNNNNNNNNNNE 90.00001 90.00000536441802978515625
SNNNNNNNNNNNNNNNNNNNNNNNW 269.99999 269.99999463558197021484375
счет
Это код-гольф . Оценка - это длина исходного кода в байтах, и кратчайшие выигрыши.
педантичность
Я сделал ошибку, думая, что «Север на северо-западе» является верным направлением компаса. Счастливая ошибка, так как она привела к сложной идее, но потом я обнаружил на странице Википедии :
«Название фильма Альфреда Хичкока 1959 года« Север на северо-западе »на самом деле не является точкой направления на 32-ветровом компасе, но Фильм содержит ссылку на Northwest Airlines. "
Также оказывается, что метод, использованный для этой задачи, совместим только с традиционными точками компаса вплоть до 16-точечного компаса. Компас с 32 ветрами, описанный на этой странице, немного отличается, и я удобно упустил из виду его существование для этой задачи.
Наконец, для тех, кто думает, что я должен использовать «Юго-восток» вместо «Юго-Восток»,,
WNNNSE
<= что будет выходом для этого примера записи в начале вашего сообщения? это звучит недействительно для меня, но трудно сказать.WNNNSE
будет вывод323.4375
. Посмотрите пример раздела для пошагового руководства, которое применимо таким же образом к этому случаю.f(N,N,N,S,E)
хорошо?Ответы:
JavaScript (ES6),
8480787472 байтаСохраненный байт благодаря @Titus, 1 благодаря @Neil
Это заняло некоторое время, но я думаю, что наконец-то усовершенствовал формулу ...
Тестовый фрагмент
Показать фрагмент кода
объяснение
Давайте начнем с самого простого случая: строки с одним символом. Результатом является просто его (0-индексированная) позиция в строке
NESW
, умноженная на 90.Для строки из двух символов результат находится на полпути между результатом первого символа и результатом второго. Однако есть одна загвоздка: если абсолютная разница между ними больше 180 (например,
NW
илиWN
), мы должны повернуть на 180 градусов, чтобы он не указывал противоположное направление.Для любой более длинной строки результат находится на полпути между результатом первого символа и результатом остальной части строки. Это можно обобщить следующим образом:
NESW
раз 90.NESW
умноженный на 45, плюс половину результата оставшейся части строки; добавить дополнительные 180, если абсолютная разница между ними больше 90.источник
search
вместо того,indexOf
чтобы сэкономить вам байт.C # 6,
226217207185 байтРедактировать: -10 байт путем «заимствования» идеи из представления ETHproductions
-22 байт благодаря @Titus
Ungolfed
источник
b=(b+360)%360;
вместоb+=b>360?-360:b<0?360:0;
. Сохраните еще 12 байтов, разделив все на 90 иreturn b*90;
.b=(b+f(c)+(b-f(c)>2?4:f(c)-b>2?-4:0)+8)/2%4;
затем распределите+8
по троичным результатамb=(b+f(c)+(b-f(c)>2?12:f(c)-b>2?4:8))/2%4;
PHP,
958886100127104101 байтN
(и больше, потому что это позволяет поместить перевод вN
заголовок цикла: верно, но оценивается0
в расчете.)strtr
одним из моих битов жонглированияЭто официально первый раз, когда я использую оператор объединения нулей. Беги с
-r
.PHP 7.1
Отрицательные смещения строк в следующей версии PHP сохранят 12 байтов:
заменить
strlen($s=$argv[1])
на0
и$s
на$argv[1]
.Бесплатные байты для (почти) каждого:
(a/2%6+2)%5
a<87?a/2&3^3:3
илиa/2&3^3*(a<87)
a&1?a&2|a/4&1:0
a/.8-1&3
источник
Python 3,
133113 байтовПросто улучшаю ответ @ L3viathan, потому что я только что создал этот аккаунт и поэтому пока не могу комментировать.
источник
05AB1E ,
48423732 байтаСохранено 6 байтов благодаря Emigna. Сохранено 5 байт благодаря идее Тита работать на диапазоне [0,4 [и умножить на 90 в конце. Сохранено 5 байт благодаря мастерству Аднана в древней метаморфозе xor / modulo.
Таким образом, каждый угол уменьшается от диапазона [0,360 [до диапазона [0,4] на протяжении всего выполнения. Результат затем умножается на 90 и отображается.
Попробуйте онлайн!
Потенциальные оси игры в гольф:
источник
NNNNNNNNNNNNNNNNNNNNNNNE
иSNNNNNNNNNNNNNNNNNNNNNNNE
тестовых случаях.v"NESW"yk90*})R¬U¦vXy+;DX-Ä89›180*+360%U}X
.89›
самом деле означает, что целочисленная часть больше 89, что эквивалентно тому, чтобы сказать, что полное число больше или равно 90 (что по-прежнему работает нормально, потому что точно 90 никогда не должно возникать). В настоящее время комментарий в объясненном коде звучит так, как будто он проверяет более 89, тогда как ваш код проходит тестовые случаи, поэтому он явно правильно проверяет более 90.›
должен вести себя к отрицательным значениям с плавающей запятой. Здесь нет проблем, так как он работает с абсолютным значением, но я предпочитаю не делать слишком строгих предположений в отношении оператора.v"NESW"yk})
наÇ30^5%
:)Python 3,
14614511710797949392 байтаПозвони
f
со строкой.источник
...0else
они бросают SyntaxErrors.else
и-
тоже? (можно в 3.3.3)d.find
может, у меня была точная идея минуту назад; см обновленный ответ.C 184 байта
Ungolfed
источник
d
)?R
172146 байтUngolfed
Разъяснения
c("N","E","S","W")
0:3*90
(вместоc(0,90,180,270)
)z
p
до степени, эквивалентной последнему символу на входеl
p
вz
Попробуйте тестовые случаи на R-fiddle (обратите внимание, что это функция из-за того, что она
scan
не работает на R-fiddle)источник
Outputs 0.00001 and 0.000005 are both correct.
так что вы должны быть в состоянии сохранить некоторые байты, не округляяc("N","N","E")
вместо"NNE"
? Это эквивалентно не вложенному списку Python["N","N","E"]
.Haskell,
109 105103 байтовСпасибо за -2 байта @xnor!
источник
f
выглядит долго, но мне сложно найти что-то более короткое. Ближайшим былf c=90*until(\i->"NESW"!!i==c)(+1)0
(35). Я думаю, что вы можете заменить'W'
на_
._
!Dyalog APL ,
554538 байтРешение
Требуется
⎕IO←0
, что по умолчанию во многих системах. Просит направление.объяснение
Обходит эту проблему путем преобразования каждой буквы в комплексное число 1∠ θ ⇔ a + b · i , затем выполняя уменьшение суммы справа налево (сильная сторона APL) при нормализации на каждом шаге. Окончательное значение θ затем преобразуется в градусы и нормализуется в пределах [0, 360):
'NES'⍳⍞
индексы каждой входной буквы в «NES»; N → 0, E → 1, S → 2, все остальное → 3○2÷⍨
преобразовать в углы в радианах; θ = π · x ∕ 2¯12○
преобразовать в комплексные числа на единичном круге; е я · θ(
...)/
уменьшить список с помощью ... (т.е. вставить функцию между элементами ...)+÷(|+)
... нормализованная сумма; x n - 1 + x n ∕ | х н - 1 + х н |12○
преобразовать в угол; θ÷○÷180×
конвертировать в градусы; 1 ∕ π · 1 ∕ 180 · x360|
остаток деления при делении на 360Попробуй APL онлайн!
Анекдот
Если бы вход и выход были как ортогональные комплексные единицы, все решение было бы просто:
Остальная часть кода анализирует ввод и форматирует вывод.
источник
⎕FR←1287
использует 128-битные числа с плавающей запятой, но TryAPL не позволяет этого.Common Lisp,
347327 байтСпасибо @Titus за то, что снял несколько
Это, вероятно, может быть больше в гольфе, но по крайней мере это работает (я думаю):
Использование:
Функция
d
принимает символN
,E
,W
илиS
и возвращает соответствующую степень. Функцияm
получает подходящую объединенную степень двух данных направлений. Функцияf
перебирает предоставленную строку, вычисляет соответствующую степень и печатает ее как число с плавающей запятой.источник
Befunge,
183181175 байтовПопробуйте онлайн!
объяснение
Это следует алгоритму, аналогичному многим другим ответам, только он использует вычисления с фиксированной запятой, эмулируемые целыми числами, так как Befunge не поддерживает с плавающей запятой.
Спасибо @Titus за процедуру ASCII-to-int.
источник
APL (Dyalog Classic) ,
3027 байтовПопробуйте онлайн!
источник