Déterminer la «chance» d'une chaîne

35

Étant donné une chaîne, renvoyez la "chance" de cette chaîne.

La chance d'une chaîne, comme je viens de la rattraper pour le but de ce défi, est un entier, déterminé comme suit:

  • La chance de base pour une chaîne est 1.
  • Pour chaque lettre consécutive qu'il partage avec le mot "chanceux" (insensible à la casse), multipliez la chance par 2. Par exemple, si votre chaîne était " lu mberjack" ou "sma ck ", vous multiplieriez par 4. (Plus précisément, 2 ^ nombre de caractères consécutifs partagés.)
    • Les lettres partagées doivent être dans le même ordre consécutif; elles apparaissent dans "chanceux" mais peuvent commencer n'importe où dans le mot pour la même valeur ("luc" a le même multiplicateur 8 * que "cky").
    • Si le mot a plusieurs occurrences où il partage des caractères consécutifs avec chanceux, utilisez la chaîne de caractères consécutive la plus longue.
  • Pour N'IMPORTE QUELLE lettre, elle partage le mot "présage", soustrayez 2 de la chance.
    • Il peut correspondre à un personnage à tout moment, dans n'importe quel ordre. Par exemple, la chaîne "nnnnnomemenn" perd 24 points de chance (12 lettres correspondantes)

Exemple:

luck("lucky")
>>32

2 ^ 5 (5 lettres consécutives) = 32

luck("firetruck")
>>6

2 ^ 3 - 2 (3 lettres consécutives de uck , e partagé avec omen)

luck("memes")
>>-7

1 - 8 (montant de base, 4 partagé avec "augure")

C'est le code de golf, donc la réponse avec le moins d'octets gagne.

Vous pouvez entrer et sortir comme vous le souhaitez - écrire une fonction, utiliser une entrée standard, etc.

Pour les fonctions, supposons que tout type de données ait un sens pour cette langue. (Par exemple, en JavaScript, vous recevrez un Stringet retournerez un Number)

Modifier: vous pouvez supposer que toute entrée est en minuscule.

charbon de bois
la source
8
Beau premier challenge!
Alex A.
2
Le programme doit-il accepter les majuscules?
busukxuan
2
@busukxuan Bonne question - non, il n'est pas nécessaire d'accepter les majuscules.
Charredgrass
@cat Pas sûr de bien comprendre ce que vous demandez. Mais vous pouvez simplement supposer que toutes les entrées seront en minuscule et que vous n’aurez pas besoin d’attraper une entrée en majuscule.
Charredgrass
1
Pouvons-nous supposer une limite supérieure ou inférieure sur la chance d'une entrée donnée? C'est-à-dire quel est le plus petit nombre de bits / type de données que je peux obtenir, ou est-il aussi grand que ma langue peut gérer? c'est-à-dire, devrait-il int8_t str_luck(const char* str);ou devrait-il être uint64_t str_luck(const char* str);?
Chat

Réponses:

7

05AB1E , 36 32 28 26 octets

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

Explication

Œ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

Essayez-le en ligne

2 octets sauvés grâce à Adnan

Emigna
la source
La compression pour 1 mot peut aussi être faite avec ', donc pour 26: Œv'¸éyåiyˆ}}¯é¤go¹'ƒÖ¦Ãg·-:).
Adnan
@Adnan: Bizarre. J'étais certain d'avoir essayé cela. Apparemment non. Merci!
Emigna
pourquoi n'est-ce pas la meilleure des réponses?
nozɐɹƆ
7

JavaScript (ES7), 123 112 107 octets

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

Edit: 11 octets enregistrés grâce à @Titus en supposant que la lettre Ln’apparaît pas dans l’entrée. 5 octets sauvés grâce à @Oriol. Version ES6 pour 125 114 109 octets:

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
la source
Pourquoi utilisez-vous replace([^])au lieu de match([])? Vous perdez 3 octets ou y a-t-il une raison?
Titus
@ Titus Combien d'octets coûte le traitement d'un nullrésultat de correspondance?
Neil
1
Quatre pour une chaîne, et une paire de ()dans ce cas; manger tous les six que vous économiseriez avec match(/[omen]/). Pitié.
Tite
1
@ Titus Je ne sais pas si c'est ce que vous vouliez dire, mais en ajoutant un Là la fin du substrat (qui n'apparaîtra jamais dans la chaîne d'origine), je n'ai pas à m'inquiéter des correspondances superflues et je peux utiliser le même tableau les [5,4,3,2,1,0]deux fois, économiser 13 octets!
Neil
1
-2*s.split(/[omen]/).length+2est plus courte.
Oriol
6

Pyth, 27 26 28 octets

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

1 octet enregistré grâce à OP :-)

Explication:

                                 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

Testez-le ici .

busukxuan
la source
1
Je ne suis pas un expert en Pyth mais je crois que vous pouvez changer "omen"en juste "omenet que Pyth comprendra
charredgrass
@charredgrass Oups, mon erreur :-)
busukxuan
1
Ne semble pas fonctionner pour une chaîne sans forme de caractères "chanceux" en elle. "memes" par exemple.
Emigna
1
@ Emigna Ah. le cas zéro encore ... Merci, corrigé!
busukxuan
6

Rubis, 91 87 octets

String#countL'utilisation de finnicky frappe encore! (Lorsqu'une chaîne est transmise, elle compte toutes les occurrences de chaque lettre dans l'argument de la fonction au lieu de toutes les occurrences de la chaîne entière.)

