Тебе было приятно в этом году?


31

Введение

У Санты слишком много имен для обработки, и ему нужна ваша помощь! Он нуждается в вас , чтобы написать программу или функцию, которая выводит nice, naughty, very naughtyили very very naughty. Чтобы определить, насколько он хорош или непослушен, Санта разработал алгоритм:

Ницца ( , ):

Прежде всего, мы получаем число из имени, добавляя все буквы вверх ( пробелы игнорируются ). Например:

Doorknob =

D = 4
o = 15
o = 15
r = 18
k = 11
n = 14
o = 15
b = 2

4 + 15 + 15 + 18 + 11 + 14 + 15 + 2 = 94

Если число делителей равно длине имени, человек считается nice. Это означает, что ваша программа должна выводить [name] has been nice. Здесь делителями 94являются:

Divisors of 94: 1, 2, 47, 94

Есть 4делители, но имя имеет длину 8( пробелы включены ). Вывод, Doorknobне было приятно. Итак, продолжаем наше путешествие:


Непослушный ( , ):

Санта разработал новую последовательность, рождественский номер . Сначала рассмотрим следующие елки:

n = 1        n = 2          n = 3          n = 4

                                             *
                                            ***
                                           *****
                                          *******
                                         *********
                          _   *             ***
                         |   ***           *****
                         |  *****         *******
               *         | *******       *********
  *           ***        |   ***            ***
 ***         *****   n*n |  *****          *****
  *           ***        | *******        *******
             *****       |   ***         *********
               *         |  *****           ***
                         |_*******         *****
                              *           *******
                           |_____|       *********
                             2n+1            *

  5            18             47             98

Количество звездочек определяет рождественский номер. Последовательность идет следующим образом : 5, 18, 47, 98, 177, ....

Отсюда можно сделать вывод, что 94это не рождественский номер. Это значит, что Doorknobон не просто был непослушным.


Очень непослушный ( ):

Для этого нам нужно выяснить, Doorknobесть ли строка подъемной лестницы . Это определяется буквами в названии с A = 1, B = 2, C = 3и т.д .:

Сначала мы посмотрим на первую букву D. Это имеет значение 4. Это наша отправная точка. Следующее письмо o. Это имеет значение 15, которое выше, чем наше предыдущее значение, поэтому мы идем на шаг выше по лестнице. Следующее значение также является o. Это то же самое, поэтому мы ничего не делаем. Если следующее значение выше текущего значения, мы пойдем на шаг выше. Если следующее значение будет ниже текущего, мы пойдем ниже. Если это так, мы останемся на том же шаге. Это визуализируется Doorknob, Martin Buttnerи Alex A:

            O
           / \
      R   N   B
     / \ /
  O-O   K                 T   N   U                 L   X
 /                       / \ / \ / \               / \ / \
D                   M   R   I   B   T-T           A   E   A
                     \ /               \
                      A                 N   R
                                         \ /
                                          E

Вы можете видеть, что Doorknobзакончилось выше, чем стартовая позиция. Так Doorknob has been very naughty. Martin Buttnerи Alex Aне стал выше, чем отправная точка. Так они оба very very naughty.

Контрольные примеры

Input: Doorknob
Output: Doorknob has been very naughty

Input: Martin Buttner
Output: Martin Buttner has been very very naughty

Input: Jakube
Output: Jakube has been nice

Input: B
Output: B has been very very naughty

правила

  • Вам необходимо предоставить программу или функцию, которая принимает данные (которые состоят как минимум из одной буквы).
  • Ввод будет состоять из прописных букв , строчных букв и пробелов . Пробелы в процессе игнорируются, за исключением длины ввода.
  • Это , поэтому выигрывает представление с наименьшим количеством байтов!

15
Кстати, правильный способ написать Бюттнер без умлаута - это Бюттнер, а не Баттнер.
Деннис

3
Рождественские номера генерируются n^3 + 2n^2 + 2, кстати.
Линн

