Czy byłeś miły w tym roku?

31

Wprowadzenie

Święty Mikołaj ma zbyt wiele nazw do przetworzenia i potrzebuje twojej pomocy! On potrzebuje napisać program lub funkcję, która wyprowadza nice, naughty, very naughtylub very very naughty. Aby określić, jak ktoś jest miły lub niegrzeczny, Mikołaj opracował algorytm:

Nicea ( , ):

Przede wszystkim otrzymujemy liczbę od nazwy, dodając wszystkie litery w górę ( spacje są ignorowane ). Na przykład:

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

Jeśli liczba dzielników jest równa długości nazwiska, osoba jest brana pod uwagę nice. Oznacza to, że Twój program powinien generować dane wyjściowe [name] has been nice. Oto dzielniki 94:

Divisors of 94: 1, 2, 47, 94

Istnieją 4dzielniki, ale nazwa ma długość 8(ze spacjami ). Wniosek, Doorknobnie był miły. Kontynuujemy naszą podróż:


Niegrzeczny ( , ):

Święty Mikołaj opracował nową sekwencję, numer świąteczny . Najpierw przyjrzymy się następującym choinkom:

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

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

  5            18             47             98

Ilość gwiazdek określa numer świąteczny. Sekwencja idzie w następujący sposób: 5, 18, 47, 98, 177, ....

Stąd możemy stwierdzić, że 94nie jest to numer świąteczny. Oznacza to, że Doorknobnie tylko było niegrzeczne.


Bardzo niegrzeczny ( ):

W tym celu musimy dowiedzieć się, czy Doorknobjest to ciąg drabiny podnoszącej . To zależy od liter w nazwie z A = 1, B = 2, C = 3itp .:

Najpierw przyjrzymy się pierwszym piśmie D. To ma wartość 4. To jest nasz punkt wyjścia. Następny list to o. Ma wartość 15wyższą niż nasza poprzednia, więc idziemy o krok wyżej na drabinie. Następna wartość to również o. To jest to samo, więc nic nie robimy. Jeśli następna wartość jest wyższa niż wartość bieżąca, pójdziemy o krok wyżej. Jeśli następna wartość jest niższa niż bieżąca wartość, pójdziemy znacznie niżej. Jeśli będzie tak samo, pozostaniemy na tym samym kroku. Ten wizualizowane za Doorknob, Martin Buttneri 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

Widać, że Doorknobzakończyło się wyżej niż pozycja początkowa. Tak Doorknob has been very naughty. Martin Buttneri Alex Anie przekroczył punktu początkowego. Więc są oboje very very naughty.

Przypadki testowe

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

Zasady

  • Musisz podać program lub funkcję, która pobiera dane wejściowe (które składają się z co najmniej jednej litery).
  • Dane wejściowe będą składały się z wielkich liter , małych liter i spacji . Spacje są ignorowane podczas procesu, z wyjątkiem długości danych wejściowych.
  • To jest , więc wygrywanie z najmniejszą ilością bajtów wygrywa!
Adnan
źródło
15
Btw, właściwym sposobem na pisanie Büttnera bez umlaut jest Buettner, a nie Buttner.
Dennis,
3
Numery świąteczne są generowane przez n^3 + 2n^2 + 2, btw.
Lynn,
2
Wporządku. Zatem maksymalny „wynik” dla imienia to ZZZ...Z = 26 * 99 = 2574, co oznacza, że ​​wystarczy sprawdzić numery świąteczne aż do włącznie n=13. (Przydatne informacje dla innych golfistów.)
Lynn,
23
Santa has been very very naughty. Czekaj, co?
Klamka
5
@Doorknob冰- Nie uzyskać jego pełną nazwę: Santa Claus has been very naughty. Czy warto też wypróbować Świętego Nicka, Świętego Mikołaja, Świętego Mikołaja, Świętego Mikołaja, Krisa Kringle, Ojca Bożego Narodzenia, Pere Noela i wszystkich innych pseudonimów - może jeden z nich zadziała? Chociaż to, dlaczego „miły” facet potrzebuje tak wielu pseudonimów, jest już dość podejrzane ...
Darrel Hoffman,

Odpowiedzi:

5

Pyth 86 bajtów

Najwyraźniej byłem miły w tym roku ...

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

Wypróbuj online: pakiet demonstracyjny lub testowy

Wyjaśnienie:

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
Jakube
źródło
10

CJam, 109 108 107 bajtów

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

Wypróbuj online.

Wyjaśnienie

Pełne wyjaśnienie będzie musiało poczekać do później, ale oto kod podzielony na różne sekcje:

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.
Martin Ender
źródło
@RikerW Ukradłem to z komentarza Doorknob.
Martin Ender,
Ja też daję +1 i jego komentarz.
Rɪᴋᴇʀ
„Święty Mikołaj był bardzo bardzo niegrzeczny”
ASCIIThenANSI,
4

MATL , 117 bajtów

Mój najdłuższy jak dotąd program MATL :-) :-(

Wykorzystuje bieżącą wersję języka, która jest wcześniejsza niż to wyzwanie.

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

Przykłady

>> 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

Wyjaśnienie

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
Luis Mendo
źródło
2

Lua, 371 284 bajtów

Jestem pewien, że jest miejsce na ulepszenia, chciałbym trochę wyciąć, jeśli jest.

Edycja: 4 miesiące później wiele się nauczyłem o lua i chciałem wrócić do tego zgłoszenia, zrobiłem dobrze: wyciąłem 87 bajtów!

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))

Bez golfa

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"

Stare rozwiązanie 371 bajtów

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

Wersja bez golfa :)

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
Katenkyo
źródło
1

Poważnie, 138 bajtów

" 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 "*+╛+

Hex Dump:

2220686173206265656e20222c3b2720402d96bb2bbcbd604f38a6402d604de43b32bf7760695875604de3bd6c3d60226e69636522be2b2e82a260ce823033bf32c033d13178603b33405e29a6e7326be4604da1755933c02b33bfbd4f6b3029702960703b2840292d7340292b2860ce6c3e5928587533c02a226e6175676874792240227665727920222a2bbe2b

Wypróbuj online

Trudno jest skutecznie grać w golfa ze względu na to, jak trudna jest skomplikowana kontrola przepływu w serialu. Pomogłaby możliwość zagnieżdżania funkcji bez użycia rejestrów. (Wyobrażam sobie, że można to już nieco skrócić poprzez rozsądne użycie przechowywanych funkcji, ale spowodowałoby to taki kod spaghetti, że nie mam serca tego spróbować).

Wyjaśnienie:

" 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
kwintopia
źródło
1

Python 2, 249 bajtów

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)]
TFeld
źródło