Essayez-le en ligne

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

Une version qui prend des lignes de STDIN et les imprime: 89 octets (86 +3 à partir du -ndrapeau)

p 2**(z=0..5).max_by{|j|z.map{|i|$_[b="lucky"[i,j]]?b.size: 0}.max}-2*$_.count("omen")
Valeur d'encre
la source
1
._. c'est String#countbizarre. +1 pour (ab) l'utiliser. Aussi est-il plus court d'utiliser getsplutôt qu'une fonction?
Downgoat
1
@Downgoat si je je getsdois aussi putspour la sortie, donc pas dans ce cas.
Valeur d'encre
4

Ruby: 100 octets

->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
la source
Essayez /[omen]/comme regex de jouer au golf - cela correspond à n’importe quel personnage et est meilleur en utilisation pratique que l’enchaînement |de personnages uniques.
Charredgrass
3

Javascript - 206 octets

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
la source
1
Vous pourriez changer cette condition: s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n'pour ressembler à ceci:"oman".split("").includes(s[k])
addison
1
Bienvenue chez PPCG! Vous pouvez jouer au golf en supprimant les espaces pour conserver les octets. Aussi, au lieu de (s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n')vous pourriez utiliser ('omen'.indexOf(s[k])+1)(en supposant que ce soit JavaScript)
charredgrass
Merci pour les conseils! Nous en sommes à 237, même si on dirait que la foule Ruby m'a battu.
Christopher Burgdorff
Une autre petite chose: vous pouvez function luck(r)en r=>faire une fonction anonyme, c'est tout ce qui est nécessaire pour relever ce défi. J'ai également r=r.toLowerCase();
modifié
Au lieu de substringvous pouvez utiliser sliceje crois (testez cela, comme je ne suis pas sûr)
Downgoat
3

Ruby, 57 octets

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

getsdéfinit $.comme un effet secondaire 1, puis nous l'incrémentons jusqu'à ce que l'expression régulière correspondant aux $.caractères porte-bonheur consécutifs ne corresponde plus.

histocrate
la source
3

Haskell, 99

Une autre approche ... Je viens d'apprendre à propos de l'aliasing de fonction

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

Usage

f"lucky"
32

f"firetruck"
6

f"memes"
-7
Zylviij
la source
2

Mathematica, 86 octets

Code:

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

Explication:

LongestCommonSubsequencerenvoie la plus longue sous-chaîne contiguë commune à l'entrée et "lucky". StringLengthdonne sa longueur. StringCountcompte le nombre d'occurrences des caractères de "omen"dans l'entrée.


la source
2

Python (139 octets)

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
la source
Vous pouvez enregistrer un octet en utilisantfrom intertools import*
wnnmaw
1

TSQL, 233 octets

Golfé:

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

Essayez-le en ligne

t-clausen.dk
la source
1

Haskell ( 134 132 octets)

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

Pas un golfeur de code ni un programmeur Haskell, alors j'aimerais quelques conseils sur celui-ci.

(Exemple: g "firetruck")

ForemanBob
la source
Je ne suis pas non plus un expert de Haskell, mais j'ai réussi à éviter quelques exceptions en modifiant légèrement l'algorithme et en utilisant des alias de fonction pour les fonctions réutilisées.
Zylviij
1

Python 3, 168 157 152 139 144 136 136 octets

EDIT: Les choses vraiment évidentes que j'aurais dû voir plus facilement ont été modifiées, et certaines légèrement moins évidentes.

Éditez 2: stoopid (n˚). Le programme a jeté des erreurs. Je l'ai arrangé. pas réellement 153 :(

Merci à Leaky Nun d’avoir économisé 5 octets et à jmilloy d’avoir économisé 13 8 octets.

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

Le programme parcourt toutes les sous-chaînes possibles en entrée (éventuellement, car il calcule également les sous-chaînes impossibles, 8 à 7, par exemple), vérifie si la sous-chaîne est "chanceux", puis définit l’exposant de 2 sur la longueur de la sous-chaîne doit être supérieure à la valeur actuelle. Peut-être pourrait-on améliorer en utilisant une seule boucle while. Pourrait éventuellement utiliser une amélioration; Je comprends toujours le problème.

Citron destructible
la source
while p+1devientwhile-~p
Leaky Nun
depuis b=s[p:q], len(b)doit avoir q-praison?
Leaky Nun
Je vous ai volé votre méthode de saisie et d’impression, mais le reste est très différent, merci! Je pense que si vous faites juste print(2**m-2*sum(i in"omen" for i in s))pour vos trois dernières lignes, vous ferez mieux, comme 148?
jmilloy
Oh, et vous pouvez simplement déplacer s [p: q] dans la clause if while-~q:n=q-p;m=n if(s[p:q]in"lucky")*n>m else m;q-=1pour 143?
jmilloy
sum(map(s.count,"omen"))enregistre un octet, ce qui en fait 135
Black Owl Kai
1

Programme PHP, 139 135 108 octets

Le saut quantique échoue pour plusieurs sous-chaînes où la première occurrence est plus courte. :(

en fait, je pourrais économiser 7 octets supplémentaires en PHP <5.4 avec register_globals sur

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

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

+5 pour une fonction:

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

tests (sur la fonction)

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

Scala, 155 octets

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