2
Alrighty. Тогда максимальная «оценка» для имени будет ZZZ...Z = 26 * 99 = 2574означать, что вам нужно проверять только рождественские номера вплоть до n=13. (Полезная информация для других игроков в гольф.)
Линн

23
Santa has been very very naughty, Чего ждать?
Дверная ручка

5
@Doorknob冰- Вы не получили его полное имя: Santa Claus has been very naughty. Стоит также попробовать Святого Ника, Святого Николая, Святого Ника, Святого Николая, Криса Крингла, Деда Мороза, Пере Ноэля и всех других его псевдонимов - может быть, один из них подойдет? Хотя почему «хорошему» парню нужно так много псевдонимов, уже довольно подозрительно…
Даррел Хоффман

Ответы:


5

Pyth 86 байт

Видимо, я был хорош в этом году ...

jd[z"has been"?qlzl{yPJsKxL+NG@Grz0"nice"+*"very "&!}Jm+*+2d*dd2SJhgs._M-VKtK0"naughty

Попробуйте онлайн: демонстрация или тестовый набор

Объяснение:

jd[z"has been"...      list with input string, "has been" and ...; join with spaces
qlzl{yPJsKxL+NG@Grz0   compares the length of input with the number of divisors
                       (computes all prime factors and counts the elements in the powerset)
?..."nice"             if True, use "nice" as last list element
                       else:
}Jm+*+2d*dd2SJ            check for christmas number
                          (checks, if its of the form n^3+2*n^2+2)
gs._M-VKtK0               check if raising ladder string ends lower or equal
                          (assigns each neighbor pair a number -1,0,1 and computes the sum)
&!...h...                 returns 0, 1 or 2
*"very "                  repeat "very " this times
+..."naughty              add "naughty" and use this as the third list element

10

CJam, 109 108 107 байт

l" has been "1$[_,\S-:eu'@f-:A:+__,:)f%0e=@=\_{)__2+**))}%&A2ew::-:g1b0<]{}#4,="very "*_5>\"naughty""nice"?

Попробуйте онлайн.

объяснение

Полное объяснение придется подождать позже, но вот код, разбитый на различные разделы:

l" has been "1$[                    e# Some preparation...
  _,\S-:eu'@f-:A:+                  e# Determine letter sum.
  __,:)f%0e=@=                      e# Check divisor count.
  \_{)__2+**))}%&                   e# Check for Christmas number.
  A2ew::-:g1b0<                     e# Check ladder.
]{}#4,="very "*_5>\"naughty""nice"? e# Determine nice/naughtiness.

@RikerW Я украл это из комментария Doorknob.
Мартин Эндер

Я + 1 и его комментарий тоже.
Rɪᴋᴇʀ

«Санта был очень очень непослушным»
ASCIIThenANSI

4

MATL , 117 байт

Моя самая длинная программа MATL до сих пор :-) :-(

Использует текущий выпуск языка, который является более ранним, чем этот вызов.

jttk96-t0>)tstt:\~s4$bn=?xx'nice'}[1,2,0,2]99:ZQ=a?'naughty'}dt0>sw0<s-O>~'very naughty'w?'very 'wh]]]' has been 'whh

Примеры

>> matl
 > jttk96-t0>)tstt:\~s4$bn=?xx'nice'}[1,2,0,2]99:ZQ=a?'naughty'}dt0>sw0<s-O>~'very naughty'w?'very 'wh]]]' has been 'whh
 > 
> Doorknob
Doorknob has been very naughty

>> matl
 > jttk96-t0>)tstt:\~s4$bn=?xx'nice'}[1,2,0,2]99:ZQ=a?'naughty'}dt0>sw0<s-O>~'very naughty'w?'very 'wh]]]' has been 'whh
 > 
> Jakube
Jakube has been nice

объяснение

