Determine a "sorte" de uma string

35

Dada uma string, retorne a "sorte" da string.

A sorte de uma string, como acabei de compensar para o objetivo desse desafio, é um número inteiro, assim determinado:

  • A sorte base de uma string é 1.
  • Para cada letra consecutiva compartilhada com a palavra "sorte" (sem distinção entre maiúsculas e minúsculas), multiplique a sorte por 2. Por exemplo, se sua sequência for " lu mberjack" ou "sma ck ", você multiplicará por 4. (Mais especificamente, 2 ^ número de caracteres consecutivos compartilhados.)
    • As letras compartilhadas devem estar na mesma ordem consecutiva que aparecem em "sortudo", mas podem começar em qualquer lugar da palavra pelo mesmo valor ("luc" tem o mesmo multiplicador de 8 * que "cky").
    • Se a palavra tiver várias ocorrências em que compartilha caracteres consecutivos com sorte, use a sequência consecutiva mais longa dos caracteres.
  • Para qualquer letra, ele compartilha com a palavra "presságio" subtrai 2 da sorte.
    • Pode corresponder a um personagem qualquer quantidade de vezes, em qualquer ordem. Por exemplo, a cadeia "nnnnnomemenn" perde 24 sorte (12 letras correspondentes)

Exemplo:

luck("lucky")
>>32

2 ^ 5 (5 letras consecutivas) = ​​32

luck("firetruck")
>>6

2 ^ 3 - 2 (3 letras consecutivas de uck , e compartilhadas com presságio)

luck("memes")
>>-7

1 - 8 (valor base, 4 compartilhados com "presságio")

Isso é código de golfe, então a resposta com o menor número de bytes vence.

Você pode inserir e enviar da maneira que desejar - escrever uma função, usar entrada padrão etc.

Para funções, assuma o tipo de dados que faria sentido para esse idioma. (Por exemplo, em JavaScript, você receberia um Stringe retornaria a Number)

Editar: você pode assumir que qualquer entrada é minúscula.

charredgrass
fonte
8
Bom primeiro desafio!
8288 Alex A. Alex
2
O programa deve aceitar entrada em maiúsculas?
busukxuan
2
@busukxuan Boa pergunta - não, ele não precisa aceitar entradas em maiúsculas.
charredgrass
@cat Não tenho certeza se entendi bem o que você está perguntando. Mas você pode simplesmente assumir que todas as entradas serão minúsculas e não precisará capturar nenhuma entrada em maiúscula.
charredgrass
11
Podemos assumir um limite superior ou inferior para a sorte de uma determinada entrada? ou seja, qual é o menor número de bits / tipo de dados com o qual posso me safar ou é tão grande quanto meu idioma pode suportar? isto é, deveria ser int8_t str_luck(const char* str);ou deveria ser uint64_t str_luck(const char* str);?
cat

Respostas:

7

05AB1E , 36 32 28 26 bytes

Œv'¸éyåiyˆ}}¯é¤go¹'ƒÖ¦Ãg·-

Explicação

Œv         }                  # for each substring of input
  '¸éyåi  }                   # if substring is part of "lucky"
        yˆ                    # add it to global array
            ¯é¤               # get the longest such substring
               go             # raise 2 to its length
                 ¹'ƒÖ¦Ã       # remove all chars from input that isn't in "omen"
                       g·     # get length and multiply by 2
                         -    # subtract
                              # implicitly display

Experimente online

Economizou 2 bytes graças a Adnan

Emigna
fonte
A compactação para 1 palavra também pode ser feita com ', portanto, para 26: Œv'¸éyåiyˆ}}¯é¤go¹'ƒÖ¦Ãg·-:).
Adnan
@Adnan: Estranho. Eu tinha certeza de que tinha tentado isso. Aparentemente não. Obrigado!
Emigna
por que essa não é a resposta principal?
noɥʇʎԀʎzɐɹƆ
7

JavaScript (ES7), 123 112 107 bytes

