Avez-vous été sympa cette année?

31

introduction

Le Père Noël a trop de noms à traiter et a besoin de votre aide! Il a besoin d'écrire un programme ou d' une fonction, qui délivre en sortie nice, naughty, very naughtyou very very naughty. Pour déterminer à quel point quelqu'un est gentil ou méchant, le Père Noël avait développé un algorithme:

Nice ( , ):

Tout d'abord, nous obtenons un nombre du nom en additionnant toutes les lettres ( espaces ignorés ). Par exemple:

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

Si le nombre de diviseurs est égal à la longueur du nom, la personne est considérée nice. Cela signifie que votre programme devrait sortir [name] has been nice. Ici, les diviseurs de 94sont:

Divisors of 94: 1, 2, 47, 94

Il existe des 4diviseurs, mais le nom a une longueur 8( espaces compris ). Conclusion, ça Doorknobn'a pas été sympa. Nous continuons donc notre voyage:


Coquine ( , ):

Le Père Noël a développé une nouvelle séquence, le numéro de Noël . Tout d'abord, nous examinerons les arbres de Noël suivants:

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

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

  5            18             47             98

Le nombre d'astérisques détermine le nombre de Noël. La séquence se déroule comme suit: 5, 18, 47, 98, 177, ....

De là, nous pouvons conclure que ce 94n'est pas un numéro de Noël. Cela signifie que cela Doorknobn'a pas seulement été méchant.


Très vilain ( ):

Pour cela, nous devons savoir s'il Doorknobs'agit d'une chaîne d'échelle élévatrice . Ceci est déterminé par les lettres du nom avec A = 1, B = 2, C = 3, etc .:

Nous allons d'abord regarder la première lettre, la D. Cela a de la valeur 4. Ceci est notre point de départ. La prochaine lettre est o. Cela a la valeur 15, qui est supérieure à notre valeur précédente, nous allons donc un peu plus haut sur l'échelle. La valeur suivante est également un o. C'est la même chose, donc nous ne faisons rien. Si la valeur suivante est supérieure à la valeur actuelle, nous irons plus haut. Si la valeur suivante est inférieure à la valeur actuelle, nous irons plus bas. Si c'est pareil, nous resterons sur la même marche. Ceci visualisé pour Doorknob, Martin Buttneret 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

Vous pouvez voir que cela Doorknobs'est terminé plus haut que la position de départ. Donc Doorknob has been very naughty. Martin Buttneret Alex An'a pas dépassé le point de départ. Ils sont donc tous les deux very very naughty.

Cas de test

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

Règles

  • Vous devez fournir un programme ou une fonction qui prend en entrée (qui se compose d'au moins une lettre).
  • L'entrée se compose de lettres majuscules , lettres minuscules et les espaces . Les espaces sont ignorés pendant le processus, à l'exception de la longueur de l'entrée.
  • C'est du , donc la soumission avec le moins d'octets gagne!
Adnan
la source
15
Btw, la bonne façon d'écrire Büttner sans tréma est Buettner, pas Buttner.
Dennis
3
Les numéros de Noël sont générés par n^3 + 2n^2 + 2, btw.
Lynn
2
Très bien. Ensuite, le «score» maximum pour un nom est ZZZ...Z = 26 * 99 = 2574, ce qui signifie que vous n'avez qu'à vérifier les numéros de Noël jusqu'à et y compris n=13. (Informations utiles pour les autres golfeurs.)
Lynn
23
Santa has been very very naughty. Attends quoi?
Poignée de porte
5
@Doorknob冰- Vous n'avez pas son nom complet: Santa Claus has been very naughty. Devrait également essayer Saint Nick, Saint Nicholas, St. Nick, St. Nicholas, Kris Kringle, Father Christmas, Pere Noel et tous ses autres pseudonymes - peut-être que l'un d'eux fonctionnera? Mais pourquoi un "gentil" gars aurait besoin de tant d'alias est déjà assez suspect ...
Darrel Hoffman

Réponses:

5

Pyth 86 octets

Apparemment, j'ai été sympa cette année ...

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

Essayez-le en ligne: démonstration ou suite de tests

Explication:

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
la source
10

CJAM, 109 108 107 octets

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

Essayez-le en ligne.

Explication

Une explication complète devra attendre plus tard, mais voici le code décomposé en différentes sections:

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
la source
@RikerW J'ai volé ça dans le commentaire de Doorknob.
Martin Ender
Je + 1'nd son commentaire aussi.
Rɪᴋᴇʀ
"Le Père Noël a été très très méchant"
ASCIIThenANSI
4

MATL , 117 octets

Mon plus long programme MATL jusqu'à présent :-) :-(

Utilise la version actuelle de la langue, antérieure à ce défi.

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

Exemples

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

Explication

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
la source
2

Lua, 371 284 octets

Je suis sûr qu'il y a place à amélioration, j'aimerais en supprimer quelques-uns.

Edit: 4 mois plus tard, j'ai beaucoup appris sur lua et je voulais revenir sur cette soumission, j'ai bien fait: coupé 87 octets!

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"

Ancienne solution de 371 octets

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

Version non golfée :)

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
la source
1

Sérieusement, 138 octets

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

Vidage hexadécimal:

2220686173206265656e20222c3b2720402d96bb2bbcbd604f38a6402d604de43b32bf7760695875604de3bd6c3d60226e69636522be2b2e82a260ce823033bf32c033d13178603b33405e29a6e7326be4604da1755933c02b33bfbd4f6b3029702960703b2840292d7340292b2860ce6c3e5928587533c02a226e6175676874792240227665727920222a2bbe2b

Essayez-le en ligne

Il est difficile de jouer efficacement au golf en raison de la difficulté du contrôle de débit complexe. La possibilité d'imbriquer des fonctions sans utiliser de registres serait utile. (J'imagine que cela pourrait déjà être quelque peu raccourci grâce à une utilisation judicieuse des fonctions stockées, mais il en résulterait un tel code de spaghetti que je n'ai pas le cœur de tenter.)

Explication:

" 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
la source
1

Python 2, 249 octets

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