Określ „Szczęście” sznurka

35

Podany ciąg zwraca „szczęście” tego ciągu.

Szczęście sznurka, które właśnie nadrobiłem na potrzeby tego wyzwania, jest liczbą całkowitą, określoną w ten sposób:

  • Podstawowym szczęściem dla sznurka jest 1.
  • Dla każdej kolejnej litery, którą dzieli ze słowem „szczęśliwy” (bez względu na wielkość liter), pomnóż szczęście przez 2. Na przykład, jeśli ciąg znaków to „ lu mberjack” lub „sma ck ”, pomnożysz przez 4. (Dokładniej, 2 ^ liczba udostępnionych kolejnych znaków.)
    • Litery współdzielone muszą być w tej samej kolejności, w jakiej występują w „szczęśliwym”, ale mogą zaczynać się w dowolnym miejscu tego słowa dla tej samej wartości („luc” ma ten sam 8 * mnożnik jak „cky”).
    • Jeśli słowo ma wiele wystąpień, w których dzieli kolejne znaki ze szczęśliwymi, użyj najdłuższego ciągu kolejnych znaków.
  • W przypadku KAŻDEJ litery, którą dzieli ze słowem „omen”, odejmij 2 od szczęścia.
    • Może pasować do postaci dowolną ilość razy, w dowolnej kolejności. Na przykład ciąg „nnnnnomemenn” traci 24 szczęścia (12 pasujących liter)

Przykład:

luck("lucky")
>>32

2 ^ 5 (5 kolejnych liter) = 32

luck("firetruck")
>>6

2 ^ 3 - 2 (3 kolejne litery od uck , e wspólne z omen)

luck("memes")
>>-7

1–8 (kwota podstawowa, 4 wspólne z „omen”)

To jest golf golfowy, więc wygrywa odpowiedź z najmniejszą liczbą bajtów.

Możesz wprowadzać i wyprowadzać w dowolny sposób - napisz funkcję, użyj standardowego wejścia itp.

W przypadku funkcji załóż, że dowolny typ danych ma sens dla tego języka. (Na przykład w JavaScript zostaniesz przekazany a Stringi zwrócisz a Number)

Edycja: Możesz założyć, że każde wejście jest pisane małymi literami.

charredgrass
źródło
8
Ładne pierwsze wyzwanie!
Alex A.,
2
Czy program powinien akceptować wprowadzanie wielkich liter?
busukxuan
2
@busukxuan Dobre pytanie - nie, nie trzeba akceptować wielkich liter.
charredgrass
@cat Nie jestem pewien, czy rozumiem, o co pytasz. Ale możesz po prostu założyć, że wszystkie dane wejściowe będą pisane małymi literami i nie musisz przechwytywać żadnych wielkich liter.
charredgrass
1
Czy możemy założyć górną lub dolną granicę szczęścia danego wkładu? tj. jaka jest najmniejsza liczba bitów / typów danych, z której mogę uciec, czy też jest tak duża, jak radzi sobie mój język? to znaczy, int8_t str_luck(const char* str);czy powinno być, czy powinno być uint64_t str_luck(const char* str);?
kot

Odpowiedzi:

7

05AB1E , 36 32 28 26 bajtów

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

Wyjaśnienie

Œ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

Wypróbuj online

Zaoszczędzono 2 bajty dzięki Adnan

Emigna
źródło
Można również kompresować 1 słowo ', więc dla 26: Œv'¸éyåiyˆ}}¯é¤go¹'ƒÖ¦Ãg·-:).
Adnan
@Adnan: Dziwne. Byłem pewien, że tego spróbowałem. Najwyraźniej nie. Dzięki!
Emigna
dlaczego nie jest to najlepsza odpowiedź?
noɥʇʎԀʎzɐɹƆ
7

JavaScript (ES7), 123 112 107 bajtów

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

Edycja: Zapisano 11 bajtów dzięki @Titus, zakładając, że litera Lnie pojawia się na wejściu. Zaoszczędź 5 bajtów dzięki @Oriol. Wersja ES6 dla 125 114 109 bajtów:

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
źródło
Dlaczego używasz replace([^])zamiast match([])? Czy marnujesz 3 bajty, czy jest jakiś powód?
Tytus
@Tytus Ile bajtów kosztuje poradzenie sobie z nullwynikiem dopasowania?
Neil
1
Cztery na ciąg i para ()w tym przypadku; zjadając wszystkie sześć, za które można by oszczędzić match(/[omen]/). Szkoda.
Tytus
1
@Titus Nie jestem pewien, czy o to ci chodziło, ale dodając Ldo końca substr (który nigdy nie pojawi się w oryginalnym ciągu), nie muszę się martwić obcymi dopasowaniami i mogę używać tej samej tablicy za [5,4,3,2,1,0]każdym razem, oszczędzając aż 13 bajtów!
Neil
1
-2*s.split(/[omen]/).length+2jest krótszy.
Oriol
6

Pyth, 27 26 28 bajtów

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

1 bajt zapisany dzięki OP :-)

Wyjaśnienie:

                                 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

Sprawdź to tutaj .

busukxuan
źródło
1
Nie jestem ekspertem w Pyth, ale wierzę, że możesz zmienić "omen"na sprawiedliwy "omeni Pyth zrozumie
charredgrass
@charredgrass Ups, mój błąd :-)
busukxuan
1
Wydaje się, że nie działa na ciąg bez znaków, które tworzą w nim „szczęście”. na przykład „memy”.
Emigna
1
@Emigna Ah. znowu zero. Dzięki, naprawiłem to!
busukxuan
6

Ruby, 91 87 bajtów

String#countdrobne użycie znów uderza! (Po przekazaniu ciągu liczy wszystkie wystąpienia każdej litery w argumencie funkcji zamiast wszystkich wystąpień całego ciągu.)

