Código Golfinator-3000

22

Como todo mundo sabe , adicionar inator-3000ao final de qualquer substantivo torna o caminho mais legal. Mas o que mais pode tornar uma palavra mais legal?

Dada uma string ASCII como entrada, produza a frescura da palavra.

Cálculo da frieza

Existem 4 elementos para calcular a frescura de uma palavra.

  • A palavra em si. A pontuação base é o número de letras maiúsculas multiplicado por 1000
  • O número final. Um número no final da palavra (como o burninator- 3000 ) é adicionado à pontuação base, mas se o número tiver mais de 4 dígitos, eles estarão gananciosos e o número deverá ser ignorado.
  • O conector. Um espaço antes do número final adiciona 1000, enquanto um hífen adiciona 2000, qualquer outro símbolo ou nenhum símbolo não tem efeito.
  • O sufixo. Se a palavra terminar ator, duplique a pontuação final. Se terminar inator, triplique a pontuação. Estes não diferenciam maiúsculas de minúsculas.

Por exemplo, Burninator-3000pode ser calculado da seguinte forma:

1 Capital letter - Base Score: 1000
(1000(base) + 3000(number) + 2000(hyphen)) * 3(suffix) = 18000

Casos de teste

Burninator-3000 -> 18000
Burnator3000 -> 8000
BurNinator 100 -> 9300
BuRnInAtOr-7253 -> 42759
burn -> 0
burn- -> 0
bUrn-1 -> 3001
inator-7 -> 6021
ator 56 -> 2112
burninators 1000 -> 2000
burn_1000 -> 1000
BURNINATOR-9999 -> 65997
burninator 99999 -> 3000
burninator_99999 -> 0
Code Golfinator-3000 -> 21000
inator ator hello world-1000 -> 3000
javaiscool_99999 -> 0
hypen-ated -> 0
1000 -> 1000
-1000 -> 3000
10000 -> 0
-10000 -> 2000
BURN1N470R-3000 -> 11000

Pontuação

Isso é , e o menor número de bytes em cada idioma vence!

Skidsdev
fonte
3
Caso de teste: inator ator hello world-1000(ou semelhante) #
TheLethalCoder 14/07
@TheLethalCoder Adicionado
Skidsdev 14/07/2017
@ Mr.Xcoder não tenho certeza que ele cobre que já não tenha sido coberta, mas é engraçado, então eu vou adicioná-lo de qualquer maneira
Skidsdev
Ok, agora um caso útil teste: 9028e -7282(somente dígitos)
Mr. Xcoder
1
Não é burninator 99999de 3000 não 1000? O espaço adiciona 1000 e triplicou por terminar no inator.
TheLethalCoder

Respostas:

13

JavaScript (ES6), 138 133 128 bytes

s=>(([,a,b,,c,d]=s.match(/((in)?ator)?((\D?)(\d+))?$/i),s.split(/[A-Z]/).length-1+(c=='-'?2:c==' '))*1e3+(d<1e4&&+d))*(b?3:2-!a)

Quão?

O número de letras maiúsculas é dado por:

s.split(/[A-Z]/).length - 1

Todos os outros critérios são deduzidos do resultado da seguinte expressão regular, dividida em 4 variáveis:

/((in)?ator)?((\D?)(\d+))?$/i     criterion  | code                    | outcome
 \_________/  \___/\___/          -----------+-------------------------+----------
      a         c    d            end number | d < 1e4 && +d           | 0 or +d
  \___/                           connector  | c == '-' ? 2 : c == ' ' | 0, 1 or 2
    b                             suffix     | * (b ? 3 : 2 - !a)      | 1, 2 or 3

Casos de teste

Arnauld
fonte
7

Baunilha C, 447 bytes

(Embrulhado para facilitar a leitura)

#include<stdio.h>
int main(int c,char**a){char*v=a[1];while(*v++);int m=0,i=
0,bn=0,s=0,b=0,mul=1;char l[256],*lp=l;v--;while(a[1]<v--)
{if(!m){i=!i?1:(i*10),('0'<=*v&&*v<='9')?(bn=bn+i*(*v-'0')
):m++;}if(m==1){(*v=='-'||*v==' ')?(s+=bn?((*v=='-')?2000:
1000):0,v--):0,m++;}if(m==2){(*v>='A'&&*v<='Z')?(s+=1000,*
v+=32):0,*lp++=*v;}}s+=(bn<10000)?bn:0;for(i=0;i<lp-l;i++)
{if(*(l+i)=="rotani"[i]){mul=(i==5)?3:((i==3)?2:mul);}}s*=
mul;printf("%d\n",s);}