s=>2**[5,4,3,2,1,0].find((i,_,a)=>a.some(j=>s.includes("luckyL".substr(j,i))))-2*~-s.split(/[omen]/).length

Editar: salvou 11 bytes graças ao @Titus assumindo que a letra Lnão aparece na entrada. Economizou 5 bytes graças a @Oriol. Versão ES6 para 125 114 109 bytes:

f=
s=>(1<<[5,4,3,2,1,0].find((i,_,a)=>a.some(j=>s.includes("luckyL".substr(j,i)))))-2*~-s.split(/[omen]/).length
;
<input oninput=o.textContent=f(this.value)><pre id=o></pre>

Neil
fonte
Por que você usa em replace([^])vez de match([])? Você desperdiça 3 bytes ou existe um motivo?
Titus
@Titus Quantos bytes custa para lidar com um nullresultado de correspondência?
Neil
11
Quatro para uma corda e um par de ()neste caso; comendo todos os seis com os quais você salvaria match(/[omen]/). Pena.
Titus
11
@Titus Não tenho certeza se foi isso que você quis dizer, mas adicionando um Lfinal ao substr (que nunca aparecerá na string original), não preciso me preocupar com correspondências estranhas e, na verdade, posso usar a mesma matriz as [5,4,3,2,1,0]duas vezes, economizando uns 13 bytes impressionantes!
Neil
11
-2*s.split(/[omen]/).length+2é mais curto.
Oriol
6

Pitão, 27 26 28 bytes

-^2le+k}#"lucky".:Q)yl@"omen

1 byte salvo graças a OP :-)

Explicação:

                                 Implicit Q as input
                .:Q              Find all substrings of input
     +k}#"lucky"                 Filter for substring of "lucky", prepend "" in case of []
    e                            Take last element, which is longest
   l                             Get its length
 ^2                              Raise two to that
                      @"omen"Q   Filter Q for characters in "omen"
                     l           Get length; counts how many characters in "omen" there are
                    y            Double that
-                                Find the difference

Teste aqui .

busukxuan
fonte
11
Eu não sou um especialista em Pyth mas eu acredito que você pode alterar "omen"para apenas "omene Pyth vai entender
charredgrass
@charredgrass Opa, meu erro :-)
busukxuan
11
Parece não funcionar para string sem caracteres de "sorte" nela. "memes" por exemplo.
Emigna
11
@Emigna Ah. o caso zero novamente .... Obrigado, consertou!
11786 Buschxuan
6

Ruby, 91 87 bytes

String#counto uso finnicky de greve novamente! (Quando transmitida uma String, ela conta todas as ocorrências de cada letra no argumento da função, em vez de todas as ocorrências de toda a string.)

Experimente online

->s{2**(z=0..5).max_by{|j|z.map{|i|s[b="lucky"[i,j]]?b.size: 0}.max}-2*s.count("omen")}

Uma versão que pega linhas do STDIN e as imprime: 89 bytes (86 +3 do -nsinalizador)

p 2**(z=0..5).max_by{|j|z.map{|i|$_[b="lucky"[i,j]]?b.size: 0}.max}-2*$_.count("omen")
Value Ink
fonte
11
._. isso String#counté estranho. +1 para (ab) usá-lo. Também é mais curto usar getsdo que uma função?
Downgoat 08/07/19
11
@ Downgoat se eu getstambém tiver que putssair, então não neste caso.
Value Ink
4

Ruby: 100 bytes

->s{2**(m=0;4.times{|j|1.upto(5){|i|m=[i,m].max if s.match"lucky"[j,i]}};m)-s.scan(/[omen]/).size*2}
Addison
fonte
Tente /[omen]/usar o regex para jogar golfe - ele corresponderá a qualquer caractere e é melhor em uso prático do que encadear |s para caracteres únicos.
charredgrass
3

Javascript - 206 bytes

