Вам було приємно в цьому році?


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. Це те саме, тому ми нічого не робимо. Якщо наступне значення вище поточного значення, ми підемо на крок вище. Якщо наступне значення нижче поточного значення, ми підемо на ster нижче. Якщо це те саме, ми залишимося на тому ж кроці. Це візуалізується 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, btw.
Лінн

2
Добре. Тоді максимальний "бал" для імені - це 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

Луа, 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))

Безумовно

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.