Warst du dieses Jahr nett?

31

Einführung

Der Weihnachtsmann hat zu viele Namen, um sie zu verarbeiten, und braucht Ihre Hilfe! Er braucht Sie ein Programm oder eine Funktion zu schreiben , die ausgibt nice, naughty, very naughtyoder very very naughty. Um festzustellen, wie nett oder frech jemand ist, hatte der Weihnachtsmann einen Algorithmus entwickelt:

Nizza ( , ):

Zunächst erhalten wir aus dem Namen eine Zahl, indem wir alle Buchstaben addieren ( Leerzeichen werden ignoriert ). Beispielsweise:

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

Wenn die Anzahl der Teiler der Länge des Namens entspricht, wird die Person berücksichtigt nice. Dies bedeutet, dass Ihr Programm ausgeben sollte [name] has been nice. Hier sind die Teiler von 94:

Divisors of 94: 1, 2, 47, 94

Es gibt 4Teiler, aber der Name hat Länge 8( einschließlich Leerzeichen ). Fazit, Doorknobwar nicht nett. Also setzen wir unsere Reise fort:


Frech ( , ):

Der Weihnachtsmann hat eine neue Sequenz entwickelt, die Weihnachtsnummer . Zuerst schauen wir uns die folgenden Weihnachtsbäume an:

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

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

  5            18             47             98

Die Anzahl der Sterne bestimmt die Weihnachtszahl. Die Sequenz geht wie folgt: 5, 18, 47, 98, 177, ....

Hieraus können wir schließen, dass 94es sich nicht um eine Weihnachtszahl handelt. Das heißt, das Doorknobwar nicht nur ungezogen.


Sehr frech ( ):

Dazu müssen wir herausfinden, ob Doorknobes sich um eine Raise-Ladder-Saite handelt . Dies wird durch die Buchstaben im Namen bestimmt mit A = 1, B = 2, C = 3, etc .:

Zuerst schauen wir uns den ersten Buchstaben an, den D. Das hat Wert 4. Dies ist unser Ausgangspunkt. Der nächste Buchstabe ist o. Dies hat den Wert 15, der höher ist als unser vorheriger Wert, also gehen wir einen Schritt höher auf der Leiter. Der nächste Wert ist ebenfalls ein o. Das ist das gleiche, also tun wir nichts. Ist der nächste Wert höher als der aktuelle Wert, gehen wir einen Schritt höher. Wenn der nächste Wert niedriger als der aktuelle Wert ist, werden wir einen Ster niedriger gehen. Wenn es dasselbe ist, bleiben wir auf dem gleichen Schritt. Diese visualisiert für Doorknob, Martin Buttnerund 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

Sie können sehen, dass Doorknobdas höher als die Startposition endete. Also Doorknob has been very naughty. Martin Buttnerund Alex Anicht höher als der Ausgangspunkt. Sie sind also beide very very naughty.

Testfälle

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

Regeln

  • Sie müssen ein Programm oder eine Funktion bereitstellen, die Eingaben akzeptiert (die aus mindestens einem Buchstaben bestehen).
  • Die Eingabe besteht aus Großbuchstaben , Kleinbuchstaben und Leerzeichen . Leerzeichen werden während des Vorgangs mit Ausnahme der Länge der Eingabe ignoriert.
  • Das ist , also gewinnt die Einsendung mit der geringsten Anzahl von Bytes!
Adnan
quelle
15
Übrigens ist die richtige Art, Büttner ohne Umlaut zu schreiben, Büttner, nicht Büttner.
Dennis
3
Die Weihnachtszahlen werden n^3 + 2n^2 + 2übrigens von generiert.
Lynn
2
Alles klar. Dann ist die maximale "Punktzahl" für einen Namen ZZZ...Z = 26 * 99 = 2574, was bedeutet, dass Sie nur Weihnachtsnummern bis einschließlich überprüfen müssen n=13. (Nützliche Informationen für andere Golfer.)
Lynn
23
Santa has been very very naughty. Warte was?
Türklinke
5
@Doorknob冰- Du hast nicht seinen vollen Namen bekommen: Santa Claus has been very naughty. Sollten Sie auch den Heiligen Nick, den Heiligen Nikolaus, den Heiligen Nick, den Heiligen Nikolaus, Kris Kringle, den Weihnachtsmann, Pere Noel und all seine anderen Pseudonyme probieren - vielleicht funktioniert einer von ihnen? Obwohl, warum ein "netter" Kerl so viele Aliase brauchen sollte, ist schon ziemlich verdächtig ...
Darrel Hoffman

Antworten:

5

Pyth 86 Bytes

Anscheinend war ich dieses Jahr nett ...

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

Probieren Sie es online aus: Demo oder Test Suite

Erläuterung:

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

CJam, 109 108 107 Bytes

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

Probieren Sie es online aus.

Erläuterung

Eine vollständige Erklärung muss bis später warten, aber hier ist der Code in die verschiedenen Abschnitte unterteilt:

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
quelle
@RikerW Das habe ich aus Doorknobs Kommentar gestohlen.
Martin Ender
Ich + 1'und sein Kommentar auch.
20.
"Der
Weihnachtsmann
4

MATL , 117 Bytes

Mein bisher längstes MATL-Programm :-) :-(

Verwendet die aktuelle Version der Sprache, die älter als diese Herausforderung ist.

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

Beispiele

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

Erläuterung

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

Lua, 371 284 Bytes

Ich bin mir sicher, dass es Raum für Verbesserungen gibt. Ich würde gerne ein paar Wenns herausschneiden.

Edit: 4 Monate später habe ich viel über Lua gelernt und wollte auf diesen Beitrag zurückkommen, das habe ich gut gemacht: 87 Bytes rausgeschnitten!

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"

Alte 371-Byte-Lösung

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

Ungolfed version :)

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

Im Ernst, 138 Bytes

" 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

Probieren Sie es online

Es ist schwierig, dies effektiv zu golfen, da die komplizierte Flusskontrolle im Ernstfall schwierig ist. Die Fähigkeit, Funktionen ohne die Verwendung von Registern zu verschachteln, würde helfen. (Ich stelle mir vor, dass dies durch den umsichtigen Einsatz gespeicherter Funktionen bereits etwas verkürzt werden könnte, aber es würde zu einem solchen Spaghetti-Code führen, für den ich nicht den Mut habe, es zu versuchen.)

Erläuterung:

" 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
Quintopie
quelle
1

Python 2, 249 Bytes

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
quelle