r=>{var a="lucky";r:for(var e=5;e>0;e--)for(var n=0;6>n+e;n++){var o=a.substring(n,e+n);if(r.includes(o))break r}for(var t=0,e=0;e<r.length;e++)('omen'.indexOf(r[e])+1)&&t++;return Math.pow(2,o.length)-2*t}
Christopher Burgdorff
fonte
11
Você poderia mudar esta condição: s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n'para se parecer com esta:"oman".split("").includes(s[k])
Addison
11
Bem-vindo ao PPCG! Você pode resolver isso removendo o espaço em branco para economizar bytes. Além disso, em vez de (s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n')você poderia usar ('omen'.indexOf(s[k])+1)(assumindo que este é JavaScript)
charredgrass
Obrigado pelas dicas! Chegou a 237, embora pareça que o público do Ruby me fez vencer.
Christopher Burgdorff
Outra pequena coisa: você pode taquigrafia function luck(r)para baixo a r=>apenas torná-lo uma função anônima, isso é tudo que é necessário para este desafio. Também fiz uma edição para o desafio para que você não precisa se preocupar sobre o caso para que você possa remover or=r.toLowerCase();
charredgrass
Em vez de substringvocê pode usar sliceeu acredito (testar isso, porém, como eu não tenho certeza)
Downgoat
3

Ruby, 57 bytes

b=gets.count'omen'
$.+=1while/[lucky]{#$.}/
p 2**$./2-2*b

getsé definido $.como 1 como efeito colateral, e o incrementamos até que a expressão regular que corresponde a $.caracteres da sorte consecutivos não corresponda mais.

histocrata
fonte
3

Haskell, 99

Outra abordagem ... Acabei de aprender sobre o alias de função

import Data.List
s=subsequences
i=intersect
l=length
f n=2^(l$last$i(s"lucky")$s n)-2*l(i n$"omen")

Uso

f"lucky"
32

f"firetruck"
6

f"memes"
-7
Zylviij
fonte
2

Mathematica, 86 bytes

Código:

2^StringLength@LongestCommonSubsequence[#,"lucky"]-2StringCount[#,{"o","m","e","n"}]&

Explicação:

LongestCommonSubsequenceretorna a substring contígua mais longa comum à entrada e "lucky". StringLengthdá o seu comprimento. StringCountconta o número de ocorrências dos caracteres de "omen"na entrada.


fonte
2

Python (139 bytes)

import itertools as t
s=input()
print 2**max([j-i for i,j in t.combinations(range(6),2)if'lucky'[i:j]in s]+[0])-2*sum(_ in'omen'for _ in s)
jmilloy
fonte
Você pode salvar um byte usandofrom intertools import*
wnnmaw
1

TSQL, 233 bytes

Golfe:

DECLARE @t varchar(99)='oluck'

,@z INT=0,@a INT=0,@ INT=1,@c INT=0WHILE @a<LEN(@t)SELECT
@a+=IIF(@=1,1,0),@z=IIF('LUCKY'LIKE'%'+x+'%'and @>@z,@,@z),@c+=IIF(x
IN('O','M','E','N'),2,0),@=IIF(@+@a-1=LEN(@t),1,@+1)FROM(SELECT
SUBSTRING(@t,@a,@)x)x PRINT POWER(2,@z)-@c

Ungolfed:

DECLARE @t varchar(99)='oluck'

,@z INT=0
,@a INT=0
,@  INT=1
,@c INT=0
WHILE @a<LEN(@t)
  SELECT
    @a+=IIF(@=1,1,0),
    @z=IIF('LUCKY'LIKE'%'+x+'%'and @>@z,@,@z),
    @c+=IIF(x IN('O','M','E','N'),2,0),
    @=IIF(@+@a-1=LEN(@t),1,@+1)
    FROM(SELECT SUBSTRING(@t,@a,@)x)x
PRINT POWER(2,@z)-@c

Experimente online

t-clausen.dk
fonte
1

Haskell ( 134133 bytes)

import Data.List
c[]=[]
c s@(_:x)=inits s++c x
l=length
g q=2^(maximum$map(\z->l q-l(q\\z))$c"lucky")-2*(l$intersect q"omen")

Não é um jogador de código nem um programador Haskell, por isso adoraria algumas dicas sobre este.

(Exemplo: g "firetruck")

ForemanBob
fonte
Também não sou especialista em Haskell, mas consegui resolver alguns problemas alterando um pouco o algoritmo e usando aliases de função em funções reutilizadas.
Zylviij
1

Python 3, 168 157 152 139 144 136 bytes

Edição: Coisas realmente óbvias que eu deveria ter visto mais fácil foram alteradas, e algumas um pouco menos óbvias.

Edit 2: stoopid (˚n˚). O programa gerou erros. Eu consertei isso. na verdade não 153 :(

Agradecimentos a Leaky Nun por salvar 5 bytes e a jmilloy por salvar 13 8 bytes.

s=input()
p=q=k=len(s)
m=0
while-~p:
 while-~q:m=(m,q-p)[(s[p:q]in"lucky")*q-p>m];q-=1
 p-=1;q=k
print(2**m-2*sum(i in"omen"for i in s))

O programa percorre todas as possíveis substrings possíveis na entrada (possivelmente possível, porque calcula também substrings impossíveis, 8 a 7, por exemplo), verifica se a substring está em "lucky" e depois define o expoente 2 para o comprimento de a substring deve ser maior que o valor atual. Possivelmente poderia ser melhorado usando apenas um loop while. Poderia usar alguma melhoria; Eu ainda estou pegando o jeito disso.

Limão destrutível
fonte
while p+1tornawhile-~p
Leaky Nun
desde b=s[p:q], len(b)deve estar q-pcerto?
Leaky Nun
Eu roubei o método de entrada e impressão, mas fiz o resto muito diferente, obrigado! Eu acho que se você fizer print(2**m-2*sum(i in"omen" for i in s))nas últimas três linhas, fará melhor, como o 148?
21416 jolloy #
Ah, e você pode simplesmente mover s [p: q] para a cláusula if while-~q:n=q-p;m=n if(s[p:q]in"lucky")*n>m else m;q-=1 para 143?
21416 jilloy
sum(map(s.count,"omen"))economiza um byte, tornando-o 135
Black Owl Kai
1

Programa PHP, 139 135 108 bytes

o salto quântico falha em várias substrings em que a primeira ocorrência é mais curta. :(

na verdade, eu poderia salvar outros 7 bytes no PHP <5.4 com register_globals em

<?for($s=$argv[1];$i<5;$i++)for($j=6;--$j;)$r=max($r,strstr($s,substr('lucky*',$i,$j))?2**$j:1);echo$r-2*preg_match_all('/[omen]/',$s);

uso: php -d error_reporting=0 <filename> <string>

+5 para uma função:

function f($s){for(;$i<5;$i++)for($j=6;--$j;)$r=max($r,strstr($s,substr('lucky*',$i,$j))?2**$j:1);return$r-2*preg_match_all('/[omen]/',$s);}

testes (na função)

echo '<table border=1><tr><th>input</th><th>output</th><th>expected</th><th>ok?</th></tr>';
foreach([
    'lumberjack'=>0,        'smack'=>2,
    'nnnnnomemenn'=>-23,    'lucky'=>32,
    'omen'=>-7,             'firetruck'=>6,
    'memes'=>-7,            'determine the “luck” of a string'=>0,
    'amazing'=>-3,          'wicked'=>2,
    'chucky'=>16,           'uckyuke'=>14,
    'ugly'=>2,              'lucy'=>8,
    'lukelucky'=>30
] as $x=>$e){
    $y=f($x);
    echo"$h<tr><td>",$x,'</td><td>',$y,'</td><td>',$e,'</td><td>',$e==$y?'Y':'N',"</td></tr>";
}echo '</table>';
Titus
fonte
0

Scala, 155 bytes

def f(w:String)=(1::List.fill((for(a<-1 to 5;s<-"lucky".sliding(a))yield if(w.contains(s)) a else 0).max){2}).product-2*w.filter("omen".contains(_)).length
melach
fonte