... ou até ... sexta-feira!

(Não usei nenhuma ferramenta para aliar o código. Na verdade, tenho muita sorte de ter escolhido as larguras de coluna corretas, sem pré-cálculos. E até compila!)

Baunilha C, 789 bytes

#include<stdio.h>
int main(int c,     char**a){char       *v=a[1];while      (*v++);int m=0,i=
        0,bn=0,     s=0,     b=0,       mul=1   ;char      l[256],    *lp=l;
          v--;      while  (a[1]<       v--)    {if(!      m){i=!i    ?1:(i*
          10),      ('0'   <=*v&&       *v<=    '9')?      (bn=bn+    i*(*v-
'0')):m++;}if(      m==1)  {(*v==       '-'||    *v==      ' ')?(s    +=bn?(
(*v=='-')?2000      :1000) :0,v--       ):0,m    ++;}      if(m==2     ){(*v
       >='A'&&      *v<=    'Z')?       (s+=    1000,      *v+=32)    :0,*lp
          ++=*      v;}}s  +=(bn<       10000   )?bn:      0;for(i     =0;i<
         lp-l;      i++){  if(*(l       +i)==   "rot"      "ani"[i]   ){mul=
(i==5) ?3: ((i      ==3)?2:mul);}       } s *= mul;        printf("%d\n",s);}

Código original:

#include <stdio.h>
#include <math.h>

int main(int argc, char** argv) {
    char *v = argv[1];
    while(*v++);
    int m=0,i=-1;
    int bonus_number=0;
    int score=0;
    int b=0;
    int mul=1;
    char letters[256];
    char* lp=letters;
    v--;
    while(argv[1]<v--) {
        printf(" * %c %x\n", *v, *v);
        if (m == 0) {
            if ('0'<=*v&&*v<='9') {
                bonus_number=bonus_number+powl(10,++i)*(*v-'0');
                printf("Digit, bonus is now %d\n", bonus_number);
            } else {
                m++;
            }
        }
        if (m == 1) {
            if (*v=='-'||*v==' ') {
                printf("Dash/space\n");
                if (bonus_number) score += (*v=='-') ? 2000 : 1000;
                v--;
            }
            m++;
        }
        if (m == 2) {
            if(*v>='A'&&*v<='Z') {
                printf("Upper letter\n");
                score += 1000;
                *v += 32;
            }
            *lp++ = *v;
        }
    }
    score += (bonus_number<10000)?bonus_number:0;
    for(i=0;i<lp-letters;i++) {
        // printf("%d: %c\n\n", i, *(letters+i));
        if (*(letters+i) == "rotani"[i]) {
            if (i == 3) {
                printf("2x!\n");
                mul = 2;
            }
            if (i == 5) {
                printf("3x!\n");
                mul = 3;
            }
        }
    }
    score *= mul;
    printf("Score: \n%d\n", score);
}

Após a 1ª minimização:

#include <stdio.h>

int main(int c, char** a) {
    char *v = a[1];while(*v++);
    int m=0,i=0,bn=0,s=0,b=0,mul=1;
    char l[256],*lp=l;
    v--;
    while(a[1]<v--) {
        if (!m) {
            i=!i?1:(i*10),
            ('0'<=*v&&*v<='9') ? (bn=bn+i*(*v-'0')) : m++;
        }
        if (m == 1) {
            (*v=='-'||*v==' ') ? (s += bn ? ((*v=='-') ? 2000 : 1000) : 0, v--):0,m++;
        }
        if (m == 2) {
            (*v>='A'&&*v<='Z') ? (s += 1000, *v += 32):0,
            *lp++ = *v;
        }
    }
    s += (bn<10000)?bn:0;
    for(i=0;i<lp-l;i++) {
        if (*(l+i) == "rotani"[i]) {
            mul=(i==5)?3:((i==3)?2:mul);
        }
    }
    s *= mul;
    printf("%d\n", s);
}

Casos de teste

#!/usr/bin/env python3
import subprocess

TESTCASES = '''
Burninator-3000 -> 18000
Burnator3000 -> 8000
BurNinator 100 -> 9300
BuRnInAtOr-7253 -> 42759
burn -> 0
burn- -> 0
bUrn-1 -> 3001
inator-7 -> 6021
ator 56 -> 2112
burninators 1000 -> 2000
burn_1000 -> 1000
BURNINATOR-9999 -> 65997
burninator 99999 -> 3000
burninator_99999 -> 0
Code Golfinator-3000 -> 21000
inator ator hello world-1000 -> 3000
javaiscool_99999 -> 0
hypen-ated -> 0
1000 -> 1000
-1000 -> 3000
10000 -> 0
-10000 -> 2000
BURN1N470R-3000 -> 11000
'''