jt                        % input string. Duplicate
tk96-t0>)                 % duplicate. Convert to lower, then to numbers, remove spaces
ts                        % duplicate. Sum
tt:                       % duplicate. Vector from 1 to obtained sum
\~s                       % modulus operation. Count zeros to determine number of divisors
4$bn=                     % does it equal original name length?
?                         % if so
    xx'nice'              % remove values not needed, and push string
}                         % else
    [1,2,0,2]99:ZQ        % all Christmas numbers
    =a                    % does sum equal any Christmas number?
    ?                     % if so
        'naughty'         % push string
    }                     % else
        dt0>s             % total number of increases
        w0<s              % total number of decreases
        -O>~              % subtract both. Is total <=0?
        'very naughty'w   % push string, which will be needed in either case. Swap
        ?                 % if total was <=0
            'very 'wh     % prepend string
        ]                 % end if
    ]                     % end if
]                         % end if
' has been 'whh           % build complete string from pushed parts

2

Lua, 371 284 байта

Я уверен, что есть возможности для улучшения, я хотел бы вырезать некоторые, если.

Редактировать: 4 месяца спустя, я много узнал о Луа и хотел вернуться к этому представлению, я справился хорошо: вырезал 87 байтов!

a=... .." has been "s=(...):lower()b="very "x=0y=s:byte(1)-96z=0r="naughty"for i=2,#s
do c=s:byte(i)y=c+y-96z=z+c<s:byte(i-1)and-1or 1 end
for i=1,y do x=y%i<1 and x+1or x end
for i=1,13 do d=y==i^3+2*i^2+2 and 0or d end
print(a..(x==#s and"nice"or(d and""or b..(z>0 and""or b))..r))

Ungolfed

a=... .." has been "           -- Start of the sentence
s=(...):lower()                -- convert the input to lower case
b="very "                      
x=0                            -- y's divisor count
y=s:byte(1)-96                 -- will contain the sum of the char's position in the alphabet
z=0                            -- will contain the raising ladder state
r="naughty"                    

for i=2,#s                     -- iterate over each character in s
do
  c=s:byte(i)                  -- shorthand for the byte value of the current char
  y=c+y-96                     -- increment the sum of letter's positions
  z=z+c<s:byte(i-1)            -- if the previous char is greater than the current
        and-1                  -- the ladder goes down
      or 1                     -- else, it goes up
end

for i=1,y                      -- iterate on the range 1..y
do
  x=y%i<1                      -- if i is a divisor of y
      and x+1                  -- increment x
    or x
end

for i=1,13                     -- iterate on the range 1..13
do                             -- no need to go further for the christmas numbers
  d=y==i^3+2*i^2+2             -- if y is a christmas number
      and 0                    -- set d
    or d                       -- else let d as it is
end
print(a..                      -- output "Name has been"
      (x==#s                   -- if y's divisor==length of input
        and"nice"              -- append "nice"
      or(d                     -- else, if d is not set
          and""                
        or b..                 -- append "very"
          (z>0                 -- and if the raising ladder doesn't raise
             and""
          or b))..             -- append a second "very"
        r))                    -- append "naughty"

Старое 371 байтовое решение

function f(s)a,b,c,d,e,r,g,s=s.." has been ","very ",0,0,0,"naughty",math.pow,s:lower()for i=1,#s 
do if 32<s:byte(i)then e,d=i>1 and(s:byte(i)<s:byte(i-1)and e-1 or e+1)or e,d-96+s:byte(i)end end
for i=1,d do c=d%i>0 and c or c+1 end if c==#s then return a.."nice"end 
for i=1,13 do if g(i,3)+2*g(i,2)+2==d then return a..r end end
return e>0 and a..b..r or a..b..b..r end

Беззвучная версия :)

function f(s)
  a,b,c,d,e,r,g,s=s.." has been ","very ",0,0,0,"naughty",math.pow,s:lower()
  for i=1,#s
  do
    if 32<s:byte(i)
    then
      --sum of the char's order in the alphabet
      d=d-96+s:byte(i)
      --raising ladder
      e=i>1 and(s:byte(i)<s:byte(i-1)and e-1 or e+1)or e
    end
  end
  for i=1,d
  do
    -- number of d's divisors
    c=d%i>0 and c or c+1
  end
  if c==#s then return a.."nice" end
  for i=1,13
  do
    --Christmas number are equals n^3+2n^2+2 as @Mauris said 
    if g(i,3)+2*g(i,2)+2==d then return a..r end
  end
  --is he very naughty or very very naughty?
  return e>0 and a..b..r or a..b..b..r 
end

1

Серьезно, 138 байт

" has been ",;' @-û╗+╝╜`O8ª@-`MΣ;2┐w`iXu`Mπ╜l=`"nice"╛+.éó`╬é03┐2└3╤1x`;;⌐**⌐`MíuY3└+3┐╜Ok0)p)`p;(@)-s@)+(`╬l>Y(Xu3└*"naughty"@"very "*+╛+

Шестнадцатеричный дамп:

2220686173206265656e20222c3b2720402d96bb2bbcbd604f38a6402d604de43b32bf7760695875604de3bd6c3d60226e69636522be2b2e82a260ce823033bf32c033d13178603b33405e29a6e7326be4604da1755933c02b33bfbd4f6b3029702960703b2840292d7340292b2860ce6c3e5928587533c02a226e6175676874792240227665727920222a2bbe2b

Попробуйте онлайн

Трудно эффективно сыграть в эту игру из-за сложности и сложности управления потоком. Помогает возможность вложения функций без использования регистров. (Я полагаю, что это уже может быть несколько сокращено за счет разумного использования хранимых функций, но это приведет к такому коду спагетти, что у меня не хватит смелости попробовать это).

Объяснение:

" has been "                                  push this string
,                                             read input
;' @-û╗                                       copy, remove space, uppercase, put in reg0
+╝                                            put '<input> has been ' in reg1
╜                                             bring back the processed input
`O8ª@-`MΣ                                     convert letters to numbers and sum
;2┐                                           store a copy of the sum in reg2
w`iXu`Mπ                                      compute the number of divisors
╜l                                            get processed input length
=                                             check if they're equal
`"nice"╛+.éó`╬                                if so, run this function that retrieves the 
                                              list we made earlier, appends "nice",
                                              prints it, empties the stack
                                              and immediately exits
é                                             empty the stack (it contains a 1)
03┐                                           put a 0 in reg3
2└                                            call back the letter sum from reg2
3╤1x                                          push [1,...1000]
`;;⌐**⌐`M                                     plug each number into x^3+2x^2+2
í                                             check if the letter sum is there
uY                                            make a 1 if it is not, 0 if it is
3└+3┐                                         add this number to reg3
╜Ok                                           convert the processed input into char codes
0)                                            put a zero behind it
p)                                            pop the first char code to bottom of stack
`p;(@)-s@)+(`╬                                Until the list of char codes is empty,
                                              subtract each one from the previous one,
                                              accumulating the signums
l                                             turn the leftover empty list into a 0
>Y                                            put a 1 if the accumulated signs are
                                              >=0 (not rising), else 0 (rising)
(X                                            clean up the last char code
u                                             increment to make 0 into 1 and 1 into 2
3└*                                           bring back the value from reg3
                                              which is 0 if *only* naughty, else 1
                                              and multiply it with preceding test result;
                                              this turns a very into a very very if this
                                              test failed, but leaves plain and single
                                              very naughty alone
"naughty"@                                    put "naughty" below the 'very' count

"very "*                                      put "", "very ", or "very very "
+                                             append the "naughty"
╛+                                            bring back the string in reg1 and append
                                              the constructed suffix

1

Python 2, 249 байт

i=input()
g=[ord(c)-96for c in i.lower()if' '!=c]
s=sum(g)
S=0
a=g.pop()
while g:b=a;a=g.pop();S+=(a<b)-(b<a)
r=range(1,14+s)
print i+' has been '+[['very '*(1+(S<1)),''][s in[x**3+2*x**2+2for x in r]]+'naughty','nice'][sum(s%x<1for x in r)==len(i)]
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.