Apakah Anda baik tahun ini?

31

pengantar

Santa memiliki terlalu banyak nama untuk diproses, dan membutuhkan bantuan Anda! Dia membutuhkan Anda untuk menulis sebuah program atau fungsi, yang output nice, naughty, very naughtyatau very very naughty. Untuk menentukan seberapa bagus atau nakal seseorang, Santa telah mengembangkan suatu algoritma:

Nice ( , ):

Pertama-tama, kami mendapatkan nomor dari nama dengan menambahkan semua huruf ( spasi diabaikan ). Sebagai contoh:

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

Jika jumlah pembagi sama dengan panjang nama, orang tersebut dianggap nice. Ini berarti program Anda seharusnya menampilkan [name] has been nice. Di sini, pembagi 94adalah:

Divisors of 94: 1, 2, 47, 94

Ada 4pembagi, tetapi namanya memiliki panjang 8( termasuk spasi ). Kesimpulannya, Doorknobbelum baik. Jadi kami melanjutkan perjalanan kami:


Nakal ( , ):

Santa telah mengembangkan urutan baru, nomor natal . Pertama, kita akan melihat pohon natal berikut:

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

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

  5            18             47             98

Jumlah tanda bintang menentukan angka natal. Urutan berjalan seperti berikut: 5, 18, 47, 98, 177, ....

Dari sini, kita dapat menyimpulkan bahwa 94itu bukan angka natal. Itu artinya Doorknobbukan hanya nakal.


Sangat nakal ( ):

Untuk ini, kita perlu mengetahui apakah Doorknobadalah string yang membesarkan tangga . Hal ini ditentukan oleh huruf dalam nama dengan A = 1, B = 2, C = 3, dll .:

Pertama kita akan melihat huruf pertama, yaitu D. Ini memiliki nilai 4. Ini adalah titik awal kita. Surat selanjutnya adalah o. Ini memiliki nilai 15, yang lebih tinggi dari nilai kami sebelumnya, jadi kami akan melangkah lebih tinggi di tangga. Nilai selanjutnya juga merupakan o. Ini sama, jadi kami tidak melakukan apa pun. Jika nilai berikutnya lebih tinggi dari nilai saat ini, kami akan melangkah lebih tinggi. Jika nilai berikutnya lebih rendah dari nilai saat ini, kami akan turun lebih rendah. Jika sama, kami akan tetap pada langkah yang sama. Ini divisualisasikan untuk Doorknob, Martin Buttnerdan 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

Anda dapat melihat bahwa Doorknobberakhir lebih tinggi dari posisi awal. Jadi Doorknob has been very naughty. Martin Buttnerdan Alex Atidak lebih tinggi dari titik awal. Jadi mereka berdua very very naughty.

Uji kasus

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

Aturan

  • Anda perlu menyediakan program atau fungsi yang membutuhkan input (yang terdiri dari setidaknya satu huruf).
  • Input akan terdiri dari huruf besar , huruf kecil dan spasi . Spasi diabaikan selama proses, kecuali untuk panjang input.
  • Ini adalah , jadi pengiriman dengan jumlah byte paling sedikit menang!
Adnan
sumber
15
Btw, cara yang tepat untuk menulis Büttner tanpa umlaut adalah Buettner, bukan Buttner.
Dennis
3
Angka-angka Natal dihasilkan oleh n^3 + 2n^2 + 2, btw.
Lynn
2
Baiklah Maka "skor" maksimum untuk sebuah nama adalah ZZZ...Z = 26 * 99 = 2574, artinya Anda hanya perlu memeriksa angka Natal hingga dan termasuk n=13. (Info berguna untuk pegolf lain.)
Lynn
23
Santa has been very very naughty. Tunggu apa?
Gagang Pintu
5
@Doorknob冰- Anda tidak mendapatkan nama lengkapnya: Santa Claus has been very naughty. Haruskah juga mencoba Saint Nick, Saint Nicholas, St. Nick, St. Nicholas, Kris Kringle, Father Christmas, Pere Noel, dan semua alias lainnya - mungkin salah satu dari mereka akan bekerja? Meskipun mengapa seorang pria "baik" harus membutuhkan banyak alias sudah cukup mencurigakan ...
Darrel Hoffman

Jawaban:

5

Pyth 86 byte

Rupanya saya sudah baik tahun ini ...

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

Cobalah online: Demonstrasi atau Test Suite

Penjelasan:

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

CJam, 109 108 107 byte

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

Cobalah online.

Penjelasan

Penjelasan lengkap harus menunggu hingga nanti, tetapi ini kode yang dipecah menjadi beberapa bagian:

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
sumber
@RikerW Saya mencurinya dari komentar Doorknob.
Martin Ender
Saya memberi +1 komentarnya juga.
Rɪᴋᴇʀ
"Santa sudah sangat sangat nakal"
ASCIIThenANSI
4

MATL , 117 byte

Program MATL terlama saya sejauh ini :-) :-(

Menggunakan pelepasan bahasa saat ini, yang lebih awal dari tantangan ini.

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

Contohnya

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

Penjelasan

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

Lua, 371 284 byte

Saya yakin ada ruang untuk perbaikan, saya ingin memotong beberapa jika.

Sunting: 4 bulan kemudian, saya belajar banyak tentang lua dan ingin kembali ke kiriman ini, saya melakukannya dengan baik: memotong 87 byte!

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

Tidak disatukan

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"

Solusi 371 byte lama

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

Versi tidak dikoleksi :)

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

Serius, 138 byte

" 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

Cobalah secara Online

Sulit untuk golf secara efektif ini karena betapa sulitnya kontrol aliran yang rumit di Serius. Kemampuan untuk membuat fungsi sarang tanpa menggunakan register akan membantu. (Saya membayangkan ini sudah bisa dipersingkat melalui penggunaan fungsi tersimpan yang bijaksana, tetapi itu akan menghasilkan kode spageti sedemikian rupa sehingga saya tidak tega mencobanya.)

Penjelasan:

" 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
kuintopia
sumber
1

Python 2, 249 byte

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
sumber