TESTCASES = dict(map(lambda x: x.split(' -> '), filter(None, TESTCASES.split('\n'))))


def process(arg):
    return subprocess.Popen(['./a.out', arg], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0].strip().split(b'\n')[-1].decode('utf-8')


for key, value in TESTCASES.items():
    assert value == process(key), '"{}" should yield {}, but got {}'.format(
        key, value, process(key)
    )
Andrew Dunai
fonte
2

C #, 322 317 bytes

namespace System.Linq{s=>{var m=Text.RegularExpressions.Regex.Match(s,"(.*?)([- ])?(\\d+)$");string t=m.Groups[1].Value.ToLower(),c=m.Groups[2].Value,n=m.Groups[3].Value;return(s.Count(char.IsUpper)*1000+(n.Length>4|n==""?0:int.Parse(n))+(c==" "?1000:c=="-"?2000:0))*(t.EndsWith("inator")?3:t.EndsWith("ator")?2:1);}}

Experimente online!

Versão completa / formatada:

namespace System.Linq
{
    class P
    {
        static void Main()
        {
            Func<string, int> f = s =>
            {
                var m = Text.RegularExpressions.Regex.Match(s, "(.*?)([- ])?(\\d+)$");
                string t = m.Groups[1].Value.ToLower(), c = m.Groups[2].Value, n = m.Groups[3].Value;

                return (
                           s.Count(char.IsUpper) * 1000 +
                           (n.Length > 4 | n == "" ? 0 : int.Parse(n)) +
                           (c == " " ? 1000 : c == "-" ? 2000 : 0)
                        )
                        * (t.EndsWith("inator") ? 3 : t.EndsWith("ator") ? 2 : 1);
            };

            string[] testCases =
            {
                "Burninator-3000", "Burnator3000", "BurNinator 100", "BuRnInAtOr-7253",
                "burn", "burn-", "bUrn-1", "inator-7", "ator 56", "burninators 1000",
                "burn_1000", "BURNINATOR-9999", "burninator 99999", "burninator_99999",
                "Code Golfinator-3000", "inator ator hello world-1000", "javaiscool_99999",
                "hypen-ated", "1000", "-1000", "10000", "-10000"
            };

            foreach (string testCase in testCases)
            {
                Console.WriteLine($"{testCase} -> {f(testCase)}");
            }

            Console.ReadLine();
        }
    }
}

Dividir a regex em seu próprio método agora é de 4 bytes mais (a menos que eu tenha perdido alguma coisa) devido à permissão de apenas um lambda. Isso vem em 321 bytes:

namespace System.Linq{string m(string s,int n)=>Text.RegularExpressions.Regex.Match(s,"(.*?)([- ])?(\\d+)$").Groups[1].Value.ToLower();s=>{string t=m(s,1),c=m(s,2),n=m(s,3);return(s.Count(char.IsUpper)*1000+(n.Length>4|n==""?0: int.Parse(n))+(c==" "?1000:c=="-"?2000:0))*(t.EndsWith("inator")?3:t.EndsWith("ator")?2:1);}}
TheLethalCoder
fonte
Não sei se isso é legal depois do último meta post, mas você acredita que é. Outra função como essa não b=c=>d=>c.Groups[d].Valueeconomizaria um pouco?
LiefdeWen
@LiefdeWen Após o último meta post, acredito que teria que declará-lo como um método completo. Eu poderia fazer string m(string s,int n)=>Text.RegularExpressions.Regex.Match(s,"(.*?)([- ])?(\\d+)$").Groups[n].Value.ToLower();string t=m(s,1),c=m(s,2),n=m(s,3);Mas acredito que, em seguida, torna 3 bytes a mais.
TheLethalCoder
2

Perl, 108 bytes

Código de 107 bytes + 1 para -p.

$\+=1e3*y/A-Z//;s/( |-)?(\d+)$//;$\+=$2*($2<1e4);$\+={$",1e3,"-",2e3}->{$1};s/(in)?ator$//i&&($\*=$1?3:2)}{

Experimente online!

Dom Hastings
fonte
0

PHP> = 7.1, 165 bytes

preg_match("#((in)?ator)?((\D)?(\d+))?$#i",$argn,$m);[,$a,$i,,$c,$d]=$m;echo($d*($d<1e4)+(preg_match_all("#[A-Z]#",$argn)+($c!="-"?$c==" "?:0:2))*1e3)*($a?$i?3:2:1);

Casos de teste

Jörg Hülsermann
fonte