Wypróbuj 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")}

Wersja, która pobiera wiersze ze STDIN i drukuje je: 89 bajtów (86 +3 z -nflagi)

p 2**(z=0..5).max_by{|j|z.map{|i|$_[b="lucky"[i,j]]?b.size: 0}.max}-2*$_.count("omen")
Wartość tuszu
źródło
1
._. że String#countto dziwne. +1 za (ab) korzystanie z niego. Czy jest też krótszy w użyciu getsniż funkcja?
Downgoat
1
@Downgoat, jeśli ja getsteż muszę putsdla danych wyjściowych, więc nie w tym przypadku.
Wartość tuszu
4

Ruby: 100 bajtów

->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
źródło
Spróbuj /[omen]/użyć wyrażenia regularnego, aby zagrać w golfa - będzie pasować do dowolnej postaci i jest lepszy w praktycznym użyciu niż łączenie łańcuchów |pojedynczych postaci.
charredgrass
3

JavaScript - 206 bajtów

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
źródło
1
Możesz zmienić ten warunek: s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n'aby wyglądać tak:"oman".split("").includes(s[k])
addison
1
Witamy w PPCG! Możesz zagrać w golfa, usuwając białe znaki, aby zaoszczędzić bajty. Zamiast tego (s[k]=='o'||s[k]=='m'||s[k]=='e'||s[k]=='n')możesz użyć ('omen'.indexOf(s[k])+1)(zakładając, że jest to JavaScript)
charredgrass
Dzięki za wskazówki! Sprowadziłem to do 237, chociaż wygląda na to, że Ruby tłum mnie pobiła.
Christopher Burgdorff
Kolejna drobna rzecz: możesz skrócić function luck(r), aby r=>uczynić ją anonimową funkcją, to wszystko, co jest potrzebne do tego wyzwania. r=r.toLowerCase();
Dokonałem
Zamiast tego substringmożesz używać, slicewierzę (przetestuj to, bo nie jestem pewien)
Downgoat
3

Rubinowy, 57 bajtów

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

getsustawia się $.na 1 jako efekt uboczny, a następnie zwiększamy go, aż wyrażenie regularne pasujące do $.kolejnych szczęśliwych znaków nie będzie już pasować.

histocrat
źródło
3

Haskell, 99

Inne podejście ... Właśnie dowiedziałem się o aliasingu funkcji

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

Stosowanie

f"lucky"
32

f"firetruck"
6

f"memes"
-7
Zylviij
źródło
2

Mathematica, 86 bajtów

Kod:

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

Wyjaśnienie:

LongestCommonSubsequencezwraca najdłuższy ciągły podciąg wspólny dla danych wejściowych i "lucky". StringLengthpodaje swoją długość. StringCountzlicza liczbę wystąpień znaków "omen"na wejściu.


źródło
2

Python (139 bajtów)

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
źródło
Możesz zapisać jeden bajt, używającfrom intertools import*
wnnmaw
1

TSQL, 233 bajty

Gra w golfa:

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

Nie golfowany:

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

Wypróbuj online

t-clausen.dk
źródło
1

Haskell ( 134 132 bajtów)

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

Ani golfista, ani programista Haskell, więc chętnie napiszę kilka wskazówek na ten temat.

(Przykład: g "firetruck")

ForemanBob
źródło
Nie jestem również ekspertem od Haskell, ale udało mi się wyryć kilka buzi, zmieniając nieco algorytm i używając aliasów funkcji na ponownie używanych funkcjach.
Zylviij
1

Python 3, 168 157 152 139 144 136 bajtów

EDYCJA: Naprawdę oczywiste rzeczy, które powinienem widzieć łatwiej, zostały zmienione, a niektóre nieco mniej oczywiste.

Edycja 2: stoopid (˚n˚). Program rzucał błędy. Naprawiłem to. właściwie nie 153 :(

Dzięki Leaky Nun za uratowanie 5 bajtów i jmilloy za uratowanie 13 8 bajtów.

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

Program przechodzi przez wszystkie możliwe podciągi wejściowe (możliwe, ponieważ oblicza również podciągi niemożliwe, na przykład od 8 do 7), sprawdza, czy podłańcuch jest „szczęśliwy”, a następnie ustawia wykładnik 2 na długość podłańcuch powinien być większy niż bieżąca wartość. Ewentualnie można to poprawić, używając tylko jednej pętli while. Przydałaby się poprawa; Nadal się rozumiem.

Zniszczalna cytryna
źródło
while p+1staje sięwhile-~p
Leaky Nun
ponieważ b=s[p:q], len(b)musi być q-pprawda?
Leaky Nun
Ukradłem ci metodę wprowadzania i drukowania, ale resztę zrobiłem zupełnie inaczej, dzięki! Myślę, że jeśli zrobisz to print(2**m-2*sum(i in"omen" for i in s))dla ostatnich trzech linii, zrobisz to lepiej, na przykład 148?
jmilloy
Aha, możesz po prostu przenieść s [p: q] do klauzuli if while-~q:n=q-p;m=n if(s[p:q]in"lucky")*n>m else m;q-=1dla 143?
jmilloy
sum(map(s.count,"omen"))oszczędza jeden bajt, dzięki czemu jest 135
Black Owl Kai
1

Program PHP, 139 135 108 bajtów

skok kwantowy kończy się niepowodzeniem w przypadku wielu podciągów, w których pierwsze wystąpienie jest krótsze. :(

właściwie mógłbym zapisać kolejne 7 bajtów w PHP <5.4 z włączonym register_globals

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

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

+5 dla funkcji:

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

testy (na funkcji)

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>';
Tytus
źródło
0

Scala, 155 bajtów

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
źródło