Determinar la "Suerte" de una cadena

35

Dada una cadena, devuelve la "suerte" de esa cadena.

La suerte de una cadena, como acabo de inventar con el propósito de este desafío, es un número entero, determinado de esta manera:

  • La suerte base para una cadena es 1.
  • Para cada letra consecutiva que comparte con la palabra "suerte" (no distingue entre mayúsculas y minúsculas), multiplique la suerte por 2. Por ejemplo, si su cadena era " lu mberjack" o "sma ck ", multiplicaría por 4. (Más específicamente, 2 ^ número de caracteres consecutivos compartidos)
    • Las letras compartidas deben estar en el mismo orden consecutivo que aparece en "suerte", pero pueden comenzar en cualquier parte de la palabra por el mismo valor ("luc" tiene el mismo multiplicador 8 * que "cky").
    • Si la palabra tiene múltiples ocurrencias donde comparte caracteres consecutivos con lucky, use la cadena consecutiva más larga de los caracteres.
  • Para CUALQUIER letra que comparta con la palabra "presagio", reste 2 de la suerte.
    • Puede coincidir con un personaje cualquier cantidad de veces, en cualquier orden. Por ejemplo, la cadena "nnnnnomemenn" pierde 24 suerte (12 letras coincidentes)

Ejemplo:

luck("lucky")
>>32

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

luck("firetruck")
>>6

2 ^ 3 - 2 (3 letras consecutivas de uck , e compartidas con presagio)

luck("memes")
>>-7

1 - 8 (cantidad base, 4 compartidos con "presagio")

Este es el código de golf, por lo que gana la respuesta con la menor cantidad de bytes.

Puede ingresar y emitir de la forma que desee: escriba una función, use la entrada estándar, etc.

Para las funciones, suponga que cualquier tipo de datos tendría sentido para ese idioma. (Por ejemplo, en JavaScript, se le pasará ay Stringdevolverá a Number)

Editar: puede suponer que cualquier entrada es minúscula.

hierba carbonizada
fuente
8
¡Buen primer desafío!
Alex A.
2
¿Debería el programa aceptar entradas en mayúsculas?
busukxuan
2
@busukxuan Buena pregunta: no, no necesita aceptar mayúsculas.
charredgrass
@cat No estoy seguro de entender lo que estás preguntando. Pero puede suponer que todas las entradas estarán en minúsculas y no necesita captar ninguna entrada en mayúsculas.
charredgrass
1
¿Podemos suponer un límite superior o inferior en la suerte de una entrada dada? es decir, ¿cuál es el número más pequeño de bits / tipo de datos que puedo usar, o es tan grande como puede manejar mi idioma? es decir, ¿debería ser int8_t str_luck(const char* str);o debería ser uint64_t str_luck(const char* str);?
gato

Respuestas:

7

05AB1E , 36 32 28 26 bytes

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

Explicación

Œ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

Pruébalo en línea

Guardado 2 bytes gracias a Adnan

Emigna
fuente
La compresión para 1 palabra también se puede hacer ', así que para 26: Œv'¸éyåiyˆ}}¯é¤go¹'ƒÖ¦Ãg·-:).
Adnan
@Adnan: raro. Estaba seguro de haberlo intentado. Aparentemente no. ¡Gracias!
Emigna
¿Por qué no es esta la mejor respuesta?
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: Guardado 11 bytes gracias a @Titus al suponer que la letra Lno aparece en la entrada. Guardado 5 bytes gracias a @Oriol. Versión 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
fuente
¿Por qué usas en replace([^])lugar de match([])? ¿Pierdes 3 bytes o hay alguna razón?
Titus
@Titus ¿Cuántos bytes cuesta lidiar con un nullresultado de coincidencia?
Neil
1
Cuatro para una cuerda y un par de ()en este caso; comiendo los seis con los que ahorrarías match(/[omen]/). Lástima.
Titus
1
@Titus No estoy seguro de si eso es lo que quiso decir, pero al agregar un Lal final del substr (que nunca aparecerá en la cadena original) no tengo que preocuparme por coincidencias extrañas y realmente puedo usar la misma matriz en [5,4,3,2,1,0]ambas ocasiones, ahorrando la friolera de 13 bytes!
Neil
1
-2*s.split(/[omen]/).length+2Es más corto.
Oriol
6

Pyth, 27 26 28 bytes

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

1 byte guardado gracias a OP :-)

Explicación:

                                 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

Pruébalo aquí .

busukxuan
fuente
1
No soy un experto en Pyth, pero creo que puedes cambiar "omen"a justo "omeny Pyth lo entenderá
Charredgrass
@charredgrass Oops, mi error :-)
busukxuan
1
No parece funcionar para una cadena sin caracteres de "suerte" en ella. "memes" por ejemplo.
Emigna
1
@Emigna Ah. el caso cero otra vez ... ¡Gracias, lo arreglé!
busukxuan
6

Ruby, 91 87 bytes

String#count¡El uso finnicky ataca de nuevo! (Cuando se pasa una Cadena, cuenta todas las apariciones de cada letra en el argumento de la función en lugar de todas las apariciones de toda la cadena).

Pruébalo en línea

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

Una versión que toma líneas de STDIN y las imprime: 89 bytes (86 +3 de la -nbandera)

p 2**(z=0..5).max_by{|j|z.map{|i|$_[b="lucky"[i,j]]?b.size: 0}.max}-2*$_.count("omen")
Tinta de valor
fuente
1
._. eso String#countes raro +1 para (ab) usándolo. ¿También es más corto de usar en getslugar de una función?
Downgoat
1
@Downgoat si getstambién tengo que hacerlo putspara la salida, así que no en este caso.
Value Ink
4

Rubí: 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
fuente
Intente /[omen]/como la expresión regular para jugar golf: coincidirá con cualquier personaje y es mejor en el uso práctico que encadenar |s para caracteres individuales.
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
fuente
1
Puede cambiar esta condición: s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n'para verse así:"oman".split("").includes(s[k])
addison
1
Bienvenido a PPCG! Puede reducir esto al eliminar espacios en blanco para conservar bytes. Además, en lugar de (s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n')que pueda usar ('omen'.indexOf(s[k])+1)(suponiendo que esto sea JavaScript)
charredgrass
¡Gracias por los consejos! Lo bajé a 237, aunque parece que la multitud de Ruby me ganó.
Christopher Burgdorff
Otra pequeña cosa: puede abreviar function luck(r)para r=>convertirlo en una función anónima, eso es todo lo que se necesita para este desafío. También hice una edición del desafío para que no tenga que preocuparse por el caso para que pueda eliminar elr=r.toLowerCase();
charredgrass
En lugar de substringque puedas usar, slicecreo (prueba esto, ya que no estoy seguro)
Downgoat
3

Ruby, 57 bytes

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

getsse establece $.en 1 como efecto secundario, luego lo incrementamos hasta que la expresión regular que coincide con $.caracteres afortunados consecutivos ya no coincide.

histocrat
fuente
3

Haskell, 99

Otro enfoque ... Acabo de aprender sobre el alias de funciones

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

Mathematica, 86 bytes

Código:

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

Explicación:

LongestCommonSubsequencedevuelve la subcadena contigua más larga común a la entrada y "lucky". StringLengthda su longitud. StringCountcuenta el número de ocurrencias de los caracteres de "omen"en la entrada.


fuente
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
fuente
Puede guardar un byte usandofrom intertools import*
wnnmaw
1

TSQL, 233 bytes

Golfizado:

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

Sin golf:

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

Pruébalo en línea

t-clausen.dk
fuente
1

Haskell ( 134 132 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")

No es un jugador de código ni un programador de Haskell, por lo que me encantaría algunos consejos sobre este.

(Ejemplo: g "firetruck")

ForemanBob
fuente
Tampoco soy un experto en Haskell, pero me las arreglé para evitar algunos cambios cambiando ligeramente el algoritmo y usando alias de funciones en las funciones reutilizadas.
Zylviij
1

Python 3, 168 157 152 139 144 136 bytes

EDITAR: Las cosas realmente obvias que debería haber visto más fáciles han cambiado, y algunas un poco menos obvias.

Edición 2: stoopid (˚n˚). El programa arrojó errores. Lo arreglé. en realidad no 153 :(

Gracias a Leaky Nun por guardar 5 bytes, y a jmilloy por guardar 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))

El programa se ejecuta a través de todas las posibles subcadenas de entrada (posiblemente posible, porque también calcula subcadenas imposibles, 8 a 7, por ejemplo), comprueba si la subcadena está en "suerte", luego establece el exponente de 2 a la longitud de la subcadena debe ser mayor que el valor actual. Posiblemente podría mejorarse usando solo un bucle while. Posiblemente podría usar alguna mejora; Todavía me estoy acostumbrando a esto.

Limón Destructible
fuente
while p+1se conviertewhile-~p
Leaky Nun
desde entonces b=s[p:q], len(b)debe estar en lo q-pcierto?
Leaky Nun
Te robé el método de entrada e impresión, pero hice el resto muy diferente, ¡gracias! Creo que si solo haces las print(2**m-2*sum(i in"omen" for i in s))últimas tres líneas, ¿te irá mejor, como 148?
jmilloy
Ah, y puedes mover s [p: q] a la cláusula if while-~q:n=q-p;m=n if(s[p:q]in"lucky")*n>m else m;q-=1para 143?
jmilloy
sum(map(s.count,"omen"))ahorra un byte, por lo que es 135
Black Owl Kai
1

Programa PHP, 139 135 108 bytes

el salto cuántico falla para múltiples subcadenas donde la primera ocurrencia es más corta. :(

De hecho, podría guardar otros 7 bytes en PHP <5.4 con register_globals en

<?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 una función:

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

pruebas (en la función)

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